tests.generics.trees.pas 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. {
  2. This file is part of the Free Pascal/NewPascal run time library.
  3. Copyright (c) 2018 by Maciej Izak (hnb),
  4. member of the NewPascal development team (http://newpascal.org)
  5. Copyright(c) 2004-2018 DaThoX
  6. It contains tests for the Free Pascal generics library
  7. See the file COPYING.FPC, included in this distribution,
  8. for details about the copyright.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  12. Acknowledgment
  13. Thanks to Sphere 10 Software (http://sphere10.com) for sponsoring
  14. many new types, tests and major refactoring of entire library
  15. **********************************************************************}
  16. unit tests.generics.trees;
  17. {$mode delphi}
  18. interface
  19. uses
  20. fpcunit, testregistry, testutils, tests.generics.utils,
  21. Classes, SysUtils, Generics.Collections;
  22. type
  23. { TTestArrayHelper }
  24. { TTestTrees }
  25. TTestTrees = class(TTestCollections)
  26. published
  27. procedure Test_IndexedAVLTree_Add_General;
  28. procedure Test_IndexedAVLTree_Add;
  29. procedure Test_IndexedAVLTree_Delete;
  30. procedure Test_IndexedAVLTree_Items;
  31. procedure Test_TAVLTreeMap_Notification;
  32. end;
  33. implementation
  34. type
  35. TStringsTree = TIndexedAVLTree<string>;
  36. TMapTree = TAVLTreeMap<string, Integer>;
  37. { TTestTrees }
  38. procedure TTestTrees.Test_IndexedAVLTree_Add_General;
  39. const
  40. _COUNT = 999;
  41. var
  42. LNumbers: THashSet<Integer>;
  43. i, j: Integer;
  44. LTree: TStringsTree;
  45. LNodes: TList<TStringsTree.PNode>;
  46. n: TStringsTree.PNode;
  47. begin
  48. LNumbers := THashSet<Integer>.Create;
  49. LTree := TStringsTree.Create;
  50. LNodes := TList<TStringsTree.PNode>.Create;
  51. try
  52. // check consistency of adding new nodes to Indexed AVL
  53. for i := 0 to _COUNT do
  54. begin
  55. LNodes.Add(LTree.Add('0'+i.ToString));
  56. LNumbers.Clear;
  57. for n in LTree.Nodes do
  58. Check(LNumbers.Add(LTree.NodeToIndex(n)), 'Wrong index (duplicate) of '+ i.ToString + ' for node ' + n.Key);
  59. for j := 0 to LNodes.Count - 1 do
  60. Check(LNumbers.Contains(j), 'Missing index ' + j.ToString + ' for i = ' + i.ToString);
  61. LTree.ConsistencyCheck;
  62. CheckEquals(i+1, LTree.Count, 'Wrong tree count');
  63. end;
  64. finally
  65. LNodes.Free;
  66. LTree.Free;
  67. LNumbers.Free;
  68. end;
  69. end;
  70. procedure TTestTrees.Test_IndexedAVLTree_Add;
  71. var
  72. LTree: TStringsTree;
  73. begin
  74. LTree := TStringsTree.Create;
  75. try
  76. LTree.Duplicates:=dupAccept;
  77. LTree.Add('Aaa');
  78. finally
  79. LTree.Free;
  80. end;
  81. end;
  82. procedure TTestTrees.Test_IndexedAVLTree_Delete;
  83. const
  84. _COUNT = 999;
  85. var
  86. LNumbers: THashSet<Integer>;
  87. i, j: Integer;
  88. LTree: TStringsTree;
  89. LNodes: TList<TStringsTree.PNode>;
  90. n: TStringsTree.PNode;
  91. begin
  92. LNumbers := THashSet<Integer>.Create;
  93. LTree := TStringsTree.Create;
  94. LNodes := TList<TStringsTree.PNode>.Create;
  95. try
  96. for i := 0 to _COUNT do
  97. LNodes.Add(LTree.Add('0'+i.ToString));
  98. // check consistency of deleting nodes from Indexed AVL
  99. for i := 0 to _COUNT do
  100. begin
  101. LTree.Delete(LNodes.ExtractIndex(Random(LNodes.count)));
  102. LNumbers.Clear;
  103. for n in LTree.Nodes do
  104. Check(LNumbers.Add(LTree.NodeToIndex(n)), 'Wrong index (duplicate) of '+ i.ToString + ' for node ' + n.Key);
  105. for j := 0 to LNodes.Count - 1 do
  106. Check(LNumbers.Contains(j), 'Missing index ' + j.ToString + ' for i = ' + i.ToString);
  107. LTree.ConsistencyCheck;
  108. CheckEquals(_COUNT-i, LTree.Count, 'Wrong tree count');
  109. end;
  110. finally
  111. LNodes.Free;
  112. LTree.Free;
  113. LNumbers.Free;
  114. end;
  115. end;
  116. procedure TTestTrees.Test_IndexedAVLTree_Items;
  117. var
  118. LTree: TMapTree;
  119. begin
  120. LTree := TMapTree.Create;
  121. try
  122. Check(LTree.Add('A', 1)<>nil);
  123. Check(LTree.Add('B', 2)<>nil);
  124. Check(LTree.Add('C', 3)<>nil);
  125. CheckEquals(LTree.Items['A'], 1);
  126. CheckEquals(LTree.Items['B'], 2);
  127. CheckEquals(LTree.Items['C'], 3);
  128. LTree.Items['A'] := 4;
  129. LTree.Items['B'] := 5;
  130. LTree.Items['C'] := 6;
  131. CheckEquals(LTree.Items['A'], 4);
  132. CheckEquals(LTree.Items['B'], 5);
  133. CheckEquals(LTree.Items['C'], 6);
  134. finally
  135. LTree.Free;
  136. end;
  137. end;
  138. procedure TTestTrees.Test_TAVLTreeMap_Notification;
  139. var
  140. LTree: TAVLTreeMap<string, string>;
  141. LNode, LA, LC: TAVLTreeMap<string, string>.PNode;
  142. begin
  143. LTree := TAVLTreeMap<string, string>.Create;
  144. LTree.OnKeyNotify := NotifyTestStr;
  145. LTree.OnValueNotify := NotifyTestStr;
  146. LTree.OnNodeNotify := NotifyTestNodeStr;
  147. try
  148. // simple add
  149. NotificationAdd(LTree, ['Aaa', 'Bbb'], cnAdded);
  150. NotificationAdd(LTree, 'Aaa', 'Bbb', nil, cnAdded, false, true);
  151. LA := LTree.Add('Aaa', 'Bbb');
  152. AssertNotificationsExecutedNodeStr;
  153. AssertNotificationsExecutedStr;
  154. // pair add
  155. NotificationAdd(LTree, ['Ccc', 'Ddd'], cnAdded);
  156. NotificationAdd(LTree, 'Ccc', 'Ddd', nil, cnAdded, false, true);
  157. LC := LTree.Add(TAVLTreeMap<string, string>.TTreePair.Create('Ccc', 'Ddd'));
  158. AssertNotificationsExecutedNodeStr;
  159. AssertNotificationsExecutedStr;
  160. // AddNode;
  161. LNode := LTree.NewNode;
  162. LNode.Key := 'Eee';
  163. LNode.Value := 'Fff';
  164. NotificationAdd(LTree, ['Eee', 'Fff'], cnAdded);
  165. NotificationAdd(LTree, 'Eee', 'Fff', LNode, cnAdded, false, false);
  166. AssertTrue(LTree.AddNode(LNode));
  167. AssertNotificationsExecutedNodeStr;
  168. AssertNotificationsExecutedStr;
  169. // Delete
  170. NotificationAdd(LTree, ['Eee', 'Fff'], cnRemoved);
  171. NotificationAdd(LTree, 'Eee', 'Fff', LNode, cnRemoved, false, false);
  172. LTree.Delete(LNode, false);
  173. AssertNotificationsExecutedNodeStr;
  174. AssertNotificationsExecutedStr;
  175. LTree.DisposeNode(LNode);
  176. // remove
  177. NotificationAdd(LTree, ['Aaa', 'Bbb'], cnRemoved);
  178. NotificationAdd(LTree, 'Aaa', 'Bbb', LA, cnRemoved, true, false);
  179. LTree.Remove('Aaa');
  180. AssertNotificationsExecutedNodeStr;
  181. AssertNotificationsExecutedStr;
  182. // free
  183. NotificationAdd(LTree, ['Ccc', 'Ddd'], cnRemoved);
  184. NotificationAdd(LTree, 'Ccc', 'Ddd', LC, cnRemoved, true, false);
  185. finally
  186. LTree.Free;
  187. AssertNotificationsExecutedNodeStr;
  188. AssertNotificationsExecutedStr;
  189. end;
  190. end;
  191. begin
  192. RegisterTest(TTestTrees);
  193. end.