Files
libsst/ZTestSuite/Test-ZList.cpp
2026-04-03 00:22:39 -05:00

417 lines
13 KiB
C++

#include "ZUnitTest.hpp"
#include <ZSTL/ZList.hpp>
#include <ZSTL/ZListAlgo.hpp>
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<int> 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<int> list1;
ZList<int>::Iterator itr1;
ZListIterator<int> 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 <typename T>
class ZListTestAllocator : public ZListAllocator<T>
{
public:
//Current number of allocated nodes
int Count;
ZListTestAllocator() : Count(0) { }
ZListNode<T>* Allocate()
{
Count++;
return new (std::nothrow) ZListNode<T>();
}
void Deallocate( ZListNode<T>* _node )
{
Count--;
delete _node;
}
};
static const char* test_Allocator_Front_Back_Clear()
{
ZList<int, ZListTestAllocator<int> > list1;
ZList<int>::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<int, ZListTestAllocator<int> > list1;
ZList<int, ZListTestAllocator<int> > list2;
ZList<int>::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<int, ZListTestAllocator<int> > list3(list2.Begin(), list2.End());
ZList<int, ZListTestAllocator<int> > 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<int, ZListTestAllocator<int> > 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<int, ZListTestAllocator<int> > list1;
ZList<int, ZListTestAllocator<int> > list2;
ZList<int>::Iterator itr1;
ZList<int>::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<int> list1;
ZList<int> list2;
ZList<int>::Iterator itr1;
ZList<int>::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;
}