tests.generics.sets.pas 9.1 KB

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