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

KSTableArchivingTest.lua

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

ADOBE CONFIDENTIAL
------------------
Copyright 2013 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 KSTableArchiving = require 'KSTableArchiving'

local KSTableArchivingTest = {}

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

--[[ WICHITA DISABLED

function KSTableArchivingTest.testSimpleUserdataWriters()
end

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

function KSTableArchivingTest.testUserdataArchivers()
end

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

function KSTableArchivingTest.testArchiveAndUnarchiveTables()

	local simpleTable = { 42, "hi", false, true, foo = { "foo" } }

	local resultString = KSTableArchiving.archiveNameAndTableToString( 'simpleTable', simpleTable )
	
	local resultTable = KSTableArchiving.unarchiveNameAndStringToTable( 'simpleTable', resultString )
 
	local resultString2 = KSTableArchiving.archiveNameAndTableToString( 'simpleTable', resultTable )
	
	assert( resultString2 == resultString, "Table failed to archive, unarchive and then rearchive the same" )
	
end

WICHITA DISABLED ]]

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

function KSTableArchivingTest.testSimpleTableToChunkString()

	-- test a simple table that we can compare the output as a string
	-- since serialized data is saved to a user's files it's probably dangerous to change how we format it
	-- so this check is here to guard against that.

	local simpleTable = { 42, "hi", false, true, foo = { "foo" } }

	local resultString = KSTableArchiving.simpleTableToChunkString_deprecated( simpleTable )
	
	-- Old versions had a bug where table keys after a false would be explicit.
	local expectedString = '{\n\t42,\n\t"hi",\n\tfalse,\n\ttrue,\n\tfoo = {\n\t\t"foo",\n\t},\n}'
	
	assert( resultString == expectedString, "Table serialization changed" )
	

	-- test with more values to increase coverage
	
	simpleTable = { 0 / 0, 1 / 0, 42, "hi", false, true, foo = { "foo" } }
	simpleTable[true] = { 1 }
	simpleTable[false] = { 0 }

	resultString = KSTableArchiving.simpleTableToChunkString_deprecated( simpleTable )

	local resultTable = loadstring( 'return ' .. resultString )()
	
	local resultString2 = KSTableArchiving.simpleTableToChunkString_deprecated( resultTable )
	assert( resultString2 == resultString, "Table failed to reload and re-serialize the same" )

	
	-- test some failure conditions
		
	assert( not pcall( KSTableArchiving.simpleTableToChunkString_deprecated, "test" ), "should error not a table" )

	assert( not pcall( KSTableArchiving.simpleTableToChunkString_deprecated, { simpleTable, simpleTable } ), "should error not a simple table" )

	assert( not pcall( KSTableArchiving.simpleTableToChunkString_deprecated, { a = simpleTable, b = { c = { simpleTable } } } ), "should error not a simple table" )

	assert( not pcall( KSTableArchiving.simpleTableToChunkString_deprecated, { fn = function() end } ), "functions are not allowed in a simple table" )

	-- table with userdata is not allowed
	
	local KSUserdataProxy = assert( require "KSUserdataProxy" )
	local factory = KSUserdataProxy.makeFactory()
	local proxy = factory()
	assert( type( proxy ) == 'userdata' )
	
	assert( not pcall( KSTableArchiving.simpleTableToChunkString_deprecated, { a = 1, b = proxy, c = 2 } ), "userdata is not allowed" )

end

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

--[[ WICHITA DISABLED

function KSTableArchivingTest.testIsValidSimpleTable()
	
	assert( KSTableArchiving.isValidSimpleTable( { } ) )
	
	local simpleTable = { 42, "hi", true, false, foo = { "foo" } }
	
	assert( KSTableArchiving.isValidSimpleTable( simpleTable ) )

	assert( not KSTableArchiving.isValidSimpleTable( nil ), "nil is not a table" )

	assert( not KSTableArchiving.isValidSimpleTable( { simpleTable, simpleTable } ), "simple tables can't have repeated sub tables" )
	
	assert( not KSTableArchiving.isValidSimpleTable( { fn = function() end } ), "functions are not allowed in a simple table" )
	
	-- table with user data is not a simple table
	local KSUserdataProxy = assert( require "KSUserdataProxy" )
	local factory = KSUserdataProxy.makeFactory()
	local proxy = factory()
	assert( type(proxy) == 'userdata')

	assert( not KSTableArchiving.isValidSimpleTable( { a = 1, b = proxy, c = 2 } ), "userdata is not allowed in a simple table" )

end
]]

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

function KSTableArchivingTest.testIsStringValidIdentifier()

	assert( KSTableArchiving.isStringValidIdentifier( "test" ), "valid identifier" )

	assert( KSTableArchiving.isStringValidIdentifier( "test" ), "test revisted valid identifier" )

	assert( not KSTableArchiving.isStringValidIdentifier( "" ), "empty string is not an identifier" )

	assert( not KSTableArchiving.isStringValidIdentifier( "for" ), "keywords are not allowed" )

	assert( not KSTableArchiving.isStringValidIdentifier( "23test" ), "identifiers must not start with a number" )

	assert( not KSTableArchiving.isStringValidIdentifier( "23test" ), "test revisted invalid identifier" )

	assert( not KSTableArchiving.isStringValidIdentifier( " test" ), "identifiers must start with a letter" )

	assert( not KSTableArchiving.isStringValidIdentifier( "test " ), "identifiers must end with alphanumeric char" )

	assert( not KSTableArchiving.isStringValidIdentifier( "te$st " ), "identifiers must only contain alphanumeric chars" )

end

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

function KSTableArchivingTest.testNotANumberAndInfiniteValuesAndKeys()
	
	local s = KSTableArchiving.simpleTableToChunkString_deprecated {
		[ -1 ] = -1,
		x = 0/0,
		[ 1/0 ] = 1/0,
		[ -1/0 ] = -1/0,
		[ 0.1 ] = 0.1,
		'first value',
		[ 3 ] = 'third value'
	}
	
	local f, e = loadstring( 'return ' .. s )
	assert( f, 'Does not compile: ' .. s .. ' because ' .. tostring( e ) )
	
	local t = f()
	assert( type( t ) == 'table' , 'not a table' )
	assert( t[ -1 ] == -1, 'negative key failed' )
	assert( t.x ~= t.x, 'NaN lost' )
	assert( t[ 1/0 ] == 1/0, 'Inf lost' )
	assert( t[ -1/0 ] == -1/0, '-Inf lost' )
	assert( t[ 0.1 ] == 0.1, 'fraction lost' )
	assert( t[ 1 ] == 'first value', 'fraction lost' )
	assert( t[ 3 ] == 'third value', 'fraction lost' )
	
	
end
--------------------------------------------------------------------------------

return KSTableArchivingTest
