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

WFRingBufferTest.lua

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

ADOBE CONFIDENTIAL
------------------
Copyright 2017 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.

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

	-- wf.core
local WFFunctionUtils = require 'WFFunctionUtils'
local WFRxTestCase = require 'WFRxTestCase'

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

local WFRingBuffer = require "WFRingBuffer"

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

local function rxTestMake( rxTest )

	rxTest:expectError( WFRingBuffer.make )

	rxTest:expectError( function() WFRingBuffer.make( {} ) end )

	rxTest:expectError( function() WFRingBuffer.make( "nope" ) end )

	rxTest:expectError( function() WFRingBuffer.make( 0 ) end )

	rxTest:expectError( function() WFRingBuffer.make( -1 ) end )

	rxTest:expectError( function() WFRingBuffer.make( 1.1 ) end )

	rxTest:expectEqual( {}, WFRingBuffer.map( function() end,
												WFRingBuffer.make( 1 ) ) )

end

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

local function makeSeq( i, n, seq )

	seq = seq or {}

	if n == 0 then

		return seq

	end

	seq[ #seq + 1 ] = i

	return makeSeq( i + 1, n - 1, seq )

end

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

local function justReturn( ... )

	return ...

end

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

local function testRingBufferMN( m, n, rxTest )

	if m == 0 then

		return

	end

	local rb = WFFunctionUtils.reduce ( WFRingBuffer.make( n ),
					WFRingBuffer.addItem,
						makeSeq( 1, m ) )
					
	local actualRbContents = WFRingBuffer.map( justReturn, rb )

	rxTest:logf( "Testing if adding %s items to ring buffer size %s has correct result", 
					m, n )

	rxTest:expectEqual( actualRbContents, 
							n == 1 and 
								{ m } or
							makeSeq( 
								m <= n and 1 or m - n + 1,
								m <= n and m or n ) )
	
end

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

local function testRingBufferN( n, rxTest )

	WFFunctionUtils.map( 
		testRingBufferMN,
			{ 1, n - 1, n, n + 1, n + 2, 2*n, 2 * n + 1 }, n, rxTest )
	
end

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

local function rxTestAdd( rxTest )

	WFFunctionUtils.map( 
		testRingBufferN,
			{ 1, 2, 3, 10, 50 }, rxTest )

end

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

local function rxTestAddNil( rxTest )

	local rb = WFRingBuffer.make( 5 )

	for _ = 1, 10 do

		rb = WFRingBuffer.addItem( rb, nil )

	end

	rxTest:expectEqual(
		WFRingBuffer.map( justReturn, rb ),
		{} )

end

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

local function rxTestAddFalse( rxTest )

	local rb = WFRingBuffer.make( 5 )

	local expected = {}

	for i = 1, 10 do

		rb = WFRingBuffer.addItem( rb, i <= 5 )

		if i <= 5 then

			expected[ i ] = false

		end

	end

	rxTest:expectEqual(
		WFRingBuffer.map( justReturn, rb ),
		expected )

end

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

local function rxTestFull( rxTest )

	local rb = WFRingBuffer.make( 5 )

	for i = 1, 10 do

		rb = WFRingBuffer.addItem( rb, i )

		rxTest:expectEqual( i >= 5, WFRingBuffer.full( rb ) )

	end

	rxTest:expectEqual( { 6, 7, 8, 9, 10 }, WFRingBuffer.map( justReturn, rb ) )

end

--==============================================================================

return WFRxTestCase.wrapSuite( 'WFRingBufferTest', {

	rxTestMake = rxTestMake,

	rxTestAdd = rxTestAdd,

	rxTestAddNil = rxTestAddNil,

	rxTestAddFalse = rxTestAddFalse,

	rxTestFull = rxTestFull,

}

)
