361 lines
11 KiB
MQL5
361 lines
11 KiB
MQL5
//+------------------------------------------------------------------+
| |||
//| TestRedBlackTree.mq5 |
| |||
//| Copyright 2000-2025, MetaQuotes Ltd. |
| |||
//| https://www.mql5.com |
| |||
//+------------------------------------------------------------------+
| |||
#include <Generic\RedBlackTree.mqh>
| |||
#include <Generic\ArrayList.mqh>
| |||
#include <Generic\HashSet.mqh>
| |||
//+------------------------------------------------------------------+
| |||
//| TestMisc_Constructor. |
| |||
//+------------------------------------------------------------------+
| |||
bool TestMisc_Constructor(const int count)
| |||
{
| |||
//--- create list
| |||
CArrayList<int>list(count);
| |||
for(int i=0; i<count; i++)
| |||
list.Add(MathRand());
| |||
//--- create source tree
| |||
CDefaultComparer<int>comparer();
| |||
CRedBlackTree<int>tree_test1(GetPointer(list),GetPointer(comparer));
| |||
CRedBlackTree<int>tree_test2(GetPointer(tree_test1));
| |||
//--- check
| |||
if(tree_test1.Count()!=tree_test2.Count())
| |||
return(false);
| |||
if(tree_test1.Comparer()!=GetPointer(comparer))
| |||
return(false);
| |||
if(tree_test2.Comparer()==GetPointer(comparer))
| |||
return(false);
| |||
//--- get unique sorted values
| |||
CHashSet<int>set(GetPointer(list));
| |||
int expected[];
| |||
set.CopyTo(expected);
| |||
ArraySort(expected);
| |||
//--- check
| |||
int actual1[];
| |||
int actual2[];
| |||
tree_test1.CopyTo(actual1);
| |||
tree_test1.CopyTo(actual2);
| |||
for(int i=0; i<ArraySize(expected); i++)
| |||
if(actual1[i]!=expected[i] || actual2[i]!=expected[i])
| |||
return(false);
| |||
//--- successful
| |||
return(true);
| |||
}
| |||
//+------------------------------------------------------------------+
| |||
//| TestMisc_Contains. |
| |||
//+------------------------------------------------------------------+
| |||
bool TestMisc_Contains(const int count)
| |||
{
| |||
//--- create list
| |||
CArrayList<int>list(count);
| |||
for(int i=0; i<count; i++)
| |||
list.Add(MathRand());
| |||
//--- create source tree
| |||
CRedBlackTree<int>tree_test(GetPointer(list));
| |||
//--- check
| |||
for(int i=0; i<count; i++)
| |||
{
| |||
int value;
| |||
list.TryGetValue(i,value);
| |||
if(!tree_test.Contains(value))
| |||
return(false);
| |||
}
| |||
//--- clear tree
| |||
tree_test.Clear();
| |||
//--- check
| |||
for(int i=0; i<count; i++)
| |||
{
| |||
int value;
| |||
list.TryGetValue(i,value);
| |||
if(tree_test.Contains(value))
| |||
return(false);
| |||
}
| |||
//--- successful
| |||
return(true);
| |||
}
| |||
//+------------------------------------------------------------------+
| |||
//| TestMisc_Add. |
| |||
//+------------------------------------------------------------------+
| |||
bool TestMisc_Add(const int count)
| |||
{
| |||
//--- create list
| |||
CArrayList<int>list(count);
| |||
for(int i=0; i<count; i++)
| |||
list.Add(MathRand());
| |||
//--- create source tree
| |||
CRedBlackTree<int>tree_test(GetPointer(list));
| |||
//--- check
| |||
if(tree_test.Count()>count)
| |||
return(false);
| |||
//--- create new unique element
| |||
int element=MathRand();
| |||
while(tree_test.Contains(element))
| |||
element=MathRand();
| |||
//--- add new unique element
| |||
if(!tree_test.Add(element))
| |||
return(false);
| |||
if(tree_test.Add(element))
| |||
return(false);
| |||
//--- successful
| |||
return(true);
| |||
}
| |||
//+------------------------------------------------------------------+
| |||
//| TestMisc. |
| |||
//+------------------------------------------------------------------+
| |||
bool TestMisc(const string test_name)
| |||
{
| |||
PrintFormat("%s started",test_name);
| |||
//--- test 1
| |||
PrintFormat("%s: Test 1: Testing Constructor of map based on several different ICollection objects with and without comparer.",test_name);
| |||
if(!TestMisc_Constructor(16))
| |||
return(false);
| |||
//--- test 2
| |||
PrintFormat("%s: Test 2: Validation of Contains method before and after cleaning the tree.",test_name);
| |||
if(!TestMisc_Contains(16))
| |||
return(false);
| |||
//--- test 3
| |||
PrintFormat("%s: Test 3: Simple validation of Add method.",test_name);
| |||
if(!TestMisc_Add(16))
| |||
return(false);
| |||
//--- successful
| |||
PrintFormat("%s passed",test_name);
| |||
return(true);
| |||
}
| |||
//+------------------------------------------------------------------+
| |||
//| TestFind_Max. |
| |||
//+------------------------------------------------------------------+
| |||
bool TestFind_Max(const int count)
| |||
{
| |||
//--- create list
| |||
CArrayList<int>list(count);
| |||
for(int i=0; i<count; i++)
| |||
list.Add(MathRand());
| |||
//--- create source tree
| |||
CRedBlackTree<int>tree_test(GetPointer(list));
| |||
//--- get max
| |||
list.Sort();
| |||
CRedBlackTreeNode<int>*max_node=tree_test.FindMax();
| |||
int expected;
| |||
list.TryGetValue(count-1,expected);
| |||
int actual=max_node.Value();
| |||
//--- check
| |||
if(expected!=actual)
| |||
return(false);
| |||
if(tree_test.Find(expected)!=max_node)
| |||
return(false);
| |||
//--- successful
| |||
return(true);
| |||
}
| |||
//+------------------------------------------------------------------+
| |||
//| TestFind_Min. |
| |||
//+------------------------------------------------------------------+
| |||
bool TestFind_Min(const int count)
| |||
{
| |||
//--- create list
| |||
CArrayList<int>list(count);
| |||
for(int i=0; i<count; i++)
| |||
list.Add(MathRand());
| |||
//--- create source tree
| |||
CRedBlackTree<int>tree_test(GetPointer(list));
| |||
//--- get max
| |||
list.Sort();
| |||
CRedBlackTreeNode<int>*min_node=tree_test.FindMin();
| |||
int expected;
| |||
list.TryGetValue(0, expected);
| |||
int actual=min_node.Value();
| |||
//--- check
| |||
if(expected!=actual)
| |||
return(false);
| |||
if(tree_test.Find(expected)!=min_node)
| |||
return(false);
| |||
//--- successful
| |||
return(true);
| |||
}
| |||
//+------------------------------------------------------------------+
| |||
//| TestFind. |
| |||
//+------------------------------------------------------------------+
| |||
bool TestFind(const string test_name)
| |||
{
| |||
PrintFormat("%s started",test_name);
| |||
//--- test 1
| |||
PrintFormat("%s: Test 1: Simple validation of FindMax method for tree.",test_name);
| |||
if(!TestFind_Max(16))
| |||
return(false);
| |||
//--- test 2
| |||
PrintFormat("%s: Test 2: Simple validation of FindMin method for tree.",test_name);
| |||
if(!TestFind_Min(16))
| |||
return(false);
| |||
//--- successful
| |||
PrintFormat("%s passed",test_name);
| |||
return(true);
| |||
}
| |||
//+------------------------------------------------------------------+
| |||
//| TestRemove_Node. |
| |||
//+------------------------------------------------------------------+
| |||
bool TestRemove_Node(const int count)
| |||
{
| |||
//--- create list
| |||
CArrayList<int>list(count);
| |||
for(int i=0; i<count; i++)
| |||
list.Add(MathRand());
| |||
//--- create source tree
| |||
CRedBlackTree<int>tree_test(GetPointer(list));
| |||
//--- get max and min
| |||
list.Sort();
| |||
int min;
| |||
int max;
| |||
list.TryGetValue(0, min);
| |||
list.TryGetValue(count-1, max);
| |||
//--- check
| |||
if(tree_test.Count()>0)
| |||
{
| |||
//--- remove min value
| |||
if(!tree_test.Remove(min))
| |||
return(false);
| |||
}
| |||
if(tree_test.Count()>0)
| |||
{
| |||
//--- remove max node
| |||
CRedBlackTreeNode<int>*node=tree_test.FindMax();
| |||
if(!tree_test.Remove(node))
| |||
return(false);
| |||
}
| |||
//--- get unique sorted values
| |||
CHashSet<int>set(GetPointer(list));
| |||
set.Remove(min);
| |||
set.Remove(max);
| |||
int expected[];
| |||
set.CopyTo(expected);
| |||
ArraySort(expected);
| |||
//--- check
| |||
int actual[];
| |||
tree_test.CopyTo(actual);
| |||
if(ArrayCompare(expected,actual)!=0)
| |||
return(false);
| |||
//--- successful
| |||
return(true);
| |||
}
| |||
//+------------------------------------------------------------------+
| |||
//| TestRemove_Max. |
| |||
//+------------------------------------------------------------------+
| |||
bool TestRemove_Max(const int count)
| |||
{
| |||
//--- create list
| |||
CArrayList<int>list(count);
| |||
for(int i=0; i<count; i++)
| |||
list.Add(MathRand());
| |||
//--- create source tree
| |||
CRedBlackTree<int>tree_test(GetPointer(list));
| |||
//--- get unique sorted values
| |||
CHashSet<int>set(GetPointer(list));
| |||
int expected[];
| |||
set.CopyTo(expected);
| |||
ArraySort(expected);
| |||
//--- check
| |||
for(int i=0; i<ArraySize(expected); i++)
| |||
{
| |||
int actual[];
| |||
tree_test.CopyTo(actual);
| |||
if(ArrayCompare(expected,actual,0,0,count-i)!=0)
| |||
return(false);
| |||
tree_test.RemoveMax();
| |||
}
| |||
//--- successful
| |||
return(true);
| |||
}
| |||
//+------------------------------------------------------------------+
| |||
//| TestRemove_Min. |
| |||
//+------------------------------------------------------------------+
| |||
bool TestRemove_Min(const int count)
| |||
{
| |||
//--- create list
| |||
CArrayList<int>list(count);
| |||
for(int i=0; i<count; i++)
| |||
list.Add(MathRand());
| |||
//--- create source tree
| |||
CRedBlackTree<int>tree_test(GetPointer(list));
| |||
//--- get unique sorted values
| |||
CHashSet<int>set(GetPointer(list));
| |||
int expected[];
| |||
set.CopyTo(expected);
| |||
ArraySort(expected);
| |||
//--- check
| |||
for(int i=0; i<ArraySize(expected); i++)
| |||
{
| |||
int actual[];
| |||
tree_test.CopyTo(actual);
| |||
if(ArrayCompare(expected,actual,i,0,count-i)!=0)
| |||
return(false);
| |||
tree_test.RemoveMin();
| |||
}
| |||
//--- successful
| |||
return(true);
| |||
}
| |||
//+------------------------------------------------------------------+
| |||
//| TestRemove. |
| |||
//+------------------------------------------------------------------+
| |||
bool TestRemove(const string test_name)
| |||
{
| |||
PrintFormat("%s started",test_name);
| |||
//--- test 1
| |||
PrintFormat("%s: Test 2: Validation of Remove method used independent element and specified node of tree.",test_name);
| |||
if(!TestRemove_Node(16))
| |||
return(false);
| |||
//--- test 2
| |||
PrintFormat("%s: Test 2: Validation of RemoveMax method for cleaning the tree.",test_name);
| |||
if(!TestRemove_Max(16))
| |||
return(false);
| |||
//--- test 3
| |||
PrintFormat("%s: Test 3: Validation of RemoveMin method for cleaning the tree.",test_name);
| |||
if(!TestRemove_Min(16))
| |||
return(false);
| |||
//--- successful
| |||
PrintFormat("%s passed",test_name);
| |||
return(true);
| |||
}
| |||
//+------------------------------------------------------------------+
| |||
//| TestRedBlackTree. |
| |||
//+------------------------------------------------------------------+
| |||
void TestRedBlackTree(int &tests_performed,int &tests_passed)
| |||
{
| |||
string test_name="";
| |||
//--- Misc functions
| |||
tests_performed++;
| |||
test_name="Misc functions test";
| |||
if(TestMisc(test_name))
| |||
tests_passed++;
| |||
else
| |||
PrintFormat("%s failed",test_name);
| |||
//--- Find functions
| |||
tests_performed++;
| |||
test_name="Find functions test";
| |||
if(TestFind(test_name))
| |||
tests_passed++;
| |||
else
| |||
PrintFormat("%s failed",test_name);
| |||
//--- Remove functions
| |||
tests_performed++;
| |||
test_name="Remove functions test";
| |||
if(TestRemove(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
| |||
TestRedBlackTree(tests_performed,tests_passed);
| |||
//--- print statistics
| |||
PrintFormat("\n%d of %d passed",tests_passed,tests_performed);
| |||
}
| |||
//+------------------------------------------------------------------+
|