#include "ZUnitTest.hpp" #include #include static const char* test_Constructors_PushBack_Size_Empty(); static const char* test_Begin_End_At_Iterator(); static const char* test_Allocator_Front_Back_Clear(); static const char* test_Copy_Equals(); static const char* test_PushFront_PopBack_PopFront(); static const char* test_Insert_Erase(); static const char* test_Swap_Splice_SwapNodes(); //List of unit tests ZUnitTest ZListUnitTests[] = { { "ZList: Constructors, PushBack, Size, Empty", test_Constructors_PushBack_Size_Empty }, { "ZList: Begin, End, At, Iterator", test_Begin_End_At_Iterator }, { "ZList: Allocator, Front, Back, Clear", test_Allocator_Front_Back_Clear }, { "ZList: Copy, Equals", test_Copy_Equals }, { "ZList: PushFront, PopBack, PopFront", test_PushFront_PopBack_PopFront }, { "ZList: Insert, Erase", test_Insert_Erase }, { "ZList: Swap, Splice, SwapNodes", test_Swap_Splice_SwapNodes } }; //Now declare the ZUnitTestBlock associated with this. DECLARE_ZTESTBLOCK(ZList); /*************************************************************************/ static const char* test_Constructors_PushBack_Size_Empty() { //Test our default list constructor with default allocator ZList list1; //Should start empty TASSERT(list1.Size() == 0, "Size() returns non-zero value but should be empty!"); TASSERT(list1.Empty() == true, "Empty() returns false on newly created list!"); //Fill in with 5 elements for(int i = 0; i < 5; i++) { list1.PushBack(i); TASSERT(list1.Size() == (size_t)(i + 1), "Size() returns incorrect value after PushBack()!"); TASSERT(list1.Empty() == false, "Empty() returns true on list with elements!"); } return ZTEST_SUCCESS; } /*************************************************************************/ static const char* test_Begin_End_At_Iterator() { int i; ZList list1; ZList::Iterator itr1; ZListIterator itr2; itr1 = list1.Begin(); TASSERT(itr1.HasNext() == false, "Iterator HasNext() returns true on empty list iterator!"); TASSERT(itr1.HasPrev() == false, "Iterator HasPrev() returns true on empty list iterator!"); TASSERT(itr1.HasCurrent() == false, "Iterator HasCurrent() returns false on empty list iterator!"); for(int i = 0; i < 5; i++) list1.PushBack(i); //These calls will invalidate the iterator, or, rather, have it point to 'End' itr1 = list1.Begin(); TASSERT(itr1.HasNext() == true, "Iterator HasNext() returns false when elements remain!"); TASSERT(itr1.HasPrev() == false, "Iterator HasPrevious() returns true at list Begin()!"); //Check going forwards for (itr1 = list1.Begin(), i = 0; i < 5; itr1++, i++) { TASSERT(itr1.HasCurrent() == true, "Iterator HasCurrent() returns false when elements should exist!"); TASSERT(itr1.Get() == i, "Iterator Get() does not return correct value when iterating list!"); TASSERT((*itr1) == i, "Iterator operator * does not return correct value when iterating list!"); TASSERT(itr1 == list1.At(i), "At() returns incorrect iterator when forward iterating!"); } //Should be at end TASSERT(list1.End() == itr1, "Iterator should be at end after forward iteration but == End() returns false!"); TASSERT(itr1.HasNext() == false, "Iterator HasNext() should return false at End() but returns true!"); TASSERT(itr1.HasPrev() == true, "Iterator HasPrev() should return true at End() but returns false!"); TASSERT(itr1.HasCurrent() == false, "Iterator HasCurrent() should return false at End() but returns true!"); for (i = 4; i >= 0; i--) { itr1--; TASSERT(itr1.Get() == i, "Iterator Get() does not return correct value when reverse iterating list!"); TASSERT((*itr1) == i, "Iterator operator * does not return correct value when reverse iterating list!"); TASSERT(itr1 == list1.At(i), "At() returns incorrect iterator when reverse iterating!"); } //Should be at the beginning now TASSERT(itr1 == list1.Begin(), "Iterator should be at start after reverse iteration but == Begin() returns false!"); for (i = 0; i < 5; i++) { itr1 = list1.At(i); TASSERT((*itr1) == i, "Iterator operator * returns incorrect value after iterator assignment!"); } return ZTEST_SUCCESS; } /*************************************************************************/ //Allocator that counts current number of node allocations template class ZListTestAllocator : public ZListAllocator { public: //Current number of allocated nodes int Count; ZListTestAllocator() : Count(0) { } ZListNode* Allocate() { Count++; return new (std::nothrow) ZListNode(); } void Deallocate( ZListNode* _node ) { Count--; delete _node; } }; static const char* test_Allocator_Front_Back_Clear() { ZList > list1; ZList::Iterator itr; for (int i = 0; i < 5; i++) { list1.PushBack(i); TASSERT(list1.Allocator().Count == i + 1, "Allocator() returns incorrect count for number of allocated nodes!"); } TASSERT(list1.Front() == 0, "Front() returns incorrect value!"); TASSERT(list1.Back() == 4, "Back() returns incorrect value!"); list1.Clear(); TASSERT(list1.Empty(), "Empty() returns false after call to Clear()!"); TASSERT(list1.Allocator().Count == 0, "Clear() failed to deallocate nodes!");; for (int i = 0; i < 5; i++) list1.PushBack(i); itr = list1.At(2); list1.Clear(itr); TASSERT(list1.Size() == 2, "Size() returns incorrect value after call to Clear()!"); itr = list1.End(); list1.Clear(itr); TASSERT(list1.Size() == 2, "Size() returns incorrect value after call to Clear(End())!"); return ZTEST_SUCCESS; } /*************************************************************************/ static const char* test_Copy_Equals() { ZList > list1; ZList > list2; ZList::Iterator itr; TASSERT(list1.Equals(list2) == true, "Equals() returns false when empty list is compared to empty list!"); for (int i = 0; i < 5; i++) list1.PushBack(i); TASSERT(list1.Equals(list2) == false, "Equals() returns true when empty list is compared to non-empty list!"); list2.Copy(list1); TASSERT(list1.Size() == list2.Size(), "Size() of list1 does not equal Size() of list2 after Copy!"); TASSERT(list1.Equals(list2) == true, "Equals(list1, list2) returns false after Copy!"); TASSERT(list2.Equals(list1) == true, "Equals(list2, list1) returns false after Copy!"); itr = list2.At(3); list2.Clear(itr); TASSERT(list1.Equals(list2) == false, "Equals(list1, list2) returns true after Clear()!"); TASSERT(list2.Equals(list1) == false, "Equals(list2, list1) returns true after Clear()!"); ZList > list3(list2.Begin(), list2.End()); ZList > list4(list2.Begin(), --itr); TASSERT(list3.Back() == 2, "Back() returns incorrect value on list3 after sub-list constructor!"); TASSERT(list4.Back() == 1, "Back() returns incorrect value on list4 after sub-list constructor!"); TASSERT(list3.Equals(list4) == false, "Equals(list3, list4) returns true after sub-list constructor!"); return ZTEST_SUCCESS; } /*************************************************************************/ static const char* test_PushFront_PopBack_PopFront() { int i; ZList > list1; for (i = 0; i < 5; i++) { list1.PushBack(i); TASSERT(list1.Allocator().Count == i + 1, "Allocator() returns incorrect count for number of allocated nodes after PushBack()!"); TASSERT(list1.Back() == i, "Back() returns incorrect value after PushBack()!"); } TASSERT(list1.Size() == 5, "Size() returns incorrect value after after PushBack()!"); for (i = 5; i > 0; i--) { int j = list1.PopBack(); TASSERT(j == i - 1, "PopBack() returns incorrect value!"); TASSERT(list1.Allocator().Count == i - 1, "Allocator() returns incorrect count for number of allocated nodes after PopBack()!"); TASSERT(list1.Size() == (size_t)(i - 1), "Size() returns incorrect value after PopBack()!"); } list1.Clear(); for (i = 0; i < 5; i++) { list1.PushFront(i); TASSERT(list1.Allocator().Count == i + 1, "Allocator() returns incorrect count for number of allocated nodes!"); TASSERT(list1.Front() == i, "Front() returns wrong value after calls to PushFront()!"); } TASSERT(list1.Size() == 5, "Size() returns incorrect value after after PushFront()!"); for (i = 5; i > 0; i--) { int j = list1.PopFront(); TASSERT(j == i - 1, "PopFront() returns incorrect value!"); TASSERT(list1.Allocator().Count == i - 1, "Allocator() returns incorrect count for number of allocated nodes!"); TASSERT(list1.Size() == (size_t)(i - 1), "Size() returns incorrect value after PopFront()!"); } return ZTEST_SUCCESS; } /*************************************************************************/ static const char* test_Insert_Erase() { ZList > list1; ZList > list2; ZList::Iterator itr1; ZList::Iterator itr2; for (int i = 0; i < 5; i++) list1.PushBack(i); itr1 = list1.Begin(); list1.Insert(itr1, 10); TASSERT((*itr1) == 0, "Iterator operator * returns incorrect value after Insert()!"); TASSERT(list1.Begin().Get() == 10, "Iterator Get() returns incorrect value after Insert()!"); TASSERT(list1.Size() == 6, "Size() returns incorrect value after Insert()!") itr2 = list1.End(); list1.Insert(itr2, 20); TASSERT(list1.Back() == 20, "Back() returns incorrect value after Insert()!"); TASSERT(itr2 == list1.End(), "Iterator does not equal End after Insert()!"); TASSERT(list1.Size() == 7, "Size() returns incorrect value after Insert(End())!"); itr1 = list1.Begin(); int j = list1.Erase(itr1); TASSERT(j == 10, "Erase(itr1) returns incorrect value!"); TASSERT(list1.Front() == 0, "Front() returns incorrect value after Erase()!"); TASSERT(list1.Size() == 6, "Size() returns incorrect value after Erase(Begin())!"); itr2 = list1.End() - 1; j = list1.Erase(itr2); TASSERT(j == 20, "Erase(itr2) returns incorrect value!"); TASSERT(list1.Back() == 4, "Back() returns incorrect value after Erase()!"); TASSERT(list1.Size() == 5, "Size() returns incorrect value after Erase(End() - 1))!"); itr1 = list1.Begin(); itr2 = list1.At(2); //0, 1, 2 list2.Insert(list2.Begin(), itr1, itr2); TASSERT(list2.Front() == 0 && list2.Back() == 1, "Front() and Back() do not return correct values after Insert(Begin(), itr1, itr2)!"); itr1 = list2.Begin(); itr2 = list2.End(); list1.Insert(list1.At(2), itr1, itr2); TASSERT(list1.Size() == 7, "Size() returns incorrect value after Insert(At(2), itr1, itr2)!"); TASSERT(list1.Front() == 0, "Front() returns incorrect value after Insert(At(2), itr1, itr2)!"); TASSERT(list1.Back() == 4, "Back() returns incorrect value after Insert(At(2), itr1, itr2)"); TASSERT(*list1.At(2) == 0, "At(2) dereference contains invalid value after Insert(At(2), itr1, itr2)!"); TASSERT(*list1.At(3) == 1, "At(3) dereference contains invalid value after Insert(At(2), itr1, itr2)!"); itr1 = list1.At(2); itr2 = list1.At(4); list1.Erase(itr1, itr2); TASSERT(list1.Size() == 5, "Size() returns incorrect value after Erase(itr1, itr2)!"); itr1 = list1.Begin(); for (int i = 0; itr1 != list1.End(); itr1++, i++) { TASSERT((*itr1) == i, "Iterator operator * returns incorrect value after Erase(itr1, itr2)!"); } return ZTEST_SUCCESS; } /*************************************************************************/ static const char* test_Swap_Splice_SwapNodes() { int i; ZList list1; ZList list2; ZList::Iterator itr1; ZList::Iterator itr2; for (int i = 0; i < 5; i++) list1.PushBack(i); for (int i = 5; i < 10; i++) list2.PushBack(i); list1.Swap(list2); for (i = 5, itr1 = list1.Begin(); itr1 != list1.End(); i++, itr1++) { TASSERT((*itr1) == i, "Iterator operator * returns incorrect value on list1 after Swap()!"); } for (i = 0, itr2 = list2.Begin(); itr2 != list2.End(); i++, itr2++) { TASSERT((*itr2) == i, "Iterator operator * returns incorrect value on list2 after Swap()!"); } itr1 = list1.Begin(); itr2 = list1.End(); list2.Splice(list2.End(), list1, itr1, itr2); TASSERT(list2.Size() == 10, "Size() returns incorrect value after Splice()!"); TASSERT(list1.Empty(), "Empty() returns false after Splice()!"); for (i = 0, itr2 = list2.Begin(); itr2 != list2.End(); i++, itr2++) { TASSERT((*itr2) == i, "Iterator operator * returns incorrect value on list2 after Splice()!"); } itr1 = list2.At(3); itr2 = list2.At(6); list1.Splice(list1.Begin(), list2, itr1, itr2); TASSERT(list2.Size() == 7, "Size() returns incorrect value for list2 after Splice(At(3), At(6))!"); TASSERT(list1.Size() == 3, "Size() returns incorrect value for list1 after Splice(At(3), At(6))!"); for (i = 3, itr1 = list1.Begin(); itr1 != list1.End(); i++, itr1++) { TASSERT((*itr1) == i, "Iterator operator * returns incorrect value on list1 after Splice()!"); } list1.SwapNodes(list1.Begin(), list1.End() - 1); TASSERT(list1.Front() == 5, "Front() returns invalid value after call to SwapNodes()!"); TASSERT(list1.Back() == 3, "Back() returns invalid value after call to SwapNodes()!"); return ZTEST_SUCCESS; }