MobinMQL/Scripts/UnitTests/Generic/TestRedBlackTree.mq5

362 lines
11 KiB
MQL5
Raw Permalink Normal View History

2025-07-22 14:48:34 +03:00
//+------------------------------------------------------------------+
//| 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);
}
//+------------------------------------------------------------------+