#include "ZUnitTest.hpp" //Hijack the assert #define ZSTL_ASSERT(condition, message) SST_OS_RuntimeAssert(condition, message) #include /* construction, size, capacity, empty and full */ static const char* test_Constructors_Array_Data_Length_Capacity(); static const char* test_Empty(); static const char* test_Full(); /* primary accessors */ static const char* test_Front(); static const char* test_Back(); /* primary removal operations */ static const char* test_PopFront(); static const char* test_PopBack(); /* primary add operations */ static const char* test_PushFront_OverflowUnsafe(); static const char* test_PushFront_OverflowAssert(); static const char* test_PushFront_OverflowIgnore(); static const char* test_PushFront_OverflowDropFront(); static const char* test_PushFront_OverflowDropBack(); static const char* test_PushFront_OverflowOverwrite(); static const char* test_PushFront_OverflowEvict(); static const char* test_PushFront_OverflowGrow(); static const char* test_PushBack_OverflowUnsafe(); static const char* test_PushBack_OverflowAssert(); static const char* test_PushBack_OverflowIgnore(); static const char* test_PushBack_OverflowDropFront(); static const char* test_PushBack_OverflowDropBack(); static const char* test_PushBack_OverflowOverwrite(); static const char* test_PushBack_OverflowEvict(); static const char* test_PushBack_OverflowGrow(); /* secondary accessors */ static const char* test_AbsoluteIndex(); static const char* test_At(); /* secondary removal operations */ static const char* test_Clear(); static const char* test_Erase(); /* secondary add operations */ static const char* test_Insert(); static const char* test_TryPushBack(); static const char* test_TryPushFront(); /* equivalence and assignment */ static const char* test_Equals(); static const char* test_Copy(); /* usage tests */ static const char* test_Stack(); static const char* test_Queue(); static const char* test_Alternating(); ZUnitTest ZRingBufferUnitTests[] = { { "ZRingBuffer: Constructors, Array, Size, Capacity", test_Constructors_Array_Data_Length_Capacity }, { "ZRingBuffer: Empty", test_Empty }, { "ZRingBuffer: Full", test_Full }, { "ZRingBuffer: Front", test_Front }, { "ZRingBuffer: Back", test_Back }, { "ZRingBuffer: PopFront", test_PopFront }, { "ZRingBuffer: PopBack", test_PopBack }, { "ZRingBuffer: PushFront (OverflowUnsafe)", test_PushFront_OverflowUnsafe }, { "ZRingBuffer: PushFront (OverflowAssert)", test_PushFront_OverflowAssert }, { "ZRingBuffer: PushFront (OverflowIgnore)", test_PushFront_OverflowIgnore }, { "ZRingBuffer: PushFront (OverflowDropFront)", test_PushFront_OverflowDropFront }, { "ZRingBuffer: PushFront (OverflowDropBack)", test_PushFront_OverflowDropBack }, { "ZRingBuffer: PushFront (OverflowOverwrite)", test_PushFront_OverflowOverwrite }, { "ZRingBuffer: PushFront (OverflowEvict)", test_PushFront_OverflowEvict }, { "ZRingBuffer: PushFront (OverflowGrow)", test_PushFront_OverflowGrow }, { "ZRingBuffer: PushBack (OverflowUnsafe)", test_PushBack_OverflowUnsafe }, { "ZRingBuffer: PushBack (OverflowAssert)", test_PushBack_OverflowAssert }, { "ZRingBuffer: PushBack (OverflowIgnore)", test_PushBack_OverflowIgnore }, { "ZRingBuffer: PushBack (OverflowDropFront)", test_PushBack_OverflowDropFront }, { "ZRingBuffer: PushBack (OverflowDropBack)", test_PushBack_OverflowDropBack }, { "ZRingBuffer: PushBack (OverflowOverwrite)", test_PushBack_OverflowOverwrite }, { "ZRingBuffer: PushBack (OverflowEvict)", test_PushBack_OverflowEvict }, { "ZRingBuffer: PushBack (OverflowGrow)", test_PushBack_OverflowGrow }, { "ZRingBuffer: AbsoluteIndex", test_AbsoluteIndex }, { "ZRingBuffer: At", test_At }, { "ZRingBuffer: Clear", test_Clear }, { "ZRingBuffer: Erase", test_Erase }, { "ZRingBuffer: Insert", test_Insert }, { "ZRingBuffer: TryPushBack", test_TryPushBack }, { "ZRingBuffer: TryPushFront", test_TryPushFront }, { "ZRingBuffer: Equals", test_Equals }, { "ZRingBuffer: Copy", test_Copy }, { "ZRingBuffer: Usage (Stack)", test_Stack }, { "ZRingBuffer: Usage (Queue)", test_Queue }, { "ZRingBuffer: Usage (Alternating)", test_Alternating } }; DECLARE_ZTESTBLOCK(ZRingBuffer); /*************************************************************************/ static const char* test_Constructors_Array_Data_Length_Capacity() { int testData[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; ZArray data1(testData, 10, 10); ZArray data2(testData, 6, 20); ZRingBuffer buf1; ZRingBuffer buf2(10); ZRingBuffer buf3(data1); ZRingBuffer buf4(data2); TASSERT(buf1.Array().Size() == ZRINGBUFFER_DEFAULT_CAPACITY, "Default constructor fails to properly initialize storage array!"); TASSERT(buf2.Array().Size() == 10, "Capacity constructor failed to properly initialize storage array!"); TASSERT(buf3.Array().Size() == 10, "Storage constructor failed to properly initialize storage array!"); for (int i = 0; i < (int)data1.Size(); i++) { TASSERT(buf3.Array()[i] == i, "Storage constructor failed to properly copy storage data!"); } for (int i = 0; i < (int)data2.Size(); i++) { TASSERT(buf4.Array()[i] == i, "Storage constructor (2) failed to properly copy storage data!"); } TASSERT(buf1.Size() == 0, "Default constructor initializes with incorrect size!"); TASSERT(buf1.Capacity() == ZRINGBUFFER_DEFAULT_CAPACITY, "Default constructor initializes with incorrect capacity!"); TASSERT(buf2.Size() == 0, "Capacity constructor initializes with incorrect size!"); TASSERT(buf2.Capacity() == 10, "Capacity constructor initializes with incorrect capacity!"); TASSERT(buf3.Size() == 10, "Storage constructor initializes with incorrect size!"); TASSERT(buf3.Capacity() == 10, "Storage constructor initializes with incorrect capacity!"); TASSERT(buf4.Size() == 6, "Storage constructor (2) initializes with incorrect size!"); TASSERT(buf4.Capacity() == 20, "Storage constructor (2) initializes with incorrect capacity!"); return ZTEST_SUCCESS; } /*************************************************************************/ static const char* test_Empty() { int testData[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; ZArray data1(testData, 10, 10); ZArray data2(testData, 6, 20); ZRingBuffer buf1; ZRingBuffer buf2(10); ZRingBuffer buf3(data1); ZRingBuffer buf4(data2); TASSERT(buf1.Empty(), "Empty() returns false on empty buffer!"); TASSERT(buf2.Empty(), "Empty() returns false on empty buffer with low capacity!"); TASSERT(!buf3.Empty(), "Empty() returns true on non-empty buffer with Size() = Capacity()!"); TASSERT(!buf4.Empty(), "Empty() returns true on non-empty buffer with Size() != Capacity()!"); return ZTEST_SUCCESS; } /*************************************************************************/ static const char* test_Full() { int testData[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; ZArray data1(testData, 10, 10); ZArray data2(testData, 6, 20); ZRingBuffer buf1; ZRingBuffer buf2(10); ZRingBuffer buf3(data1); ZRingBuffer buf4(data2); TASSERT(!buf1.Full(), "Full() returns true on empty buffer!"); TASSERT(!buf2.Full(), "Full() returns true on empty buffer with low capacity!"); TASSERT(buf3.Full(), "Full() returns false on non-empty buffer with Size() = Capacity()!"); TASSERT(!buf4.Full(), "Full() returns true on non-empty buffer with Size() != Capacity()!"); return ZTEST_SUCCESS; } /*************************************************************************/ static const char* test_Front() { int testData[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; ZArray data1(testData, 10, 10); ZArray data2(testData, 6, 20); ZRingBuffer buf1; ZRingBuffer buf2(10); ZRingBuffer buf3(data1); ZRingBuffer buf4(data2); ZTEST_BeginHandleAssert(); buf1.Front(); //This will ruin buf1, so don't use it anymore ZTEST_EndHandleAssert(); TASSERT(ZTEST_CheckAssert(), "Front() on empty buffer failed to trigger assert!"); TASSERT(buf3.Front() == 0, "Front() returns incorrect value on non-empty buffer!"); TASSERT(buf4.Front() == 0, "Front() returns incorrect value on second non-empty buffer!"); return ZTEST_SUCCESS; } /*************************************************************************/ static const char* test_Back() { int testData[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; ZArray data1(testData, 10, 10); ZArray data2(testData, 6, 20); ZRingBuffer buf1; ZRingBuffer buf2(10); ZRingBuffer buf3(data1); ZRingBuffer buf4(data2); ZTEST_BeginHandleAssert(); buf1.Back(); //This will ruin buf1, so don't use it anymore ZTEST_EndHandleAssert(); TASSERT(ZTEST_CheckAssert(), "Back() on empty buffer failed to trigger assert!"); TASSERT(buf3.Back() == 9, "Back() returns incorrect value on non-empty buffer!"); TASSERT(buf4.Back() == 5, "Back() returns incorrect value on second non-empty buffer!"); return ZTEST_SUCCESS; } /*************************************************************************/ static const char* test_PopFront() { int testData[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; ZArray data1(testData, 10, 10); ZArray data2(testData, 6, 20); ZRingBuffer buf1; ZRingBuffer buf2(10); ZRingBuffer buf3(data1); ZRingBuffer buf4(data2); int i; ZTEST_BeginHandleAssert(); buf1.PopFront(); //This will ruin buf1, so don't use it anymore ZTEST_EndHandleAssert(); TASSERT(ZTEST_CheckAssert(), "PopFront() on empty buffer failed to trigger assert!"); i = buf3.PopFront(); TASSERT(i == 0, "PopFront() returned incorrect value for first element!"); TASSERT(buf3.Size() == 9, "PopFront() failed to reduce buffer size!"); TASSERT(buf3.Capacity() == 10, "PopFront improperly reduced capacity!"); for (i = 1; i < 9; i++) { TASSERT(buf3.PopFront() == i, "PopFront() returned incorrect value when looping through buf3!"); } TASSERT(buf3.Size() == 1, "PopFront() x 8 failed to reduce buffer to one element!"); i = buf3.PopFront(); TASSERT(i == 9, "PopFront() returned incorrect value on last element!"); TASSERT(buf3.Size() == 0, "PopFront() on last element did not reduce buffer size to zero!"); return ZTEST_SUCCESS; } /*************************************************************************/ static const char* test_PopBack() { int testData[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; ZArray data1(testData, 10, 10); ZArray data2(testData, 6, 20); ZRingBuffer buf1; ZRingBuffer buf2(10); ZRingBuffer buf3(data1); ZRingBuffer buf4(data2); int i; ZTEST_BeginHandleAssert(); buf1.PopBack(); //This will ruin buf1, so don't use it anymore ZTEST_EndHandleAssert(); TASSERT(ZTEST_CheckAssert(), "PopBack() on empty buffer failed to trigger assert!"); i = buf3.PopBack(); TASSERT(i == 9, "PopBack() returned incorrect value for last element!"); TASSERT(buf3.Size() == 9, "PopBack() failed to reduce buffer size!"); TASSERT(buf3.Capacity() == 10, "PopBack improperly reduced capacity!"); for (i = 8; i > 5; i--) { TASSERT(buf3.PopBack() == i, "PopBack() returned incorrect value when looping through buf3!"); } for (i = 0; i < 5; i++) buf3.PopFront(); TASSERT(buf3.Size() == 1, "PopBack() / PopFront() combo failed to reduce buffer to correct size!"); return ZTEST_SUCCESS; } /*************************************************************************/ const char* test_PushFront_ErrorMsg = NULL; #define PF_TASSERT(condition, msg) if (!(condition)) { test_PushFront_ErrorMsg = msg; return false; } /* This little helper method will test an empty ring buffer push front function and return a full buffer that has been wrap-around tested so you can test the specifics of overflow looks like the following when done: [ (Back)0, (Front) 9, 8, 7, 6, 5, 4, 3, 2, 1 ] */ template inline bool test_PushFront(ZRingBuffer& buffer) { int i; buffer.PushFront(0); PF_TASSERT(buffer.Size() == 1, "PushFront() does not properly increment size!"); PF_TASSERT(buffer.Front() == 0, "PushFront() does not properly set value for Front()!"); PF_TASSERT(buffer.Back() == 0, "PushFront() does not properly set value for Back()!"); for (i = 1; i < 10; i++) buffer.PushFront(i); PF_TASSERT(buffer.Size() == 10, "PushFront() does not properly handle wrap-around!"); PF_TASSERT(buffer.Front() == 9, "PushFront() does not correctly set Front() value after wrap-around!"); PF_TASSERT(buffer.Back() == 0, "PushFront() improperly modifies Back() value after wrap-around!"); return true; } static const char* test_PushFront_OverflowUnsafe() { int testData[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; ZArray data1(testData, 10, 10); ZArray data2(testData, 6, 20); ZRingBuffer buf1; ZRingBuffer buf2(10); ZRingBuffer buf3(data1); ZRingBuffer buf4(data2); if (!test_PushFront(buf2)) return test_PushFront_ErrorMsg; //Test the unsafe behavior (this will actually invalidate the buffer, so BEWARE) buf2.PushFront(15); TASSERT(buf2.Front() == buf2.Back(), "PushFront() does not properly overwrite the back value when overflow occurs!"); return ZTEST_SUCCESS; } /*************************************************************************/ static const char* test_PushFront_OverflowAssert() { int testData[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; ZArray data1(testData, 10, 10); ZArray data2(testData, 6, 20); ZRingBuffer buf1; ZRingBuffer buf2(10); ZRingBuffer buf3(data1); ZRingBuffer buf4(data2); if (!test_PushFront(buf2)) return test_PushFront_ErrorMsg; ZTEST_BeginHandleAssert(); buf2.PushFront(15); //This will ruin buf2, so don't use it anymore ZTEST_EndHandleAssert(); TASSERT(ZTEST_CheckAssert(), "PushFront() on full buffer failed to assert!"); return ZTEST_SUCCESS; } /*************************************************************************/ static const char* test_PushFront_OverflowIgnore() { int testData[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; ZArray data1(testData, 10, 10); ZArray data2(testData, 6, 20); ZRingBuffer buf1; ZRingBuffer buf2(10); ZRingBuffer buf3(data1); ZRingBuffer buf4(data2); if (!test_PushFront(buf2)) return test_PushFront_ErrorMsg; buf2.PushFront(15); TASSERT(buf2.Front() == 9, "PushFront() added element on full buffer with ZRingBuffer_OverflowIgnore policy (Front)!"); TASSERT(buf2.Back() == 0, "PushFront() added element on full buffer with ZRingBuffer_OverflowIgnore policy (Back)!"); TASSERT(buf2.Size() == 10, "PushFront() added element on full buffer with ZRingBuffer_OverflowIgnore policy (Size)!"); TASSERT(buf2.Full(), "PushFront() added element on full buffer with ZRingBuffer_OverflowIgnore policy (Full)!"); return ZTEST_SUCCESS; } /*************************************************************************/ static const char* test_PushFront_OverflowDropFront() { int testData[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; ZArray data1(testData, 10, 10); ZArray data2(testData, 6, 20); ZRingBuffer buf1; ZRingBuffer buf2(10); ZRingBuffer buf3(data1); ZRingBuffer buf4(data2); if (!test_PushFront(buf2)) return test_PushFront_ErrorMsg; buf2.PushFront(15); TASSERT(buf2.Front() == 15, "PushFront() failed to drop front element with ZRingBuffer_OverflowDropFront policy!"); TASSERT(buf2.Back() == 0, "PushFront() improperly modified back element with ZRingBuffer_OverflowDropFront policy!"); TASSERT(buf2.Size() == 10, "PushFront() failed to keep size with ZRingBuffer_OverflowDropFront policy!"); TASSERT(buf2.Full(), "PushFront() failed to keep buffer full with ZRingBuffer_OverflowDropFront policy!"); return ZTEST_SUCCESS; } /*************************************************************************/ static const char* test_PushFront_OverflowDropBack() { int testData[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; ZArray data1(testData, 10, 10); ZArray data2(testData, 6, 20); ZRingBuffer buf1; ZRingBuffer buf2(10); ZRingBuffer buf3(data1); ZRingBuffer buf4(data2); if (!test_PushFront(buf2)) return test_PushFront_ErrorMsg; buf2.PushFront(15); TASSERT(buf2.Front() == 15, "PushFront() failed to change front element with ZRingBuffer_OverflowDropBack policy!"); TASSERT(buf2.Back() == 1, "PushFront() failed to drop back element with ZRingBuffer_OverflowDropBack policy!"); TASSERT(buf2.Size() == 10, "PushFront() failed to keep size with ZRingBuffer_OverflowDropBack policy!"); TASSERT(buf2.Full(), "PushFront() failed to keep buffer full with ZRingBuffer_OverflowDropBack policy!"); return ZTEST_SUCCESS; } /*************************************************************************/ static const char* test_PushFront_OverflowOverwrite() { int testData[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; ZArray data1(testData, 10, 10); ZArray data2(testData, 6, 20); ZRingBuffer buf1; ZRingBuffer buf2(10); ZRingBuffer buf3(data1); ZRingBuffer buf4(data2); if (!test_PushFront(buf2)) return test_PushFront_ErrorMsg; buf2.PushFront(15); TASSERT(buf2.Front() == 15, "PushFront() failed to overwrite front element with ZRingBuffer_OverflowOverwrite policy!"); TASSERT(buf2.Back() == 0, "PushFront() improperly modified back element with ZRingBuffer_OverflowOverwrite policy!"); TASSERT(buf2.Size() == 10, "PushFront() failed to keep size with ZRingBuffer_OverflowOverwrite policy!"); TASSERT(buf2.Full(), "PushFront() failed to keep buffer full with ZRingBuffer_OverflowOverwrite policy!"); return ZTEST_SUCCESS; } /*************************************************************************/ static const char* test_PushFront_OverflowEvict() { int testData[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; ZArray data1(testData, 10, 10); ZArray data2(testData, 6, 20); ZRingBuffer buf1; ZRingBuffer buf2(10); ZRingBuffer buf3(data1); ZRingBuffer buf4(data2); if (!test_PushFront(buf2)) return test_PushFront_ErrorMsg; buf2.PushFront(15); TASSERT(buf2.Front() == 15, "PushFront() failed to change front element with ZRingBuffer_OverflowEvict policy!"); TASSERT(buf2.Back() == 1, "PushFront() failed to evict back element with ZRingBuffer_OverflowEvict policy!"); TASSERT(buf2.Size() == 10, "PushFront() failed to keep size with ZRingBuffer_OverflowEvict policy!"); TASSERT(buf2.Full(), "PushFront() failed to keep buffer full with ZRingBuffer_OverflowEvict policy!"); return ZTEST_SUCCESS; } /*************************************************************************/ static const char* test_PushFront_OverflowGrow() { int testData[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; ZArray data1(testData, 10, 10); ZArray data2(testData, 6, 20); ZRingBuffer buf1; ZRingBuffer buf2(10); ZRingBuffer buf3(data1); ZRingBuffer buf4(data2); if (!test_PushFront(buf2)) return test_PushFront_ErrorMsg; buf2.PushFront(15); TASSERT(buf2.Front() == 15, "PushFront() failed to add front element with ZRingBuffer_OverflowGrow policy!"); TASSERT(buf2.Back() == 0, "PushFront() improperly modified back element with ZRingBuffer_OverflowGrow policy!"); TASSERT(buf2.Size() == 11, "PushFront() did not properly increment size with ZRingBuffer_OverflowGrow policy!"); TASSERT(buf2.Capacity() > 10, "PushFront() did not properly grow the buffer with ZRingBuffer_OverflowGrow policy!"); return ZTEST_SUCCESS; } /*************************************************************************/ const char* test_PushBack_ErrorMsg = NULL; #define PB_TASSERT(condition, msg) if (!(condition)) { test_PushBack_ErrorMsg = msg; return false; } /* This little helper method will test an empty ring buffer push front function and return a full buffer that has been wrap-around tested so you can test the specifics of overflow looks like the following when done: [ 6, 7, 8, 9, (Front) 0, (Back) 1, 2, 3, 4, 5 ] */ template inline bool test_PushBack(ZRingBuffer& buffer) { int i; buffer.PushBack(0); PB_TASSERT(buffer.Size() == 1, "PushBack() does not properly increment size!"); PB_TASSERT(buffer.Front() == 0, "PushBack() does not properly set value for Front()!"); PB_TASSERT(buffer.Back() == 0, "PushBack() does not properly set value for Back()!"); for (i = 1; i < 5; i++) buffer.PushBack(i); for (i = 5; i < 10; i++) buffer.PushFront(i); //Current layout: [ 0, 1, 2, 3, (Back) 4, (Front) 9, 8, 7, 6, 5 ] for (i = 0; i < 5; i++) { PB_TASSERT(buffer.Array()[i] == i, "PushBack() does not correctly set values!"); PB_TASSERT(buffer.Array()[9 - i] == 5 + i, "PushFront() does not correctly set values!"); } for (i = 0; i < 10; i++) { buffer.PopFront(); buffer.PushBack(i); } //New layout: [ 5, 6, 7, 8, (Back) 9, (Front) 0, 1, 2, 3, 4 ] for (i = 0; i < 5; i++) { PB_TASSERT(buffer.Array()[i] == i + 5, "PopFront()/PushBack() does not correctly set values!"); PB_TASSERT(buffer.Array()[i + 5] == i, "PopFront()/PushBack() does not correctly set values!"); } PB_TASSERT(buffer.Size() == 10, "PushFront() does not properly handle wrap-around!"); PB_TASSERT(buffer.Front() == 0, "Buffer does not correctly set Front() value after wrap-around!"); PB_TASSERT(buffer.Back() == 9, "Buffer improperly modifies Back() value after wrap-around!"); return true; } static const char* test_PushBack_OverflowUnsafe() { int testData[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; ZArray data1(testData, 10, 10); ZArray data2(testData, 6, 20); ZRingBuffer buf1; ZRingBuffer buf2(10); ZRingBuffer buf3(data1); ZRingBuffer buf4(data2); if (!test_PushBack(buf2)) return test_PushBack_ErrorMsg; //Test the unsafe behavior (this will actually invalidate the buffer, so BEWARE) buf2.PushBack(15); TASSERT(buf2.Front() == buf2.Back(), "PushBack() does not properly overwrite the back value when overflow occurs!"); return ZTEST_SUCCESS; } /*************************************************************************/ static const char* test_PushBack_OverflowAssert() { int testData[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; ZArray data1(testData, 10, 10); ZArray data2(testData, 6, 20); ZRingBuffer buf1; ZRingBuffer buf2(10); ZRingBuffer buf3(data1); ZRingBuffer buf4(data2); if (!test_PushBack(buf2)) return test_PushBack_ErrorMsg; ZTEST_BeginHandleAssert(); buf2.PushBack(15); //This will ruin buf2, so don't use it anymore ZTEST_EndHandleAssert(); TASSERT(ZTEST_CheckAssert(), "PushBack() on full buffer failed to assert!"); return ZTEST_SUCCESS; } /*************************************************************************/ static const char* test_PushBack_OverflowIgnore() { int testData[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; ZArray data1(testData, 10, 10); ZArray data2(testData, 6, 20); ZRingBuffer buf1; ZRingBuffer buf2(10); ZRingBuffer buf3(data1); ZRingBuffer buf4(data2); if (!test_PushBack(buf2)) return test_PushBack_ErrorMsg; buf2.PushBack(15); TASSERT(buf2.Back() == 9, "PushBack() added element on full buffer with ZRingBuffer_OverflowIgnore policy (Back)!"); TASSERT(buf2.Front() == 0, "PushBack() added element on full buffer with ZRingBuffer_OverflowIgnore policy (Front)!"); TASSERT(buf2.Size() == 10, "PushBack() added element on full buffer with ZRingBuffer_OverflowIgnore policy (Size)!"); TASSERT(buf2.Full(), "PushBack() added element on full buffer with ZRingBuffer_OverflowIgnore policy (Full)!"); return ZTEST_SUCCESS; } /*************************************************************************/ static const char* test_PushBack_OverflowDropFront() { int testData[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; ZArray data1(testData, 10, 10); ZArray data2(testData, 6, 20); ZRingBuffer buf1; ZRingBuffer buf2(10); ZRingBuffer buf3(data1); ZRingBuffer buf4(data2); if (!test_PushBack(buf2)) return test_PushBack_ErrorMsg; buf2.PushBack(15); TASSERT(buf2.Back() == 15, "PushBack() failed to correctly set back element with ZRingBuffer_OverflowDropFront policy!"); TASSERT(buf2.Front() == 1, "PushBack() failed to drop front element with ZRingBuffer_OverflowDropFront policy!"); TASSERT(buf2.Size() == 10, "PushBack() failed to keep size with ZRingBuffer_OverflowDropFront policy!"); TASSERT(buf2.Full(), "PushBack() failed to keep buffer full with ZRingBuffer_OverflowDropFront policy!"); return ZTEST_SUCCESS; } /*************************************************************************/ static const char* test_PushBack_OverflowDropBack() { int testData[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; ZArray data1(testData, 10, 10); ZArray data2(testData, 6, 20); ZRingBuffer buf1; ZRingBuffer buf2(10); ZRingBuffer buf3(data1); ZRingBuffer buf4(data2); if (!test_PushBack(buf2)) return test_PushBack_ErrorMsg; buf2.PushBack(15); TASSERT(buf2.Back() == 15, "PushBack() failed to correctly set back element with ZRingBuffer_OverflowDropBack policy!"); TASSERT(buf2.Front() == 0, "PushBack() improperly modified front element with ZRingBuffer_OverflowDropBack policy!"); TASSERT(buf2.Size() == 10, "PushBack() failed to keep size with ZRingBuffer_OverflowDropBack policy!"); TASSERT(buf2.Full(), "PushBack() failed to keep buffer full with ZRingBuffer_OverflowDropBack policy!"); return ZTEST_SUCCESS; } /*************************************************************************/ static const char* test_PushBack_OverflowOverwrite() { int testData[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; ZArray data1(testData, 10, 10); ZArray data2(testData, 6, 20); ZRingBuffer buf1; ZRingBuffer buf2(10); ZRingBuffer buf3(data1); ZRingBuffer buf4(data2); if (!test_PushBack(buf2)) return test_PushBack_ErrorMsg; buf2.PushBack(15); TASSERT(buf2.Back() == 15, "PushBack() failed to correctly overwrite back element with ZRingBuffer_OverflowOverwrite policy!"); TASSERT(buf2.Front() == 0, "PushBack() improperly modified front element with ZRingBuffer_OverflowOverwrite policy!"); TASSERT(buf2.Size() == 10, "PushBack() failed to keep size with ZRingBuffer_OverflowOverwrite policy!"); TASSERT(buf2.Full(), "PushBack() failed to keep buffer full with ZRingBuffer_OverflowOverwrite policy!"); return ZTEST_SUCCESS; } /*************************************************************************/ static const char* test_PushBack_OverflowEvict() { int testData[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; ZArray data1(testData, 10, 10); ZArray data2(testData, 6, 20); ZRingBuffer buf1; ZRingBuffer buf2(10); ZRingBuffer buf3(data1); ZRingBuffer buf4(data2); if (!test_PushBack(buf2)) return test_PushBack_ErrorMsg; buf2.PushBack(15); TASSERT(buf2.Back() == 15, "PushBack() failed to correctly set back element with ZRingBuffer_OverflowEvict policy!"); TASSERT(buf2.Front() == 1, "PushBack() failed to evict front element with ZRingBuffer_OverflowEvict policy!"); TASSERT(buf2.Size() == 10, "PushBack() failed to keep size with ZRingBuffer_OverflowEvict policy!"); TASSERT(buf2.Full(), "PushBack() failed to keep buffer full with ZRingBuffer_OverflowEvict policy!"); return ZTEST_SUCCESS; } /*************************************************************************/ static const char* test_PushBack_OverflowGrow() { int testData[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; ZArray data1(testData, 10, 10); ZArray data2(testData, 6, 20); ZRingBuffer buf1; ZRingBuffer buf2(10); ZRingBuffer buf3(data1); ZRingBuffer buf4(data2); if (!test_PushBack(buf2)) return test_PushBack_ErrorMsg; buf2.PushBack(15); TASSERT(buf2.Back() == 15, "PushBack() failed to add back element with ZRingBuffer_OverflowGrow policy!"); TASSERT(buf2.Front() == 0, "PushBack() improperly modified front element with ZRingBuffer_OverflowGrow policy!"); TASSERT(buf2.Size() == 11, "PushBack() did not properly increment size with ZRingBuffer_OverflowGrow policy!"); TASSERT(buf2.Capacity() > 10, "PushBack() did not properly grow the buffer with ZRingBuffer_OverflowGrow policy!"); return ZTEST_SUCCESS; } /*************************************************************************/ static const char* test_AbsoluteIndex() { int testData[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; ZArray data1(testData, 10, 10); ZArray data2(testData, 6, 20); ZRingBuffer buf1; ZRingBuffer buf2(10); ZRingBuffer buf3(data1); ZRingBuffer buf4(data2); size_t i; for (i = 0; i < buf3.Size(); i++) { TASSERT(buf3.ActualIndex(i) == i, "AbsoluteIndex() does not return correct value on aligned buffer!"); } buf3.PopBack(); TASSERT(buf3.ActualIndex(0) == 0, "AbsoluteIndex(0) returns non-zero after PopBack()!"); buf3.PopFront(); TASSERT(buf3.ActualIndex(0) == 1, "AbsoluteIndex(0) returns incorrect value after PopFront()!"); buf3.PushBack(9); buf3.PushBack(10); //New layout: [(Back) 10, (Front) 1, 2, 3, 4, 5, 6, 7, 8, 9 ] TASSERT(buf3.ActualIndex(9) == 0, "AbsoluteIndex(9) returns incorrect value with Back < Front!"); buf3.PopFront(); ZTEST_BeginHandleAssert(); buf3.ActualIndex(9); ZTEST_EndHandleAssert(); TASSERT(ZTEST_CheckAssert(), "AbsoluteIndex(9) with 9 out-of-bounds did not trigger assert!"); return ZTEST_SUCCESS; } /*************************************************************************/ static const char* test_At() { int testData[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; ZArray data1(testData, 10, 10); ZArray data2(testData, 6, 20); ZRingBuffer buf1; ZRingBuffer buf2(10); ZRingBuffer buf3(data1); ZRingBuffer buf4(data2); int i; for (i = 0; i < (int)buf3.Size(); i++) { TASSERT(buf3.At(i) == i, "At() does not return correct value on aligned buffer!"); } buf3.PopBack(); TASSERT(buf3.At(0) == 0, "At(0) returns non-zero after PopBack()!"); buf3.PopFront(); TASSERT(buf3.At(0) == 1, "At(0) returns incorrect value after PopFront()!"); buf3.PushBack(9); buf3.PushBack(10); //New layout: [(Back) 10, (Front) 1, 2, 3, 4, 5, 6, 7, 8, 9 ] TASSERT(buf3.At(9) == 10, "At(9) returns incorrect value with Back < Front!"); buf3.PopFront(); ZTEST_BeginHandleAssert(); buf3.At(9); ZTEST_EndHandleAssert(); TASSERT(ZTEST_CheckAssert(), "At(9) with 9 out-of-bounds did not trigger assert!"); return ZTEST_SUCCESS; } /*************************************************************************/ static const char* test_Clear() { int testData[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; ZArray data1(testData, 10, 10); ZArray data2(testData, 6, 20); ZRingBuffer buf1; ZRingBuffer buf2(10); ZRingBuffer buf3(data1); ZRingBuffer buf4(data2); buf3.Clear(); TASSERT(buf3.Size() == 0, "Clear() failed to reduce buffer size to zero!"); TASSERT(buf3.Capacity() == 10, "Clear() improperly reduced capacity!"); buf4.Clear(64); TASSERT(buf4.Size() == 0, "Clear(64) failed to reduce buffer size to zero!"); TASSERT(buf4.Capacity() == 64, "Clear(64) failed to set proper capacity!"); return ZTEST_SUCCESS; } /*************************************************************************/ static const char* test_Erase() { int testData[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; ZArray data1(testData, 10, 10); ZArray data2(testData, 6, 20); ZRingBuffer buf1; ZRingBuffer buf2(10); ZRingBuffer buf3(data1); ZRingBuffer buf4(data2); buf3.PopFront(); buf3.PushBack(10); //New layout: [(Back) 10, (Front) 1, 2, 3, 4, 5, 6, 7, 8, 9 ] buf3.Erase(0); TASSERT(buf3.Size() == 9, "Erase() did not correctly reduce size!"); TASSERT(buf3.At(0) == 2, "Erase() did not erase correct element!"); buf3.Erase(4, 6); TASSERT(buf3.Size() == 7, "Erase(i, j) did not correctly reduce size!"); TASSERT(buf3.At(4) == 8, "Erase(i, j) did not erase correct elements!"); TASSERT(buf3.At(5) == 9, "Erase(i, j) did not erase correct elements!"); return ZTEST_SUCCESS; } /*************************************************************************/ static const char* test_Insert() { int testData[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; ZArray data1(testData, 10, 10); ZArray data2(testData, 6, 20); ZRingBuffer buf1; ZRingBuffer buf2(10); ZRingBuffer buf3(data1); ZRingBuffer buf4(data2); buf3.PopFront(); buf3.PushBack(10); buf3.PopFront(); buf3.PopFront(); //New layout: [(Back) 10, x, x, (Front) 3, 4, 5, 6, 7, 8, 9 ] buf3.Insert(2, 15, 1); //Insert at index 2 the value 15, 1 time //New layout: [(Front) 3, 4, 15, 5, 6, 7, 8, 9, (Back) 10, x ] TASSERT(buf3.Size() == 9, "Insert(i, j, k) did not correctly increase buffer size!"); TASSERT(buf3.Front() == 3, "Insert(i, j, k) improperly modified Front() value!"); TASSERT(buf3.Back() == 10, "Insert(i, j, k) improperly modified Back() value!"); TASSERT(buf3.At(2) == 15, "Insert(i, j, k) did not insert correct value at location 2!"); buf3.PopFront(); buf3.PopFront(); //New layout: [ x, x, (Front) 15, 5, 6, 7, 8, 9, (Back) 10, x ] buf3.Insert(1, 15, 2); //Insert at index 1 the value 15, 2 times //New layout: [ (Front) 15, 15, 15, 5, 6, 7, 8, 9, (Back) 10, x ] TASSERT(buf3.Size() == 9, "Insert(i, j, 2k) did not correctly increase buffer size!"); TASSERT(buf3.Front() == 15, "Insert(i, j, 2k) improperly modified Front() value!"); TASSERT(buf3.Back() == 10, "Insert(i, j, 2k) improperly modified Back() value!"); TASSERT(buf3.At(1) == 15, "Insert(i, j, 2k) did not insert correct value at location 1!"); TASSERT(buf3.At(2) == 15, "Insert(i, j, 2k) did not insert correct value at location 2!"); buf3.PopFront(); buf3.PopFront(); buf3.PopFront(); //New layout: [ x, x, x, (Front) 5, 6, 7, 8, 9, (Back) 10, x ] ZArray data3(testData, 4, 10); //Array [0, 1, 2, 3] with capacity 10 buf3.Insert(6, data3); //New layout: [ (Front) 5, 6, 7, 8, 9, 10, 0, 1, 2, (Back) 3 ] TASSERT(buf3.Size() == 10, "Insert(i, array) did not correctly increase buffer size!"); TASSERT(buf3.Front() == 5, "Insert(i, array) improperly modified Front() value!"); TASSERT(buf3.Back() == 3, "Insert(i, array) did not correctly set Back() value!"); TASSERT(buf3.At(5) == 10, "Insert(i, array) improperly set At(5) value!"); TASSERT(buf3.At(6) == 0, "Insert(i, array) did not correctly set At(6) value!"); ZRingBuffer buf5(data1); buf5.Insert(0, buf3, 6, 4); //Insert at index 0 the values contained in buf3 starting at index 6 (4 values) //New layout: [ (Front) 0, 1, 2, 3, 0, 1, 2, 3, 4, 5, 6, 7, 8, (Back) 9 ] TASSERT(buf5.Size() == 14, "Insert(i, buffer) did not correctly increase buffer size!"); TASSERT(buf5.Front() == 0, "Insert(i, buffer) did not correctly set Front() value!"); TASSERT(buf5.Back() == 9, "Insert(i, buffer) improperly modified Back() value!"); return ZTEST_SUCCESS; } /*************************************************************************/ static const char* test_TryPushBack() { int testData[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; ZArray data1(testData, 10, 10); ZArray data2(testData, 6, 20); ZRingBuffer buf1; ZRingBuffer buf2(10); ZRingBuffer buf3(data1); ZRingBuffer buf4(data2); bool val; val = buf1.TryPushBack(0); TASSERT(val == true, "TryPushBack() fails with empty buffer!"); val = buf3.TryPushBack(0); TASSERT(val == false, "TryPushBack() succeeds with full buffer!"); return ZTEST_SUCCESS; } /*************************************************************************/ static const char* test_TryPushFront() { int testData[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; ZArray data1(testData, 10, 10); ZArray data2(testData, 6, 20); ZRingBuffer buf1; ZRingBuffer buf2(10); ZRingBuffer buf3(data1); ZRingBuffer buf4(data2); bool val; val = buf1.TryPushFront(0); TASSERT(val == true, "TryPushFront() fails with empty buffer!"); val = buf3.TryPushFront(0); TASSERT(val == false, "TryPushFront() succeeds with full buffer!"); return ZTEST_SUCCESS; } /*************************************************************************/ static const char* test_Equals() { int testData[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; ZArray data1(testData, 10, 10); ZArray data2(testData, 6, 20); ZRingBuffer buf1; ZRingBuffer buf2(10); ZRingBuffer buf3(data1); ZRingBuffer buf4(data2); ZRingBuffer buf5(data2); TASSERT(buf1.Equals(buf1), "Equals returns false on same buffer!"); TASSERT(buf1.Equals(buf2), "Equals returns false on buffers with different capacity!"); TASSERT(!buf1.Equals(buf3), "Equals returns true on empty buffer and 10-element buffer!"); TASSERT(!buf1.Equals(buf4), "Equals returns true on empty buffer and 6-element buffer!"); TASSERT(buf3.Equals(buf3), "Equals returns false on same (non-empty) buffer!"); TASSERT(!buf3.Equals(buf4), "Equals returns true on non-equivalent buffers!"); TASSERT(buf4.Equals(buf5), "Equals returns false on equivalent buffers!"); return ZTEST_SUCCESS; } /*************************************************************************/ static const char* test_Copy() { int testData[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; ZArray data1(testData, 10, 10); ZArray data2(testData, 6, 20); ZRingBuffer buf1; ZRingBuffer buf2(10); ZRingBuffer buf3(data1); ZRingBuffer buf4(data2); buf1.Copy(buf2); TASSERT(buf1.Empty(), "Copy() fails on empty buffer source and target!"); buf1.Copy(buf3); TASSERT(buf1.Equals(buf3), "Equals() returns false after Copy() with empty target!"); buf4.Copy(buf3); TASSERT(buf4.Equals(buf3), "Equals() returns false after Copy() with non-empty target!"); buf4.Copy(buf2); TASSERT(buf4.Empty(), "Copy() fails with empty buffer source and non-empty target!"); return ZTEST_SUCCESS; } /*************************************************************************/ static const char* test_Stack() { int testData[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; //Test using front loading ZRingBuffer buf1(10); for (int i = 0; i < 5; i++) buf1.PushFront(testData[i]); TASSERT (buf1.Size() == 5, "After 5 front pushes, Size() returned something other than 5!"); for (int i = 0; i < 5; i++) { int temp = buf1.PopFront(); TASSERT(temp == testData[4 - i], "Ring buffer corrupted while front loading as stack!"); } //Test using back loading ZRingBuffer buf2(10); for (int i = 0; i < 5; i++) buf2.PushBack(testData[i]); TASSERT(buf2.Size() == 5, "After 5 back pushes, Size() returned something other than 5!"); for (int i = 0; i < 5; i++) { int temp = buf2.PopBack(); TASSERT(temp == testData[4 - i], "Ring buffer corrupted while back loading as stack!"); } return ZTEST_SUCCESS; } /*************************************************************************/ static const char* test_Queue() { int testData[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; //Test front loading ZRingBuffer buf1(10); for (int i = 0; i < 5; i++) buf1.PushFront(testData[i]); TASSERT(buf1.Size() == 5, "After 5 front pushes, Size() returned something other than 5!"); for (int i = 0; i < 5; i++) { int temp = buf1.PopBack(); TASSERT(temp == testData[i], "Ring buffer corrupted while front loading as queue!"); } //Test back loading ZRingBuffer buf2(10); for (int i = 0; i < 5; i++) buf2.PushBack(testData[i]); TASSERT(buf2.Size() == 5, "After 5 back pushes, GetSize() returned something other than 5!"); for (int i = 0; i < 5; i++) { int temp = buf2.PopFront(); TASSERT(temp == testData[i], "Ring buffer corrupted while back loading as queue!"); } return ZTEST_SUCCESS; } /*************************************************************************/ static const char* test_Alternating() { ZRingBuffer buffer(10); int testArray[] = {0, 1, 2, 3, 4, 5, 6, 7}; int correctResults[] = {7, 5, 3, 1, 0, 2, 4, 6}; buffer.PushFront(testArray[0]); buffer.PushBack(testArray[1]); buffer.PushFront(testArray[2]); buffer.PushBack(testArray[3]); buffer.PushFront(testArray[4]); buffer.PushBack(testArray[5]); buffer.PushFront(testArray[6]); buffer.PushBack(testArray[7]); TASSERT(buffer.Size() == 8, "After 8 pushes, ring buffer returned something other than 8!"); for (int i = 0; i < 8; i++) { int temp = buffer.PopBack(); TASSERT(temp == correctResults[i], "Ring buffer corrupted while alternate loading!"); } return ZTEST_SUCCESS; }