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

WFPackedValuesTest.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 WFPackedValuesTest = { }

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

local KSTestUtils = require 'KSTestUtils'

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

local function testPackAndUnpack( case, ... )

	local WFPackedValues = require 'WFPackedValues'
	
	local pv = WFPackedValues.pack( ... )
	
	assert( KSTestUtils.testResults( WFPackedValues.unpack, pv )( ... ), "Pack and unpack test failed: " .. case )

end

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

local function testPackDataAndUnpack( case, ... )

	local WFPackedValues = require 'WFPackedValues'
	
	local pv = WFPackedValues.packData( ... )
	
	assert( KSTestUtils.testResults( WFPackedValues.unpack, pv )( 'data', ... ), "Pack and unpack test failed: " .. case )

end

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

local function testPackAndStatus( case, ... )

	local WFPackedValues = require 'WFPackedValues'
	
	local pv = WFPackedValues.pack( ... )
	
	assert( KSTestUtils.testResults( WFPackedValues.status, pv )( ( ... ) ), "Status test failed: " .. case )

end

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

function WFPackedValuesTest.testPackCases( )

	testPackAndUnpack( 'empty', 'data' )
	testPackAndUnpack( 'unit:3', 'data', 3 )
	testPackAndUnpack( 'unit:false', 'data', false )
	testPackAndUnpack( 'unit:nil', 'data', nil )
	--testPackAndUnpack( 'unit:NaN', 'data', 0/0 )
		-- NaN test fails equality because NaN ~= NaN
	testPackAndUnpack( 'pair:3,4', 'data', 3, 4 )
	testPackAndUnpack( 'pair:nil,4', 'data', nil, 4 )
	testPackAndUnpack( 'pair:3,nil', 'data', 3, nil )
	testPackAndUnpack( 'trio:3,4,5', 'data', 3, 4, 5 )

end

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

function WFPackedValuesTest.testPackStatusCases( )

	testPackAndStatus( 'empty', 'data' )
	testPackAndStatus( 'unit:3', 'data', 3 )
	testPackAndStatus( 'unit:false', 'data', false )
	testPackAndStatus( 'unit:nil', 'data', nil )
	testPackAndStatus( 'unit:NaN', 'data', 0/0 )
	testPackAndStatus( 'pair:3,4', 'data', 3, 4 )
	testPackAndStatus( 'pair:nil,4', 'data', nil, 4 )
	testPackAndStatus( 'pair:3,nil', 'data', 3, nil )
	testPackAndStatus( 'trio:3,4,5', 'data', 3, 4, 5 )

end

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

function WFPackedValuesTest.testPackData()

	testPackDataAndUnpack( 'empty' )
	testPackDataAndUnpack( 'unit:3', 3 )
	testPackDataAndUnpack( 'unit:false', false )
	testPackDataAndUnpack( 'unit:nil', nil )
	--testPackDataAndUnpack( 'unit:NaN', 0/0 )
		-- NaN test fails equality because NaN ~= NaN
	testPackDataAndUnpack( 'pair:3,4', 3, 4 )
	testPackDataAndUnpack( 'pair:nil,4', nil, 4 )
	testPackDataAndUnpack( 'pair:3,nil', 3, nil )
	testPackDataAndUnpack( 'trio:3,4,5', 3, 4, 5 )

end

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

function WFPackedValuesTest.testPackError()

	local WFPackedValues = require 'WFPackedValues'

	local packError = WFPackedValues.packError
	
	local pe = packError( "This is the error message" )
	
	assert( WFPackedValues.status( pe ) == 'error', "Error does not have appropriate status" )
	
	assert( KSTestUtils.testResults( WFPackedValues.unpack, pe )( 'error', "This is the error message" ) )
	
	local pz = packError()
	
	local pz_status, pz_msg = WFPackedValues.unpack( pz )
	
	assert( pz_status == 'error', "Packed empty error has wrong status" )
	assert( pz_msg ~= nil, "Packed empty error should still have message when packed via packError" )

end

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

function WFPackedValuesTest.testSingleValueOptimization( )

	local WFPackedValues = require 'WFPackedValues'
	
	local pack = WFPackedValues.packData
	
	assert( pack( 3 ) == pack( 3 ), "Packing same value should match (3)" )
	assert( pack( nil ) == pack( nil ), "Packing same value should match (nil)" )

	assert( pack( { } ) ~= pack( { } ), "Packing non-matching values should not match" )

end

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

function WFPackedValuesTest.testEquals()

	local WFPackedValues = require 'WFPackedValues'
	
	local pa = WFPackedValues.packData()
	local pb = WFPackedValues.packData( 4, 5, 6 )
	local pb2 = WFPackedValues.packData( 4, 5, 6 )
	local pc = WFPackedValues.packData( 4, 5, 6, 7 )
	local pd = WFPackedValues.packData( nil, nil, 6 )
	
	assert( WFPackedValues.equals( pa, pa ) )
	assert( not WFPackedValues.equals( pa, pb ) )
	assert( not WFPackedValues.equals( pa, pb2 ) )
	assert( not WFPackedValues.equals( pa, pc ) )
	assert( not WFPackedValues.equals( pa, pd ) )
	
	assert( not WFPackedValues.equals( pb, pa ) )
	assert( WFPackedValues.equals( pb, pb ) )
	assert( WFPackedValues.equals( pb, pb2 ) )
	assert( not WFPackedValues.equals( pb, pc ) )
	assert( not WFPackedValues.equals( pb, pd ) )

	assert( not WFPackedValues.equals( pb2, pa ) )
	assert( WFPackedValues.equals( pb2, pb ) )
	assert( WFPackedValues.equals( pb2, pb2 ) )
	assert( not WFPackedValues.equals( pb2, pc ) )
	assert( not WFPackedValues.equals( pb2, pd ) )

	assert( not WFPackedValues.equals( pc, pa ) )
	assert( not WFPackedValues.equals( pc, pb ) )
	assert( not WFPackedValues.equals( pc, pb2 ) )
	assert( WFPackedValues.equals( pc, pc ) )
	assert( not WFPackedValues.equals( pc, pd ) )

	assert( not WFPackedValues.equals( pd, pa ) )
	assert( not WFPackedValues.equals( pd, pb ) )
	assert( not WFPackedValues.equals( pd, pb2 ) )
	assert( not WFPackedValues.equals( pd, pc ) )
	assert( WFPackedValues.equals( pd, pd ) )
	
	local deepEquals = require 'KSTableUtils' . deepEquals
	
	local px = WFPackedValues.packData( { foo = 7 } )
	local py = WFPackedValues.packData( { foo = 7 } )
	
	assert( not WFPackedValues.equals( px, py ) )
	assert( WFPackedValues.equals( px, py, deepEquals ) )

end

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

return WFPackedValuesTest
