tests.generics.sets.pas 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358
  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.sets;
  17. {$mode delphi}
  18. interface
  19. uses
  20. fpcunit, testregistry, testutils, tests.generics.utils,
  21. Classes, SysUtils, Generics.Collections;
  22. type
  23. THashSet_Integer = THashSet<Integer>;
  24. TSortedSet_Integer = TSortedSet<Integer>;
  25. TSortedHashSet_Integer = TSortedHashSet<Integer>;
  26. { TTestSets }
  27. TTestSets = class(TTestCollections)
  28. protected
  29. procedure Test_TCustomSet_Notification(ASet: TCustomSet<string>);
  30. public
  31. constructor Create; override;
  32. published
  33. procedure Test_HashSet_General;
  34. procedure Test_SortedSet_General;
  35. procedure Test_SortedHashSet_General;
  36. procedure Test_HashSet;
  37. procedure Test_SortedSet;
  38. procedure Test_SortedHashSet;
  39. procedure Test_THashSet_Notification;
  40. procedure Test_TSortedSet_Notification;
  41. procedure Test_TSortedHashSet_Notification;
  42. end;
  43. { TGenericTestSets }
  44. TGenericTestSets<T> = record
  45. class procedure ValidateSet(ASet: T; const ANumbers: array of Integer); static;
  46. class procedure Test_Set_General; static;
  47. class procedure Test_Set_Sorted; static;
  48. class procedure Test_Set_NonSorted; static;
  49. end;
  50. var
  51. GTest: TTestSets;
  52. procedure CheckSet_10(ASet: TCustomSet<Integer>; ASortedList: TSortedList<Integer>);
  53. implementation
  54. { TGenericTestSets }
  55. class procedure TGenericTestSets<T>.ValidateSet(ASet: T;
  56. const ANumbers: array of Integer);
  57. var
  58. i: Integer;
  59. begin with GTest do begin
  60. for i in ANumbers do
  61. AssertTrue('Can''t find number ' + i.ToString, ASet.Contains(i));
  62. AssertEquals(ASet.Count, Length(ANumbers));
  63. end end;
  64. class procedure TGenericTestSets<T>.Test_Set_General;
  65. var
  66. NumbersA: T;
  67. NumbersB: T;
  68. NumbersC: T;
  69. i: Integer;
  70. begin with GTest do begin
  71. NumbersA := T.Create;
  72. NumbersB := T.Create;
  73. for i := 0 to 4 do
  74. begin
  75. AssertTrue(NumbersA.Add(i * 2));
  76. AssertTrue(NumbersB.Add((i * 2) + 1));
  77. end;
  78. ValidateSet(NumbersA, [0, 2, 4, 6, 8]);
  79. ValidateSet(NumbersB, [1, 3, 5, 7, 9]);
  80. { UnionWith }
  81. NumbersC := T.Create(NumbersA);
  82. NumbersC.UnionWith(NumbersB);
  83. ValidateSet(NumbersC, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
  84. AssertFalse(NumbersC.Add(5));
  85. AssertFalse(NumbersC.AddRange([6, 7]));
  86. AssertEquals(NumbersC.Count, 10);
  87. { ExceptWith }
  88. NumbersC.ExceptWith(NumbersB);
  89. AssertEquals(NumbersC.Count, 5);
  90. ValidateSet(NumbersC, [0, 2, 4, 6, 8]);
  91. AssertTrue(NumbersC.AddRange(NumbersB));
  92. ValidateSet(NumbersC, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
  93. { SymmetricExceptWith }
  94. NumbersA.Clear;
  95. AssertEquals(NumbersA.Count, 0);
  96. NumbersB.Clear;
  97. AssertEquals(NumbersB.Count, 0);
  98. NumbersC.Clear;
  99. AssertEquals(NumbersC.Count, 0);
  100. AssertTrue(NumbersA.AddRange([0, 1, 2, 3, 4, 5]));
  101. ValidateSet(NumbersA, [0, 1, 2, 3, 4, 5]);
  102. AssertTrue(NumbersB.AddRange([3, 4, 5, 6, 7, 8, 9]));
  103. ValidateSet(NumbersB, [3, 4, 5, 6, 7, 8, 9]);
  104. NumbersC.Free;
  105. NumbersC := T.Create(NumbersA);
  106. ValidateSet(NumbersC, [0, 1, 2, 3, 4, 5]);
  107. NumbersC.SymmetricExceptWith(NumbersB);
  108. ValidateSet(NumbersC, [0, 1, 2, 8, 7, 6, 9]);
  109. { IntersectWith }
  110. NumbersA.Clear;
  111. AssertEquals(NumbersA.Count, 0);
  112. NumbersB.Clear;
  113. AssertEquals(NumbersB.Count, 0);
  114. NumbersC.Clear;
  115. AssertEquals(NumbersC.Count, 0);
  116. AssertTrue(NumbersA.AddRange([0, 1, 2, 3, 4, 5]));
  117. AssertTrue(NumbersB.AddRange([3, 4, 5, 6, 7, 8, 9]));
  118. AssertTrue(NumbersC.AddRange(NumbersA));
  119. NumbersC.IntersectWith(NumbersB);
  120. ValidateSet(NumbersC, [3, 4, 5]);
  121. NumbersC.Free;
  122. NumbersB.Free;
  123. NumbersA.Free;
  124. end end;
  125. class procedure TGenericTestSets<T>.Test_Set_Sorted;
  126. const
  127. SORTED_NUMBERS: array[0..9] of Integer = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
  128. var
  129. Numbers: T;
  130. i, j: Integer;
  131. pi: PInteger;
  132. begin with GTest do begin
  133. Numbers := T.Create;
  134. AssertTrue(Numbers.AddRange([8, 4, 6, 2, 0, 9, 5, 7, 3, 1]));
  135. ValidateSet(Numbers, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
  136. j := 0;
  137. for i in TCustomSet<Integer>(Numbers) do
  138. begin
  139. AssertEquals(i, SORTED_NUMBERS[j]);
  140. Inc(j);
  141. end;
  142. j := 0;
  143. for pi in TCustomSet<Integer>(Numbers).Ptr^ do
  144. begin
  145. AssertEquals(pi^, SORTED_NUMBERS[j]);
  146. Inc(j);
  147. end;
  148. Numbers.Free;
  149. end end;
  150. procedure CheckSet_10(ASet: TCustomSet<Integer>; ASortedList: TSortedList<Integer>);
  151. var
  152. i: Integer;
  153. begin with GTest do begin
  154. AssertEquals(ASortedList.Count, 10);
  155. for i := 0 to 9 do
  156. begin
  157. AssertEquals(i, ASortedList[i]);
  158. AssertTrue(ASet.Contains(i));
  159. end;
  160. end end;
  161. class procedure TGenericTestSets<T>.Test_Set_NonSorted;
  162. var
  163. Numbers: T;
  164. LSortedList: TSortedList<Integer>;
  165. i: Integer;
  166. pi: PInteger;
  167. begin with GTest do begin
  168. Numbers := T.Create;
  169. LSortedList := TSortedList<Integer>.Create;
  170. AssertTrue(Numbers.AddRange([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]));
  171. ValidateSet(Numbers, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
  172. for i in TCustomSet<Integer>(Numbers) do
  173. LSortedList.Add(i);
  174. CheckSet_10(Numbers, LSortedList);
  175. LSortedList.Clear;
  176. for pi in TCustomSet<Integer>(Numbers).Ptr^ do
  177. LSortedList.Add(pi^);
  178. CheckSet_10(Numbers, LSortedList);
  179. LSortedList.Free;
  180. Numbers.Free;
  181. end end;
  182. { TTestSets }
  183. constructor TTestSets.Create;
  184. begin
  185. inherited Create;
  186. GTest := Self;
  187. end;
  188. procedure TTestSets.Test_HashSet_General;
  189. begin
  190. TGenericTestSets<THashSet_Integer>.Test_Set_General;
  191. end;
  192. procedure TTestSets.Test_SortedSet_General;
  193. begin
  194. TGenericTestSets<TSortedSet_Integer>.Test_Set_General;
  195. end;
  196. procedure TTestSets.Test_SortedHashSet_General;
  197. begin
  198. TGenericTestSets<TSortedHashSet_Integer>.Test_Set_General;
  199. end;
  200. procedure TTestSets.Test_HashSet;
  201. begin
  202. TGenericTestSets<THashSet_Integer>.Test_Set_NonSorted;
  203. end;
  204. procedure TTestSets.Test_SortedSet;
  205. begin
  206. TGenericTestSets<TSortedSet_Integer>.Test_Set_Sorted;
  207. end;
  208. procedure TTestSets.Test_SortedHashSet;
  209. begin
  210. TGenericTestSets<TSortedHashSet_Integer>.Test_Set_Sorted;
  211. end;
  212. procedure TTestSets.Test_TCustomSet_Notification(ASet: TCustomSet<string>);
  213. var
  214. LSet: THashSet<string>;
  215. LStringsObj: TEnumerable<string>;
  216. LStringsIntf: IEnumerable<string>;
  217. begin
  218. LSet := THashSet<string>.Create;
  219. try
  220. LStringsObj := EnumerableStringsObj(['Ddd', 'Eee']);
  221. LStringsIntf := EnumerableStringsIntf(['Fff', 'Ggg']);
  222. ASet.OnNotify := NotifyTestStr;
  223. { Add + AddRange }
  224. NotificationAdd(ASet, ['Aaa', 'Bbb', 'Ccc', 'Ddd', 'Eee', 'Fff', 'Ggg'], cnAdded);
  225. AssertTrue(ASet.Add('Aaa'));
  226. AssertTrue(ASet.AddRange(['Bbb', 'Ccc']));
  227. AssertTrue(ASet.AddRange(LStringsObj));
  228. AssertTrue(ASet.AddRange(LStringsIntf));
  229. AssertNotificationsExecutedStr;
  230. { Remove and Extract }
  231. NotificationAdd(ASet, 'Ccc', cnRemoved);
  232. NotificationAdd(ASet, 'Aaa', cnExtracted);
  233. AssertTrue(ASet.Remove('Ccc'));
  234. AssertEquals(ASet.Extract('Aaa'), 'Aaa');
  235. AssertNotificationsExecutedStr;
  236. { ExceptWith }
  237. LSet.Add('Bbb');
  238. NotificationAdd(ASet, 'Bbb', cnRemoved);
  239. ASet.ExceptWith(LSet);
  240. AssertNotificationsExecutedStr;
  241. { IntersectWith }
  242. LSet.AddRange(['Eee', 'Fff', 'Ggg']);
  243. NotificationAdd(ASet, 'Ddd', cnRemoved);
  244. ASet.IntersectWith(LSet);
  245. AssertNotificationsExecutedStr;
  246. { SymmetricExceptWith }
  247. LSet.Clear;
  248. LSet.AddRange(['Fff', 'FPC']);
  249. NotificationAdd(ASet, 'FPC', cnAdded);
  250. NotificationAdd(ASet, 'Fff', cnRemoved);
  251. ASet.SymmetricExceptWith(LSet);
  252. AssertNotificationsExecutedStr;
  253. { Small clean up }
  254. NotificationAdd(ASet, 'Eee', cnRemoved);
  255. NotificationAdd(ASet, 'Ggg', cnExtracted);
  256. AssertTrue(ASet.Remove('Eee'));
  257. AssertEquals(ASet.Extract('Ggg'), 'Ggg');
  258. AssertNotificationsExecutedStr;
  259. { UnionWith }
  260. LSet.Clear;
  261. LSet.Add('Polandball');
  262. NotificationAdd(ASet, 'Polandball', cnAdded);
  263. ASet.UnionWith(LSet);
  264. AssertNotificationsExecutedStr;
  265. { Clear }
  266. NotificationAdd(ASet, 'FPC', cnRemoved);
  267. AssertTrue(ASet.Remove('FPC'));
  268. AssertNotificationsExecutedStr;
  269. NotificationAdd(ASet, 'Polandball', cnRemoved);
  270. ASet.Clear;
  271. AssertNotificationsExecutedStr;
  272. finally
  273. NotificationAdd(ASet, 'Polandball', cnAdded);
  274. ASet.Add('Polandball');
  275. AssertNotificationsExecutedStr;
  276. LSet.Free;
  277. NotificationAdd(ASet, 'Polandball', cnRemoved);
  278. ASet.Free;
  279. AssertNotificationsExecutedStr;
  280. end;
  281. end;
  282. procedure TTestSets.Test_THashSet_Notification;
  283. begin
  284. Test_TCustomSet_Notification(THashSet<string>.Create);
  285. end;
  286. procedure TTestSets.Test_TSortedSet_Notification;
  287. begin
  288. Test_TCustomSet_Notification(TSortedSet<string>.Create);
  289. end;
  290. procedure TTestSets.Test_TSortedHashSet_Notification;
  291. begin
  292. Test_TCustomSet_Notification(TSortedHashSet<string>.Create);
  293. end;
  294. begin
  295. RegisterTest(TTestSets);
  296. end.