--[[----------------------------------------------------------------------------

KSBucketBrigadeTest.lua

--------------------------------------------------------------------------------

ADOBE CONFIDENTIAL
------------------
Copyright 2010 Adobe Systems Incorporated
All Rights Reserved.

NOTICE: All information contained herein is, and remain the property of
Adobe Systems Incorporated and its suppliers, if any. The intellectual and
technical concepts contained herein are proprietary to Adobe Systems
Incorporated and its suppliers and may be covered by U.S. and Foreign
Patents, patents in process, and are protected by trade secret or copyright
law.  Dissemination of this information or reproduction of this material is
strictly forbidden unless prior written permission is obtained from
Adobe Systems Incorporated.

------------------------------------------------------------------------------]]

local T = { }

--------------------------------------------------------------------------------

function T.testBucketBrigade()

	local KSBucketBrigade = require "KSBucketBrigade"
	
	local brigade = KSBucketBrigade.makeBrigade( 5 )
	
	local weakRef = require 'KSTableUtils'.makeFullyWeak()
	
	local obj = { }
	
	weakRef[ 1 ] = obj
	
	brigade( obj )
	
	obj = nil
	
	assert( weakRef[ 1 ], "object was created" )
	
	collectgarbage()
	
	assert( weakRef[ 1 ], "object survived collection" )
	
	collectgarbage()
	
	assert( weakRef[ 1 ], "survived collection (2)" )
	
	for i = 1, 10 do
		collectgarbage()
	end
	
	assert( weakRef[ 1 ], "object survived repeated GCs" )
	
	-- Now, we push the brigade forward with each collection
	
	local obj2 = { }
	
	brigade( obj2 )
	
	assert( weakRef[ 1 ], "object survives first addition to brigade" )
	
	collectgarbage()
	
	assert( weakRef[ 1 ], "object survives GC after addition" )
	
	for i = 1, 10 do
		brigade( obj2 )
		collectgarbage()
	end
	
	assert( weakRef[ 1 ] == nil, "object was collected" )
	
	-- adding two items executes another code path (headLink ~= nil) in the function returned by makeBrigade

	local obj3 = { }
	local obj4 = { }

	weakRef[ 1 ] = obj3
	weakRef[ 2 ] = obj4

	brigade( obj3 )
	brigade( obj4 )

	obj3 = nil
	obj4 = nil

	collectgarbage()

	assert( weakRef[ 1 ], "obj3 survived collection" )
	assert( weakRef[ 2 ], "obj4 survived collection" )

	-- validate brigade return value
	
	assert( brigade( nil ) == nil, "brigade handles nil item" )
	
	local obj5 = { }
	assert( brigade( obj5 ) == obj5, "brigade returns passed in item" )
		
end

--------------------------------------------------------------------------------

function T.testPurge()

	local KSBucketBrigade = require "KSBucketBrigade"
	
	local brigade = KSBucketBrigade.makeBrigade()
	
	local weakRef = require 'KSTableUtils'.makeFullyWeak()
	
	local obj = { }
	
	weakRef[ 1 ] = obj
	
	brigade( obj )
	
	obj = nil
	
	assert( weakRef[ 1 ], "object was created" )
	
	collectgarbage()
	
	assert( weakRef[ 1 ], "object survived collection" )
	
	collectgarbage()
	
	assert( weakRef[ 1 ], "survived collection (2)" )
	
	for i = 1, 10 do
		collectgarbage()
	end
	
	assert( weakRef[ 1 ], "object survived repeated GCs" )
	
	brigade( '< purge >' )
	
	collectgarbage()
	
	assert( weakRef[ 1 ] == nil, "object should have been purged" )

end

--------------------------------------------------------------------------------

function T.testPurgeAllBrigades()

	local KSBucketBrigade = require "KSBucketBrigade"
	
	local brigades = { }
	
	for i = 1, 10 do
		brigades[ i ] = KSBucketBrigade.makeBrigade()
	end
	
	local weakRefs = require 'KSTableUtils'.makeFullyWeak()
	
	for i = 1, 10 do
		local obj = { }
		weakRefs[ i ] = obj
		brigades[ i ]( obj )
	end
	
	for i = 1, 10 do
		assert( weakRefs[ i ], "object was created" )
	end
		
	collectgarbage()
	
	for i = 1, 10 do
		assert( weakRefs[ i ], "object survived collection" )
	end
	
	for j = 1, 10 do
		collectgarbage()
	end
	
	for i = 1, 10 do
		assert( weakRefs[ i ], "object survived repeated collections" )
	end
	
	KSBucketBrigade.purgeAllBrigades()
	
	collectgarbage()
	
	for i = 1, 10 do
		assert( weakRefs[ i ] == nil, "object should have been purged" )
	end

end

--------------------------------------------------------------------------------

return T
