MobinMQL/Scripts/UnitTests/Generic/TestLinkedList.mq5

1992 lines
59 KiB
MQL5
Raw Permalink Normal View History

2025-07-22 14:48:34 +03:00
//+------------------------------------------------------------------+
//| TestLinkedList.mq5 |
//| Copyright 2000-2025, MetaQuotes Ltd. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#include <Generic\LinkedList.mqh>
#include <Generic\ArrayList.mqh>
//+------------------------------------------------------------------+
//| TestAddAfter_Node. |
//+------------------------------------------------------------------+
bool TestAddAfter_Node(const int count)
{
CLinkedList<int>list_test();
//--- create test arrays
int check_array[];
int temp_items[];
int head_items[];
int head_reverse_items[];
int tail_items[];
ArrayResize(temp_items,count);
ArrayResize(head_items,count);
ArrayResize(head_reverse_items,count);
ArrayResize(tail_items,count);
for(int i=0; i<count; i++)
{
int index=count-1-i;
int head = MathRand();
int tail = MathRand();
head_items[i]=head;
head_reverse_items[index]=head;
tail_items[i]=tail;
}
//--- test verify value is -1
//--- add values
CLinkedListNode<int>*node=list_test.AddFirst(head_items[0]);
list_test.AddAfter(node,-1);
//--- check
list_test.CopyTo(check_array);
if(check_array[0]!=head_items[0] && check_array[1]!=-1)
return(false);
//--- clear
list_test.Clear();
//--- test node in the head
//--- add values
list_test.AddFirst(head_items[0]);
ArrayCopy(temp_items,head_items);
ArrayReverse(temp_items,1,count-1);
for(int i=1; i<count; i++)
list_test.AddAfter(list_test.First(),head_items[i]);
//--- check
list_test.CopyTo(check_array);
if(ArrayCompare(check_array,temp_items)!=0)
return(false);
//--- clear
list_test.Clear();
//--- test node in the tail
//--- add values
list_test.AddFirst(head_items[0]);
for(int i=1; i<count;++i)
list_test.AddAfter(list_test.Last(),head_items[i]);
//--- check
list_test.CopyTo(check_array);
if(ArrayCompare(check_array,head_items)!=0)
return(false);
//--- clear
list_test.Clear();
//--- test node is after the head
//--- add values
list_test.AddFirst(head_items[0]);
list_test.AddLast(head_items[1]);
ArrayCopy(temp_items,head_items);
ArrayReverse(temp_items,2,count-2);
for(int i=2; i<count;++i)
list_test.AddAfter(list_test.First().Next(),head_items[i]);
//--- check
list_test.CopyTo(check_array);
if(ArrayCompare(check_array,temp_items)!=0)
return(false);
//--- clear
list_test.Clear();
//--- test node is before the tail
//--- add values
list_test.AddFirst(head_items[0]);
list_test.AddLast(head_items[1]);
ArrayCopy(temp_items,head_items,1,2,count-2);
temp_items[0]=head_items[0];
temp_items[count-1]=head_items[1];
for(int i=2; i<count;++i)
list_test.AddAfter(list_test.Last().Previous(),head_items[i]);
//--- check
list_test.CopyTo(check_array);
if(ArrayCompare(check_array,temp_items)!=0)
return(false);
//--- clear
list_test.Clear();
//--- test node is somewhere in the middle
//--- add values
list_test.AddFirst(head_items[0]);
list_test.AddLast(head_items[1]);
list_test.AddLast(head_items[2]);
ArrayCopy(temp_items,head_items,1,3,count-3);
temp_items[0]=head_items[0];
temp_items[count - 2] = head_items[1];
temp_items[count - 1] = head_items[2];
for(int i=3; i<count;++i)
list_test.AddAfter(list_test.Last().Previous().Previous(),head_items[i]);
//--- check
list_test.CopyTo(check_array);
if(ArrayCompare(check_array,temp_items)!=0)
return(false);
//--- clear
list_test.Clear();
//--- test call AddAfter several times remove some of the items
//--- add values
list_test.AddFirst(head_items[0]);
for(int i=1; i<count;++i)
list_test.AddAfter(list_test.Last(),head_items[i]);
//--- remove values
list_test.Remove(head_items[2]);
list_test.Remove(head_items[count-3]);
list_test.Remove(head_items[1]);
list_test.Remove(head_items[count-2]);
list_test.RemoveFirst();
list_test.RemoveLast();
//--- with the above remove we should have removed the first and last 3 items
ArrayFree(temp_items);
ArrayCopy(temp_items,head_items,0,3,count-6);
//--- check
ArrayFree(check_array);
list_test.CopyTo(check_array);
if(ArrayCompare(check_array,temp_items)!=0)
return(false);
//--- add values
for(int i=0; i<count;++i)
list_test.AddAfter(list_test.Last(),tail_items[i]);
int temp_items2[];
ArrayCopy(temp_items2,temp_items);
ArrayCopy(temp_items2,tail_items,ArraySize(temp_items));
//--- check
list_test.CopyTo(check_array);
if(ArrayCompare(check_array,temp_items2)!=0)
return(false);
//--- clear
list_test.Clear();
//--- test call AddAfter several times remove all of the items
//--- add values
list_test.AddFirst(head_items[0]);
for(int i=1; i<count;++i)
list_test.AddAfter(list_test.Last(),head_items[i]);
//--- remove values
for(int i=0; i<count;++i)
list_test.RemoveFirst();
//--- add values
list_test.AddFirst(tail_items[0]);
for(int i=1; i<count;++i)
list_test.AddAfter(list_test.Last(),tail_items[i]);
//--- check
ArrayFree(check_array);
list_test.CopyTo(check_array);
if(ArrayCompare(check_array,tail_items)!=0)
return(false);
//--- clear
list_test.Clear();
//--- test call AddAfter several times then call Clear
//--- add values
list_test.AddFirst(head_items[0]);
for(int i=1; i<count;++i)
list_test.AddAfter(list_test.Last(),head_items[i]);
//--- clear
list_test.Clear();
//--- add values
list_test.AddFirst(tail_items[0]);
for(int i=1; i<count;++i)
list_test.AddAfter(list_test.Last(),tail_items[i]);
//--- check
list_test.CopyTo(check_array);
if(ArrayCompare(check_array,tail_items)!=0)
return(false);
//--- clear
list_test.Clear();
//--- test mix AddBefore and AddAfter calls
//--- add values
list_test.AddLast(head_items[0]);
list_test.AddLast(tail_items[0]);
for(int i=1; i<count;++i)
{
list_test.AddBefore(list_test.First(), head_items[i]);
list_test.AddAfter(list_test.Last(), tail_items[i]);
}
ArrayFree(temp_items);
ArrayCopy(temp_items,head_reverse_items);
ArrayCopy(temp_items,tail_items,count);
//--- check
list_test.CopyTo(check_array);
if(ArrayCompare(check_array,temp_items)!=0)
return(false);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| TestAddAfter_Node_Negative. |
//+------------------------------------------------------------------+
bool TestAddAfter_Node_Negative(const int count)
{
//--- create lists
CLinkedList<int>list_test();
CLinkedList<int>list_temp();
//--- test verify null node
//--- check
if(list_test.AddAfter(NULL,0)!=NULL)
return(false);
if(list_test.Count()!=0)
return(false);
//--- test verify Node that is a new Node
//--- add values
list_test.AddLast(0);
CLinkedListNode<int>node(1);
//--- check
if(list_test.AddAfter(GetPointer(node),-1)!=NULL)
return(false);
if(list_test.Count()!=1)
return(false);
//--- clear
list_test.Clear();
//--- test verify Node that already exists in another collection
//--- add values
list_test.AddLast(MathRand());
list_test.AddLast(MathRand());
list_temp.AddLast(MathRand());
list_temp.AddLast(MathRand());
//--- check
if(list_test.AddAfter(list_temp.Last(),MathRand())!=NULL)
return(false);
if(list_test.Count()!=2)
return(false);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| TestAddAfter. |
//+------------------------------------------------------------------+
bool TestAddAfter(const string test_name)
{
PrintFormat("%s started",test_name);
//--- test 1
PrintFormat("%s: Test 1: Complex validation of AddAfter method for head node, tail node, some node in the middle, "+
"also testing after remove several element, remove all element and cleaning of list.",test_name);
if(!TestAddAfter_Node(16))
return(false);
//--- test 2
PrintFormat("%s: Test 2: Validation of AddAfter method for incorrect node.",test_name);
if(!TestAddAfter_Node_Negative(16))
return(false);
//--- successful
PrintFormat("%s passed",test_name);
return(true);
}
//+------------------------------------------------------------------+
//| TestAddBefore_Node. |
//+------------------------------------------------------------------+
bool TestAddBefore_Node(const int count)
{
CLinkedList<int>list_test();
//--- create test arrays
int check_array[];
int temp_items[];
int head_items[];
int head_reverse_items[];
int tail_items[];
int tail_reverse_items[];
ArrayResize(temp_items,count);
ArrayResize(head_items,count);
ArrayResize(head_reverse_items,count);
ArrayResize(tail_items,count);
ArrayResize(tail_reverse_items,count);
for(int i=0; i<count; i++)
{
int index=count-1-i;
int head = MathRand();
int tail = MathRand();
head_items[i]=head;
head_reverse_items[index]=head;
tail_items[i]=tail;
tail_reverse_items[index]=tail;
}
//--- test verify value is -1
//--- add values
list_test.AddFirst(head_items[0]);
list_test.AddBefore(list_test.First(), -1);
//--- check
list_test.CopyTo(check_array);
if(check_array[0]!=-1 && check_array[1]!=head_items[0])
return(false);
//--- clear
list_test.Clear();
//--- test node is the head
list_test.AddFirst(head_items[0]);
for(int i=1; i<count;++i)
list_test.AddBefore(list_test.First(),head_items[i]);
//--- check
list_test.CopyTo(check_array);
if(ArrayCompare(check_array,head_reverse_items)!=0)
return(false);
//--- clear
list_test.Clear();
//--- test node is the tail
list_test.AddFirst(head_items[0]);
ArrayCopy(temp_items,head_items,0,1,count);
temp_items[count-1]=head_items[0];
for(int i=1; i<count;++i)
list_test.AddBefore(list_test.Last(),head_items[i]);
//--- check
list_test.CopyTo(check_array);
if(ArrayCompare(check_array,temp_items)!=0)
return(false);
//--- clear
list_test.Clear();
//--- test node is after the head
//--- add values
list_test.AddFirst(head_items[0]);
list_test.AddLast(head_items[1]);
ArrayFree(temp_items);
ArrayCopy(temp_items,head_items);
ArrayReverse(temp_items,1,count-1);
for(int i=2; i<count;++i)
list_test.AddBefore(list_test.First().Next(),head_items[i]);
//--- check
list_test.CopyTo(check_array);
if(ArrayCompare(check_array,temp_items)!=0)
return(false);
//--- clear
list_test.Clear();
//--- test node is before the tail
//--- add values
list_test.AddFirst(head_items[0]);
list_test.AddLast(head_items[1]);
ArrayResize(temp_items,count);
ArrayCopy(temp_items,head_items,0,2,count-2);
temp_items[count-2] = head_items[0];
temp_items[count-1] = head_items[1];
for(int i=2; i<count;++i)
list_test.AddBefore(list_test.Last().Previous(),head_items[i]);
//--- check
list_test.CopyTo(check_array);
if(ArrayCompare(check_array,temp_items)!=0)
return(false);
//--- clear
list_test.Clear();
//--- test node is somewhere in the middle
//--- add values
list_test.AddFirst(head_items[0]);
list_test.AddLast(head_items[1]);
list_test.AddLast(head_items[2]);
ArrayResize(temp_items,count);
ArrayCopy(temp_items,head_items,0,3,count-3);
temp_items[count-3] = head_items[0];
temp_items[count-2] = head_items[1];
temp_items[count-1] = head_items[2];
for(int i=3; i<count;++i)
list_test.AddBefore(list_test.Last().Previous().Previous(),head_items[i]);
//--- check
list_test.CopyTo(check_array);
if(ArrayCompare(check_array,temp_items)!=0)
return(false);
//--- clear
list_test.Clear();
//--- test call AddBefore several times remove some of the items
//--- add values
list_test.AddFirst(head_items[0]);
for(int i=1; i<count;++i)
list_test.AddBefore(list_test.First(),head_items[i]);
//--- remove values
list_test.Remove(head_items[2]);
list_test.Remove(head_items[count - 3]);
list_test.Remove(head_items[1]);
list_test.Remove(head_items[count - 2]);
list_test.RemoveFirst();
list_test.RemoveLast();
//--- with the above remove we should have removed the first and last 3 items
ArrayResize(temp_items,count-6);
ArrayCopy(temp_items,head_reverse_items,0,3,count-6);
//--- check
ArrayFree(check_array);
list_test.CopyTo(check_array);
if(ArrayCompare(check_array,temp_items)!=0)
return(false);
//--- add values
for(int i=0; i<count;++i)
list_test.AddBefore(list_test.First(),tail_items[i]);
int temp_items2[];
ArrayCopy(temp_items2,tail_reverse_items);
ArrayCopy(temp_items2,temp_items,count);
//--- check
list_test.CopyTo(check_array);
if(ArrayCompare(check_array,temp_items2)!=0)
return(false);
//--- clear
list_test.Clear();
//--- test call AddBefore several times remove all of the items
//--- add values
list_test.AddFirst(head_items[0]);
for(int i=1; i<count;++i)
list_test.AddBefore(list_test.First(),head_items[i]);
//--- remove values
for(int i=0; i<count;++i)
list_test.RemoveFirst();
//--- add values
list_test.AddFirst(tail_items[0]);
for(int i=1; i<count;++i)
list_test.AddBefore(list_test.First(),tail_items[i]);
//--- check
ArrayFree(check_array);
list_test.CopyTo(check_array);
if(ArrayCompare(check_array,tail_reverse_items)!=0)
return(false);
//--- clear
list_test.Clear();
//--- test call AddBefore several times then call Clear
//--- add values
list_test.AddFirst(head_items[0]);
for(int i=1; i<count;++i)
list_test.AddBefore(list_test.First(),head_items[i]);
//--- clear
list_test.Clear();
//--- add values
list_test.AddFirst(tail_items[0]);
for(int i=1; i<count;++i)
list_test.AddBefore(list_test.First(),tail_items[i]);
//--- check
list_test.CopyTo(check_array);
if(ArrayCompare(check_array,tail_reverse_items)!=0)
return(false);
//--- clear
list_test.Clear();
//--- test mix AddBefore and AddAfter calls
list_test.AddLast(head_items[0]);
list_test.AddLast(tail_items[0]);
for(int i=1; i<count;++i)
{
list_test.AddBefore(list_test.First(), head_items[i]);
list_test.AddAfter(list_test.Last(), tail_items[i]);
}
ArrayResize(temp_items,count*2);
ArrayCopy(temp_items,head_reverse_items);
ArrayCopy(temp_items,tail_items,count);
//--- check
list_test.CopyTo(check_array);
if(ArrayCompare(check_array,temp_items)!=0)
return(false);
//--- clear
list_test.Clear();
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| TestAddBefore_Node_Negative. |
//+------------------------------------------------------------------+
bool TestAddBefore_Node_Negative(const int count)
{
//--- create lists
CLinkedList<int>list_test();
CLinkedList<int>list_temp();
//--- test verify null node
//--- check
if(list_test.AddBefore(NULL,0)!=NULL)
return(false);
if(list_test.Count()!=0)
return(false);
//--- test verify Node that is a new Node
//--- add values
list_test.AddLast(0);
CLinkedListNode<int>node(1);
//--- check
if(list_test.AddBefore(GetPointer(node),-1)!=NULL)
return(false);
if(list_test.Count()!=1)
return(false);
//--- clear
list_test.Clear();
//--- test verify Node that already exists in another collection
//--- add values
list_test.AddLast(MathRand());
list_test.AddLast(MathRand());
list_temp.AddLast(MathRand());
list_temp.AddLast(MathRand());
//--- check
if(list_test.AddBefore(list_temp.Last(),MathRand())!=NULL)
return(false);
if(list_test.Count()!=2)
return(false);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| TestAddBefore. |
//+------------------------------------------------------------------+
bool TestAddBefore(const string test_name)
{
PrintFormat("%s started",test_name);
//--- test 1
PrintFormat("%s: Test 1: Complex validation of AddBefore method for head node, tail node, some node in the middle, "+
"also testing after remove several element, remove all element and cleaning of list.",test_name);
if(!TestAddBefore_Node(16))
return(false);
//--- test 2
PrintFormat("%s: Test 2: Validation of AddBefore method for incorrect node.",test_name);
if(!TestAddBefore_Node_Negative(16))
return(false);
//--- successful
PrintFormat("%s passed",test_name);
return(true);
}
//+------------------------------------------------------------------+
//| TestAddFirst_Node. |
//+------------------------------------------------------------------+
bool TestAddFirst_Node(const int count)
{
CLinkedList<int>list_test();
//--- create test arrays
int check_array[];
int temp_items[];
int head_items[];
int head_reverse_items[];
int tail_items[];
int tail_reverse_items[];
ArrayResize(temp_items,count);
ArrayResize(head_items,count);
ArrayResize(head_reverse_items,count);
ArrayResize(tail_items,count);
ArrayResize(tail_reverse_items,count);
for(int i=0; i<count; i++)
{
int index=count-1-i;
int head = MathRand();
int tail = MathRand();
head_items[i]=head;
head_reverse_items[index]=head;
tail_items[i]=tail;
tail_reverse_items[index]=tail;
}
//--- test verify value is -1
//--- add values
list_test.AddFirst(-1);
//--- check
list_test.CopyTo(check_array);
if(check_array[0]!=-1)
return(false);
//--- clear
list_test.Clear();
//--- test call AddHead several times
//--- add values
for(int i=0; i<count;++i)
list_test.AddFirst(head_items[i]);
//--- check
list_test.CopyTo(check_array);
if(ArrayCompare(check_array,head_reverse_items)!=0)
return(false);
//--- clear
list_test.Clear();
//--- test call AddHead several times remove some of the items
//--- add values
for(int i=0; i<count;++i)
list_test.AddFirst(head_items[i]);
//--- remove values
list_test.Remove(head_items[2]);
list_test.Remove(head_items[count-3]);
list_test.Remove(head_items[1]);
list_test.Remove(head_items[count-2]);
list_test.RemoveFirst();
list_test.RemoveLast();
//--- with the above remove we should have removed the first and last 3 items
//--- expected items are head_items in reverse order, or a subset of them.
ArrayResize(temp_items,count-6);
ArrayCopy(temp_items,head_reverse_items,0,3,count-6);
//--- check
ArrayFree(check_array);
list_test.CopyTo(check_array);
if(ArrayCompare(check_array,temp_items)!=0)
return(false);
//--- add values
for(int i=0; i<count;++i)
list_test.AddFirst(tail_items[i]);
int temp_items2[];
ArrayCopy(temp_items2,tail_reverse_items);
ArrayCopy(temp_items2,temp_items,count);
//--- check
list_test.CopyTo(check_array);
if(ArrayCompare(check_array,temp_items2)!=0)
return(false);
//--- clear
list_test.Clear();
//--- test call AddHead several times remove all of the items
//--- add values
for(int i=0; i<count;++i)
list_test.AddFirst(head_items[i]);
//--- remove values
for(int i=0; i<count;++i)
list_test.RemoveFirst();
//--- add values
for(int i=0; i<count;++i)
list_test.AddFirst(tail_items[i]);
//--- check
ArrayFree(check_array);
list_test.CopyTo(check_array);
if(ArrayCompare(check_array,tail_reverse_items)!=0)
return(false);
//--- clear
list_test.Clear();
//--- test call AddHead several times then call Clear
//--- add vlues
for(int i=0; i<count;++i)
list_test.AddFirst(head_items[i]);
//--- clear
list_test.Clear();
//--- add values
for(int i=0; i<count;++i)
list_test.AddFirst(tail_items[i]);
//--- check
list_test.CopyTo(check_array);
if(ArrayCompare(check_array,tail_reverse_items)!=0)
return(false);
//--- clear
list_test.Clear();
//--- test mix AddHead and AddTail calls
//--- add values
for(int i=0; i<count;++i)
{
list_test.AddFirst(head_items[i]);
list_test.AddLast(tail_items[i]);
}
ArrayResize(temp_items,count*2);
ArrayCopy(temp_items,head_reverse_items);
ArrayCopy(temp_items,tail_items,count);
//--- check
list_test.CopyTo(check_array);
if(ArrayCompare(check_array,temp_items)!=0)
return(false);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| TestAddFirst_Node_Negative. |
//+------------------------------------------------------------------+
bool TestAddFirst_Node_Negative(const int count)
{
//--- create lists
CLinkedList<int>list_test();
CLinkedList<int>list_temp();
//--- test verify null node
//--- check
if(list_test.AddFirst((CLinkedListNode<int>*)NULL)==true)
return(false);
if(list_test.Count()!=0)
return(false);
//--- test verify Node that is a new Node
//--- add values
list_test.AddLast(0);
CLinkedListNode<int>node(1);
//--- check
if(list_test.AddFirst(list_test.First())==true)
return(false);
if(list_test.Count()!=1)
return(false);
//--- clear
list_test.Clear();
//--- test verify Node that already exists in another collection
//--- add values
list_test.AddLast(MathRand());
list_test.AddLast(MathRand());
//--- check
if(list_test.AddFirst(list_test.Last())==true)
return(false);
if(list_test.Count()!=2)
return(false);
//--- clear
list_test.Clear();
//--- test verify Node that already exists in another collection
//--- add values
list_test.AddLast(MathRand());
list_test.AddLast(MathRand());
list_temp.AddLast(MathRand());
list_temp.AddLast(MathRand());
//--- check
if(list_test.AddFirst(list_temp.Last())==true)
return(false);
if(list_test.Count()!=2)
return(false);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| TestAddFirst. |
//+------------------------------------------------------------------+
bool TestAddFirst(const string test_name)
{
PrintFormat("%s started",test_name);
//--- test 1
PrintFormat("%s: Test 1: Complex validation of AddFirst method after remove several element, remove all, several calling method of clearing.",test_name);
if(!TestAddFirst_Node(16))
return(false);
//--- test 2
PrintFormat("%s: Test 2: Validation of AddFirst method for incorrect node.",test_name);
if(!TestAddFirst_Node_Negative(16))
return(false);
//--- successful
PrintFormat("%s passed",test_name);
return(true);
}
//+------------------------------------------------------------------+
//| TestAddLast_Node. |
//+------------------------------------------------------------------+
bool TestAddLast_Node(const int count)
{
CLinkedList<int>list_test();
//--- create test arrays
int check_array[];
int temp_items[];
int head_items[];
int head_reverse_items[];
int tail_items[];
int tail_reverse_items[];
ArrayResize(temp_items,count);
ArrayResize(head_items,count);
ArrayResize(head_reverse_items,count);
ArrayResize(tail_items,count);
ArrayResize(tail_reverse_items,count);
for(int i=0; i<count; i++)
{
int index=count-1-i;
int head = MathRand();
int tail = MathRand();
head_items[i]=head;
head_reverse_items[index]=head;
tail_items[i]=tail;
tail_reverse_items[index]=tail;
}
//--- test verify value is -1
//--- add values
list_test.AddLast(-1);
//--- check
list_test.CopyTo(check_array);
if(check_array[0]!=-1)
return(false);
//--- clear
list_test.Clear();
//--- test call AddTail several times
//--- add values
for(int i=0; i<count;++i)
list_test.AddLast(tail_items[i]);
//--- check
list_test.CopyTo(check_array);
if(ArrayCompare(check_array,tail_items)!=0)
return(false);
//--- clear
list_test.Clear();
//--- test call AddTail several times remove some of the items
//--- add values
for(int i=0; i<count;++i)
list_test.AddLast(tail_items[i]);
//--- remove values
list_test.Remove(tail_items[2]);
list_test.Remove(tail_items[count - 3]);
list_test.Remove(tail_items[1]);
list_test.Remove(tail_items[count - 2]);
list_test.RemoveFirst();
list_test.RemoveLast();
//--- with the above remove we should have removed the first and last 3 items
ArrayResize(temp_items,count-6);
ArrayCopy(temp_items,tail_items,0,3,count-6);
//--- check
ArrayFree(check_array);
list_test.CopyTo(check_array);
if(ArrayCompare(check_array,temp_items)!=0)
return(false);
//--- adding some more items to the tail of the linked list
for(int i=0; i<count;++i)
list_test.AddLast(head_items[i]);
int temp_items2[];
ArrayCopy(temp_items2,temp_items);
ArrayCopy(temp_items2,head_items,ArraySize(temp_items));
//--- check
list_test.CopyTo(check_array);
if(ArrayCompare(check_array,temp_items2)!=0)
return(false);
//--- clear
list_test.Clear();
//--- test call AddTail several times then call Clear
//--- add values
for(int i=0; i<count;++i)
list_test.AddLast(tail_items[i]);
//--- clear
list_test.Clear();
//--- add values
for(int i=0; i<count;++i)
list_test.AddLast(head_items[i]);
//--- check
ArrayFree(check_array);
list_test.CopyTo(check_array);
if(ArrayCompare(check_array,head_items)!=0)
return(false);
//--- clear
list_test.Clear();
//--- test mix AddTail and AddTail calls
for(int i=0; i<count;++i)
{
list_test.AddFirst(head_items[i]);
list_test.AddLast(tail_items[i]);
}
ArrayResize(temp_items,count);
//--- adding the head_items in reverse order.
for(int i=0; i<count; i++)
{
int index=count-1-i;
temp_items[i]=head_items[index];
}
ArrayCopy(temp_items2,temp_items);
ArrayCopy(temp_items2,tail_items,count);
//--- check
list_test.CopyTo(check_array);
if(ArrayCompare(check_array,temp_items2)!=0)
return(false);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| TestAddLast_Node_Negative. |
//+------------------------------------------------------------------+
bool TestAddLast_Node_Negative(const int count)
{
//--- create lists
CLinkedList<int>list_test();
CLinkedList<int>list_temp();
//--- test verify null node
//--- check
if(list_test.AddLast((CLinkedListNode<int>*)NULL)==true)
return(false);
if(list_test.Count()!=0)
return(false);
//--- test verify Node that is a new Node
//--- add values
list_test.AddLast(0);
CLinkedListNode<int>node(1);
//--- check
if(list_test.AddLast(list_test.First())==true)
return(false);
if(list_test.Count()!=1)
return(false);
//--- clear
list_test.Clear();
//--- test verify Node that already exists in another collection
//--- add values
list_test.AddLast(MathRand());
list_test.AddLast(MathRand());
//--- check
if(list_test.AddLast(list_test.Last())==true)
return(false);
if(list_test.Count()!=2)
return(false);
//--- clear
list_test.Clear();
//--- test verify Node that already exists in another collection
//--- add values
list_test.AddLast(MathRand());
list_test.AddLast(MathRand());
list_temp.AddLast(MathRand());
list_temp.AddLast(MathRand());
//--- check
if(list_test.AddLast(list_temp.Last())==true)
return(false);
if(list_test.Count()!=2)
return(false);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| TestAddLast. |
//+------------------------------------------------------------------+
bool TestAddLast(const string test_name)
{
PrintFormat("%s started",test_name);
//--- test 1
PrintFormat("%s: Test 1: Complex validation of AddLast method after remove several element, remove all, several calling method of clearing.",test_name);
if(!TestAddLast_Node(16))
return(false);
//--- test 2
PrintFormat("%s: Test 2: Validation of AddLast method for incorrect node.",test_name);
if(!TestAddLast_Node_Negative(16))
return(false);
//--- successful
PrintFormat("%s passed",test_name);
return(true);
}
//+------------------------------------------------------------------+
//| TestConstructor_Complex. |
//+------------------------------------------------------------------+
bool TestConstructor_Complex(const int count)
{
//--- create source array and list
int array[];
ArrayResize(array,count);
for(int i=0; i<count; i++)
array[i]=MathRand();
CArrayList<int>list(array);
//--- crete linked list
CLinkedList<int>llist1(array);
CLinkedList<int>llist2(GetPointer(list));
CLinkedList<int>llist3(GetPointer(llist1));
CLinkedList<int>llist4(NULL);
//--- check
int check_array1[];
llist1.CopyTo(check_array1);
if(ArrayCompare(check_array1,array)!=0)
return(false);
int check_array2[];
llist1.CopyTo(check_array2);
if(ArrayCompare(check_array2,array)!=0)
return(false);
int check_array3[];
llist1.CopyTo(check_array3);
if(ArrayCompare(check_array3,array)!=0)
return(false);
if(llist4.Count()!=0)
return(false);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| TestConstructor. |
//+------------------------------------------------------------------+
bool TestConstructor(const string test_name)
{
PrintFormat("%s started",test_name);
//--- test 1
PrintFormat("%s: Test 1: Complex validation constructor of linked list dased on array, several ICollection objects and NULL object.",test_name);
if(!TestConstructor_Complex(16))
return(false);
//--- successful
PrintFormat("%s passed",test_name);
return(true);
}
//+------------------------------------------------------------------+
//| TestMisc_Find. |
//+------------------------------------------------------------------+
bool TestMisc_Find(const int count)
{
CLinkedList<int>list_test();
//--- create test arrays
int check_array[];
int head_items[];
int tail_items[];
int head_prepend_items[];
int tail_prepend_items[];
ArrayResize(head_items,count);
ArrayResize(tail_items,count);
ArrayResize(head_prepend_items,count+1);
ArrayResize(tail_prepend_items,count+1);
head_prepend_items[0]=-1;
tail_prepend_items[0]=-1;
for(int i=0; i<count; i++)
{
int head = (i+1);
int tail = (i+1)*100;
head_items[i]=head;
tail_items[i]=tail;
head_prepend_items[i+1]=head;
tail_prepend_items[i+1]=tail;
}
//--- test call Find an empty collection
//--- check
if(list_test.Find(head_items[0])!=NULL)
return(false);
if(list_test.Find(-1)!=NULL)
return(false);
//--- test call Find on a collection with one item in it
//--- add values
list_test.AddLast(head_items[0]);
//--- check
if(list_test.Find(head_items[1])!=NULL)
return(false);
if(list_test.Find(-1)!=NULL)
return(false);
if(list_test.Find(head_items[0]).Value()!=head_items[0])
return(false);
//--- clear
list_test.Clear();
//--- test call Find on a collection with two items in it
//--- add values
list_test.AddFirst(head_items[0]);
list_test.AddLast(head_items[1]);
//--- check
if(list_test.Find(head_items[2])!=NULL)
return(false);
if(list_test.Find(-1)!=NULL)
return(false);
if(list_test.Find(head_items[0]).Value()!=head_items[0])
return(false);
if(list_test.Find(head_items[1]).Value()!=head_items[1])
return(false);
//--- clear
list_test.Clear();
//--- test call Find on a collection with three items in it
//--- add values
list_test.AddFirst(head_items[0]);
list_test.AddLast(head_items[1]);
list_test.AddLast(head_items[2]);
//--- check
if(list_test.Find(head_items[3])!=NULL)
return(false);
if(list_test.Find(-1)!=NULL)
return(false);
if(list_test.Find(head_items[0]).Value()!=head_items[0])
return(false);
if(list_test.Find(head_items[1]).Value()!=head_items[1])
return(false);
if(list_test.Find(head_items[2]).Value()!=head_items[2])
return(false);
//--- clear
list_test.Clear();
//--- test call Find on a collection with multiple items in it
//--- add values
for(int i=0; i<count;++i)
list_test.AddLast(head_items[i]);
//--- check
if(list_test.Find(tail_items[0])!=NULL)
return(false);
if(list_test.Find(-1)!=NULL)
return(false);
for(int i=0; i<list_test.Count(); i++)
if(list_test.Find(head_items[i]).Value()!=head_items[i])
return(false);
//--- clear
list_test.Clear();
//--- test call Find on a collection with duplicate items in it
//--- add values
for(int i=0; i<count;++i)
list_test.AddLast(head_items[i]);
for(int i=0; i<count;++i)
list_test.AddLast(head_items[i]);
int temp_items[];
ArrayCopy(temp_items,head_items);
ArrayCopy(temp_items,head_items,count);
//--- check
if(list_test.Find(tail_items[0])!=NULL)
return(false);
if(list_test.Find(-1)!=NULL)
return(false);
for(int i=0; i<list_test.Count(); i++)
if(list_test.Find(temp_items[i]).Value()!=temp_items[i])
return(false);
//--- clear
list_test.Clear();
//--- test call Find with -1 at the beginning
//--- add values
for(int i=0; i<count;++i)
list_test.AddLast(head_items[i]);
list_test.AddFirst(-1);
//--- check
if(list_test.Find(tail_items[0])!=NULL)
return(false);
for(int i=0; i<list_test.Count(); i++)
if(list_test.Find(head_prepend_items[i]).Value()!=head_prepend_items[i])
return(false);
//--- clear
list_test.Clear();
//--- test call Find with -1 in the middle
//--- add values
for(int i=0; i<count;++i)
list_test.AddLast(head_items[i]);
list_test.AddLast(-1);
for(int i=0; i<count;++i)
list_test.AddLast(tail_items[i]);
ArrayFree(temp_items);
ArrayCopy(temp_items,head_items);
ArrayCopy(temp_items,tail_prepend_items,count);
//--- check
for(int i=0; i<list_test.Count(); i++)
if(list_test.Find(temp_items[i]).Value()!=temp_items[i])
return(false);
//--- clear
list_test.Clear();
//--- test call Find on a collection with duplicate items in it
//--- add values
for(int i=0; i<count;++i)
list_test.AddLast(head_items[i]);
list_test.AddLast(-1);
ArrayResize(temp_items,count+1);
temp_items[count]=-1;
ArrayCopy(temp_items,head_items);
//--- check
if(list_test.Find(tail_items[0])!=NULL)
return(false);
for(int i=0; i<list_test.Count(); i++)
if(list_test.Find(temp_items[i]).Value()!=temp_items[i])
return(false);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| TestMisc_FindLast. |
//+------------------------------------------------------------------+
bool TestMisc_FindLast(const int count)
{
CLinkedList<int>list_test();
//--- create test arrays
int check_array[];
int head_items[];
int tail_items[];
int head_prepend_items[];
int tail_prepend_items[];
ArrayResize(head_items,count);
ArrayResize(tail_items,count);
ArrayResize(head_prepend_items,count+1);
ArrayResize(tail_prepend_items,count+1);
head_prepend_items[0]=-1;
tail_prepend_items[0]=-1;
for(int i=0; i<count; i++)
{
int head = (i+1);
int tail = (i+1)*100;
head_items[i]=head;
tail_items[i]=tail;
head_prepend_items[i+1]=head;
tail_prepend_items[i+1]=tail;
}
//--- test call FindLast an empty collection
//--- check
if(list_test.FindLast(head_items[0])!=NULL)
return(false);
if(list_test.FindLast(-1)!=NULL)
return(false);
//--- test call FindLast on a collection with one item in it
//--- add values
list_test.AddLast(head_items[0]);
//--- check
if(list_test.FindLast(head_items[1])!=NULL)
return(false);
if(list_test.FindLast(-1)!=NULL)
return(false);
if(list_test.FindLast(head_items[0]).Value()!=head_items[0])
return(false);
//--- clear
list_test.Clear();
//--- test call FindLast on a collection with two items in it
//--- add values
list_test.AddFirst(head_items[0]);
list_test.AddLast(head_items[1]);
//--- check
if(list_test.FindLast(head_items[2])!=NULL)
return(false);
if(list_test.FindLast(-1)!=NULL)
return(false);
if(list_test.FindLast(head_items[0]).Value()!=head_items[0])
return(false);
if(list_test.FindLast(head_items[1]).Value()!=head_items[1])
return(false);
//--- clear
list_test.Clear();
//--- test call FindLast on a collection with three items in it
//--- add values
list_test.AddFirst(head_items[0]);
list_test.AddLast(head_items[1]);
list_test.AddLast(head_items[2]);
//--- check
if(list_test.FindLast(head_items[3])!=NULL)
return(false);
if(list_test.FindLast(-1)!=NULL)
return(false);
if(list_test.FindLast(head_items[0]).Value()!=head_items[0])
return(false);
if(list_test.FindLast(head_items[1]).Value()!=head_items[1])
return(false);
if(list_test.FindLast(head_items[2]).Value()!=head_items[2])
return(false);
//--- clear
list_test.Clear();
//--- test call FindLast on a collection with multiple items in it
//--- add values
for(int i=0; i<count;++i)
list_test.AddLast(head_items[i]);
//--- check
if(list_test.FindLast(tail_items[0])!=NULL)
return(false);
if(list_test.FindLast(-1)!=NULL)
return(false);
for(int i=0; i<list_test.Count(); i++)
if(list_test.FindLast(head_items[i]).Value()!=head_items[i])
return(false);
//--- clear
list_test.Clear();
//--- test call FindLast on a collection with duplicate items in it
//--- add values
for(int i=0; i<count;++i)
list_test.AddLast(head_items[i]);
for(int i=0; i<count;++i)
list_test.AddLast(head_items[i]);
int temp_items[];
ArrayCopy(temp_items,head_items);
ArrayCopy(temp_items,head_items,count);
//--- check
if(list_test.FindLast(tail_items[0])!=NULL)
return(false);
if(list_test.FindLast(-1)!=NULL)
return(false);
for(int i=0; i<list_test.Count(); i++)
if(list_test.FindLast(temp_items[i]).Value()!=temp_items[i])
return(false);
//--- clear
list_test.Clear();
//--- test call FindLast with -1 at the beginning
//--- add values
for(int i=0; i<count;++i)
list_test.AddLast(head_items[i]);
list_test.AddFirst(-1);
//--- check
if(list_test.FindLast(tail_items[0])!=NULL)
return(false);
for(int i=0; i<list_test.Count(); i++)
if(list_test.FindLast(head_prepend_items[i]).Value()!=head_prepend_items[i])
return(false);
//--- clear
list_test.Clear();
//--- test call FindLast with -1 in the middle
//--- add values
for(int i=0; i<count;++i)
list_test.AddLast(head_items[i]);
list_test.AddLast(-1);
for(int i=0; i<count;++i)
list_test.AddLast(tail_items[i]);
ArrayFree(temp_items);
ArrayCopy(temp_items,head_items);
ArrayCopy(temp_items,tail_prepend_items,count);
//--- check
for(int i=0; i<list_test.Count(); i++)
if(list_test.FindLast(temp_items[i]).Value()!=temp_items[i])
return(false);
//--- clear
list_test.Clear();
//--- test call FindLast on a collection with duplicate items in it
//--- add values
for(int i=0; i<count;++i)
list_test.AddLast(head_items[i]);
list_test.AddLast(-1);
ArrayResize(temp_items,count+1);
temp_items[count]=-1;
ArrayCopy(temp_items,head_items);
//--- check
if(list_test.FindLast(tail_items[0])!=NULL)
return(false);
for(int i=0; i<list_test.Count(); i++)
if(list_test.FindLast(temp_items[i]).Value()!=temp_items[i])
return(false);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| TestMisc_RemoveNode. |
//+------------------------------------------------------------------+
bool TestMisc_RemoveNode(const int count)
{
CLinkedList<int>list_test();
int temp_value1;
int temp_value2;
int temp_value3;
//--- create test arrays
int check_array[];
int head_items[];
int tail_items[];
int temp_items[];
ArrayResize(head_items,count);
ArrayResize(tail_items,count);
for(int i=0; i<count; i++)
{
int head = (i+1);
int tail = (i+1)*100;
head_items[i]=head;
tail_items[i]=tail;
}
//--- test call Remove with an item that exists in the collection size=1
//--- add values
list_test.AddLast(head_items[0]);
temp_value1=list_test.First().Value();
//--- remove
list_test.Remove(list_test.First());
//--- check
if(list_test.Count()!=0)
return(false);
if(temp_value1!=head_items[0])
return(false);
//--- clear
list_test.Clear();
//--- test call Remove with the Head collection size=2
//--- add values
list_test.AddFirst(head_items[0]);
list_test.AddLast(head_items[1]);
temp_value1=list_test.First().Value();
//--- remove
list_test.Remove(list_test.First());
//--- check
if(list_test.Count()!=1)
return(false);
if(list_test.First().Value()!=head_items[1])
return(false);
if(temp_value1!=head_items[0])
return(false);
//--- clear
list_test.Clear();
//--- test call Remove with the Tail collection size=2
//--- add values
list_test.AddFirst(head_items[0]);
list_test.AddLast(head_items[1]);
temp_value1=list_test.Last().Value();
//--- remove
list_test.Remove(list_test.Last());
//--- check
if(list_test.Count()!=1)
return(false);
if(list_test.First().Value()!=head_items[0])
return(false);
if(temp_value1!=head_items[1])
return(false);
//--- clear
list_test.Clear();
//--- test call Remove all the items collection size=2
//--- add values
list_test.AddFirst(head_items[0]);
list_test.AddLast(head_items[1]);
temp_value1 = list_test.First().Value();
temp_value2 = list_test.Last().Value();
//--- remove
list_test.Remove(list_test.First());
list_test.Remove(list_test.Last());
//--- check
if(list_test.Count()!=0)
return(false);
if(temp_value2!=head_items[1])
return(false);
if(temp_value1!=head_items[0])
return(false);
//--- clear
list_test.Clear();
//--- test call Remove with the Head collection size=3
//--- add values
list_test.AddFirst(head_items[0]);
list_test.AddLast(head_items[1]);
list_test.AddLast(head_items[2]);
temp_value1=list_test.First().Value();
//--- remove
list_test.Remove(list_test.First());
//--- check
if(list_test.Count()!=2)
return(false);
if(list_test.First().Value()!=head_items[1])
return(false);
if(list_test.First().Next().Value()!=head_items[2])
return(false);
if(temp_value1!=head_items[0])
return(false);
//--- clear
list_test.Clear();
//--- test call Remove with the middle item collection size=3
//--- add values
list_test.AddFirst(head_items[0]);
list_test.AddLast(head_items[1]);
list_test.AddLast(head_items[2]);
temp_value1=list_test.First().Next().Value();
//--- remove
list_test.Remove(list_test.First().Next());
//--- check
if(list_test.Count()!=2)
return(false);
if(list_test.First().Value()!=head_items[0])
return(false);
if(list_test.First().Next().Value()!=head_items[2])
return(false);
if(temp_value1!=head_items[1])
return(false);
//--- clear
list_test.Clear();
//--- test call Remove with the Tail collection size=3
//--- add values
list_test.AddFirst(head_items[0]);
list_test.AddLast(head_items[1]);
list_test.AddLast(head_items[2]);
temp_value1=list_test.Last().Value();
//--- remove
list_test.Remove(list_test.Last());
//--- check
if(list_test.Count()!=2)
return(false);
if(list_test.First().Value()!=head_items[0])
return(false);
if(list_test.First().Next().Value()!=head_items[1])
return(false);
if(temp_value1!=head_items[2])
return(false);
//--- clear
list_test.Clear();
//--- test call Remove all the items collection size=3
//--- add values
list_test.AddFirst(head_items[0]);
list_test.AddLast(head_items[1]);
list_test.AddLast(head_items[2]);
temp_value1 = list_test.First().Value();
temp_value2 = list_test.First().Next().Value();
temp_value3 = list_test.Last().Value();
//--- remove
list_test.Remove(list_test.First().Next().Next());
list_test.Remove(list_test.First().Next());
list_test.Remove(list_test.First());
//--- check
if(list_test.Count()!=0)
return(false);
if(temp_value3!=head_items[2])
return(false);
if(temp_value2!=head_items[1])
return(false);
if(temp_value1!=head_items[0])
return(false);
//--- clear
list_test.Clear();
//--- test call Remove all the items starting with the first collection size=16
//--- add values
for(int i=0; i<count;++i)
list_test.AddLast(head_items[i]);
//--- remove and check
for(int i=0; i<count;++i)
{
list_test.Remove(list_test.First());
int index=i+1;
int length=count-i-1;
int expected[];
int actual[];
ArrayCopy(expected,head_items,0,index,length);
list_test.CopyTo(actual);
if(ArrayCompare(actual,expected)!=0)
return(false);
}
//--- clear
list_test.Clear();
//--- test call Remove all the items starting with the last collection size=16
//--- add values
for(int i=0; i<count;++i)
list_test.AddLast(head_items[i]);
//--- remove and check
for(int i=count-1; 0<=i; --i)
{
list_test.Remove(list_test.Last());
int expected[];
int actual[];
ArrayCopy(expected,head_items,0,0,i);
list_test.CopyTo(actual);
if(ArrayCompare(actual,expected)!=0)
return(false);
}
//--- clear
list_test.Clear();
//--- test remove some items in the middle
//--- add values
for(int i=0; i<count;++i)
list_test.AddFirst(head_items[i]);
//--- remove
list_test.Remove(list_test.First().Next().Next());
list_test.Remove(list_test.Last().Previous().Previous());
list_test.Remove(list_test.First().Next());
list_test.Remove(list_test.Last().Previous());
list_test.Remove(list_test.First());
list_test.Remove(list_test.Last());
//--- with the above remove we should have removed the first and last 3 items
int head_reverse_items[];
ArrayCopy(head_reverse_items,head_items);
ArrayReverse(head_reverse_items,0,count);
ArrayCopy(temp_items,head_reverse_items,0,3,count-6);
//--- check
list_test.CopyTo(check_array);
if(ArrayCompare(check_array,temp_items)!=0)
return(false);
//--- clear
list_test.Clear();
//--- test remove an item with a value of -1
//--- add values
for(int i=0; i<count;++i)
list_test.AddLast(head_items[i]);
list_test.AddLast(-1);
//--- remove
list_test.Remove(list_test.Last());
//--- check
ArrayFree(check_array);
list_test.CopyTo(check_array);
if(ArrayCompare(check_array,head_items)!=0)
return(false);
//--- clear
list_test.Clear();
//--- test remove node with duplicates
int items[];
ArrayResize(items,count);
for(int i=0; i<count; i++)
items[i]=MathRand();
//--- add values
for(int i=0; i<count; i++)
list_test.AddLast(items[i]);
for(int i=0; i<count; i++)
list_test.AddLast(items[i]);
//--- store nodes
CLinkedListNode<int>*nodes[];
CLinkedListNode<int>*current_node=list_test.First();
int index=0;
ArrayResize(nodes,count*2);
while(index<count*2)
{
nodes[index] = current_node;
current_node = current_node.Next();
index++;
}
//--- remove
list_test.Remove(list_test.First().Next().Next());
list_test.Remove(list_test.Last().Previous().Previous());
list_test.Remove(list_test.First().Next());
list_test.Remove(list_test.Last().Previous());
list_test.Remove(list_test.First());
list_test.Remove(list_test.Last());
//--- check
current_node=list_test.First();
for(int i=3; i<(count*2)-3;i++)
{
if(current_node==NULL)
return(false);
if(current_node!=nodes[i])
return(false);
if(items[i%count]!=current_node.Value())
return(false);
current_node=current_node.Next();
}
//--- clear
list_test.Clear();
//--- test verify NULL node
//--- check
if(list_test.Remove((CLinkedListNode<int>*)NULL) && list_test.Remove(0))
return(false);
//--- test verify Node that is a new Node
//--- add values
list_test.AddLast(0);
CLinkedListNode<int>node(1);
//--- check
if(list_test.Remove(GetPointer(node)))
return(false);
//--- clear
list_test.Clear();
//--- test verify Node that already exists in another collection
list_test.AddLast(MathRand());
list_test.AddLast(MathRand());
CLinkedList<int>other();
other.AddLast(MathRand());
other.AddLast(MathRand());
if(list_test.Remove(other.Last()))
return(false);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| TestMisc_RemoveFirst. |
//+------------------------------------------------------------------+
bool TestMisc_RemoveFirst(const int count)
{
CLinkedList<int>list_test();
int temp_value1;
int temp_value2;
int temp_value3;
//--- create test arrays
int check_array[];
int head_items[];
int tail_items[];
int temp_items[];
ArrayResize(head_items,count);
ArrayResize(tail_items,count);
ArrayResize(temp_items,count);
for(int i=0; i<count; i++)
{
int head = (i+1);
int tail = (i+1)*100;
head_items[i]=head;
tail_items[i]=tail;
}
//--- test call RemoveHead on a collection with one item in it
//--- add values
list_test.AddLast(head_items[0]);
temp_value1=list_test.First().Value();
list_test.RemoveFirst();
//--- check
if(list_test.Count()!=0)
return(false);
if(temp_value1!=head_items[0])
return(false);
//--- test call RemoveHead on a collection with two items in it
//--- add values
list_test.AddFirst(head_items[0]);
list_test.AddLast(head_items[1]);
temp_value1 = list_test.First().Value();
temp_value2 = list_test.Last().Value();
//--- remove
list_test.RemoveFirst();
list_test.RemoveFirst();
//--- check
if(list_test.Count()!=0)
return(false);
if(temp_value1!=head_items[0])
return(false);
if(temp_value2!=head_items[1])
return(false);
//--- test call RemoveHead on a collection with three items in it
//--- add values
list_test.AddFirst(head_items[0]);
list_test.AddLast(head_items[1]);
list_test.AddLast(head_items[2]);
temp_value1 = list_test.First().Value();
temp_value2 = list_test.First().Next().Value();
temp_value3 = list_test.Last().Value();
//--- remove
list_test.RemoveFirst();
list_test.RemoveFirst();
list_test.RemoveFirst();
//--- check
if(list_test.Count()!=0)
return(false);
if(temp_value1!=head_items[0])
return(false);
if(temp_value2!=head_items[1])
return(false);
if(temp_value3!=head_items[2])
return(false);
//--- test call RemoveHead on a collection with 16 items in it
//--- add values
for(int i=0; i<count;++i)
list_test.AddLast(head_items[i]);
//--- remove and check
for(int i=0; i<count;++i)
{
list_test.RemoveFirst();
int index=i+1;
int length=count-i-1;
int expected[];
int actual[];
ArrayCopy(expected,head_items,0,index,length);
list_test.CopyTo(actual);
if(ArrayCompare(actual,expected)!=0)
return(false);
}
//--- clear
list_test.Clear();
//--- test mix RemoveHead and RemoveTail call
//--- add values
for(int i=0; i<count;++i)
list_test.AddLast(head_items[i]);
//--- remove and check
for(int i=0; i<count;++i)
{
if((i &1)==0)
list_test.RemoveFirst();
else
list_test.RemoveLast();
int index=(i/2)+1;
int length=count-i-1;
int expected[];
int actual[];
ArrayCopy(expected,head_items,0,index,length);
list_test.CopyTo(actual);
if(ArrayCompare(actual,expected)!=0)
return(false);
}
//--- clear
list_test.Clear();
//--- test call RemoveHead an empty collection
if(list_test.RemoveFirst())
return(false);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| TestMisc_RemoveLast. |
//+------------------------------------------------------------------+
bool TestMisc_RemoveLast(const int count)
{
CLinkedList<int>list_test();
int temp_value1;
int temp_value2;
int temp_value3;
//--- create test arrays
int check_array[];
int head_items[];
int tail_items[];
int temp_items[];
ArrayResize(head_items,count);
ArrayResize(tail_items,count);
ArrayResize(temp_items,count);
for(int i=0; i<count; i++)
{
int head = (i+1);
int tail = (i+1)*100;
head_items[i]=head;
tail_items[i]=tail;
}
//--- test call RemoveHead on a collection with one item in it
//--- add values
list_test.AddLast(head_items[0]);
temp_value1=list_test.First().Value();
list_test.RemoveLast();
//--- check
if(list_test.Count()!=0)
return(false);
if(temp_value1!=head_items[0])
return(false);
//--- test call RemoveHead on a collection with two items in it
//--- add values
list_test.AddFirst(head_items[0]);
list_test.AddLast(head_items[1]);
temp_value1 = list_test.First().Value();
temp_value2 = list_test.Last().Value();
//--- remove and check
list_test.RemoveLast();
if(list_test.Last().Value()!=head_items[0])
return(false);
list_test.RemoveLast();
//--- check
if(list_test.Count()!=0)
return(false);
if(temp_value1!=head_items[0])
return(false);
if(temp_value2!=head_items[1])
return(false);
//--- test call RemoveHead on a collection with three items in it
//--- add values
list_test.AddFirst(head_items[0]);
list_test.AddLast(head_items[1]);
list_test.AddLast(head_items[2]);
temp_value1 = list_test.First().Value();
temp_value2 = list_test.First().Next().Value();
temp_value3 = list_test.Last().Value();
//--- remove and check
list_test.RemoveLast();
if(list_test.Last().Value()!=head_items[1])
return(false);
list_test.RemoveLast();
if(list_test.Last().Value()!=head_items[0])
return(false);
list_test.RemoveLast();
//--- check
if(list_test.Count()!=0)
return(false);
if(temp_value1!=head_items[0])
return(false);
if(temp_value2!=head_items[1])
return(false);
if(temp_value3!=head_items[2])
return(false);
//--- test call RemoveHead on a collection with 16 items in it
//--- add values
for(int i=0; i<count;++i)
list_test.AddLast(head_items[i]);
//--- remove and check
for(int i=0; i<count;++i)
{
list_test.RemoveLast();
int length=count-i-1;
int expected[];
int actual[];
ArrayCopy(expected,head_items,0,0,length);
list_test.CopyTo(actual);
if(ArrayCompare(actual,expected)!=0)
return(false);
}
//--- clear
list_test.Clear();
//--- test mix RemoveHead and RemoveTail call
//--- add values
for(int i=0; i<count;++i)
list_test.AddLast(head_items[i]);
//--- remove and check
for(int i=0; i<count;++i)
{
if((i &1)==0)
list_test.RemoveFirst();
else
list_test.RemoveLast();
int index=(i/2)+1;
int length=count-i-1;
int expected[];
int actual[];
ArrayCopy(expected,head_items,0,index,length);
list_test.CopyTo(actual);
if(ArrayCompare(actual,expected)!=0)
return(false);
}
//--- clear
list_test.Clear();
//--- test call RemoveHead an empty collection
if(list_test.RemoveLast())
return(false);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| TestMisc. |
//+------------------------------------------------------------------+
bool TestMisc(const string test_name)
{
PrintFormat("%s started",test_name);
//--- test 1
PrintFormat("%s: Test 1: Complex validation of Find method of some element in different positions on the linked list with and without duplicates.",test_name);
if(!TestMisc_Find(16))
return(false);
//--- test 2
PrintFormat("%s: Test 2: Complex validation of FindLast method of some element in different positions on the linked list with and without duplicates.",test_name);
if(!TestMisc_FindLast(16))
return(false);
//--- test 3
PrintFormat("%s: Test 3: Complex validation of Remove method of some node in different positions on the linked list with different count of elements.",test_name);
if(!TestMisc_RemoveNode(16))
return(false);
//--- test 4
PrintFormat("%s: Test 3: Complex validation of RemoveFirst method on the linked list with different count of elements.",test_name);
if(!TestMisc_RemoveFirst(16))
return(false);
//--- test 5
PrintFormat("%s: Test 3: Complex validation of RemoveLast method on the linked list with different count of elements.",test_name);
if(!TestMisc_RemoveLast(16))
return(false);
//--- successful
PrintFormat("%s passed",test_name);
return(true);
}
//+------------------------------------------------------------------+
//| TestLinkedList. |
//+------------------------------------------------------------------+
void TestLinkedList(int &tests_performed,int &tests_passed)
{
string test_name="";
//--- AddAfter functions
tests_performed++;
test_name="AddAfter functions test";
if(TestAddAfter(test_name))
tests_passed++;
else
PrintFormat("%s failed",test_name);
//--- AddBefore functions
tests_performed++;
test_name="AddBefore functions test";
if(TestAddBefore(test_name))
tests_passed++;
else
PrintFormat("%s failed",test_name);
//--- AddFirst functions
tests_performed++;
test_name="AddFirst functions test";
if(TestAddFirst(test_name))
tests_passed++;
else
PrintFormat("%s failed",test_name);
//--- AddLast functions
tests_performed++;
test_name="AddLast functions test";
if(TestAddLast(test_name))
tests_passed++;
else
PrintFormat("%s failed",test_name);
//--- Constructor functions
tests_performed++;
test_name="Constructor functions test";
if(TestConstructor(test_name))
tests_passed++;
else
PrintFormat("%s failed",test_name);
//--- Misc functions
tests_performed++;
test_name="Misc functions test";
if(TestMisc(test_name))
tests_passed++;
else
PrintFormat("%s failed",test_name);
}
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
MathSrand(0);
string package_name="Generic";
PrintFormat("Unit tests for Package %s\n",package_name);
//--- initial values
int tests_performed=0;
int tests_passed=0;
//--- test distributions
TestLinkedList(tests_performed,tests_passed);
//--- print statistics
PrintFormat("\n%d of %d passed",tests_passed,tests_performed);
}
//+------------------------------------------------------------------+