You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

523 lines
17 KiB

  1. unit uutlEnumeratorTests;
  2. {$mode objfpc}{$H+}
  3. {$IFDEF UTL_NESTED_PROCVARS}
  4. {$modeswitch nestedprocvars}
  5. {$ENDIF}
  6. interface
  7. uses
  8. Classes, SysUtils, TestFramework,
  9. uutlEnumerator, uutlInterfaces;
  10. type
  11. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  12. IIntEnumerator = specialize {$IFDEF UTL_ENUMERATORS}IutlEnumerator{$ELSE}IEnumerator{$ENDIF}<Integer>;
  13. TutlEnumeratorTests = class(TTestCase)
  14. protected
  15. fEnumerator: IIntEnumerator;
  16. function GenerateOther(const aData: array of Integer): IIntEnumerator;
  17. procedure Generate(const aData: array of Integer); virtual; abstract;
  18. published
  19. // Procedure Names: ProcedureUnderTest_[Parameter]_EnumeratorItems_Result
  20. procedure Iterate_1to5_1to5;
  21. {$IFDEF UTL_ENUMERATORS}
  22. procedure Count_1to5_5;
  23. procedure Any_Empty_False;
  24. procedure Any_1to5_True;
  25. procedure Reverse_1to5_5to1;
  26. procedure Skip2_1to5_3to5;
  27. procedure Take3_1to5_1to3;
  28. procedure Skip5_Reverse_0to9_9to5;
  29. procedure Take5_Reverse_0to9_4to0;
  30. procedure Reverse_Skip5_0to9_4to0;
  31. procedure Reverse_Take5_0to9_9to5;
  32. procedure Contains3_1to5_true;
  33. procedure Contains9_1to5_false;
  34. procedure Concat6to8_1to5_1to8;
  35. {$IFDEF UTL_ADVANCED_ENUMERATORS}
  36. procedure Sort;
  37. procedure Where_IsEven;
  38. procedure Distinct;
  39. procedure Intersect;
  40. procedure Union;
  41. procedure Without;
  42. procedure Select;
  43. {$ENDIF}
  44. {$ENDIF}
  45. end;
  46. TutlArrayEnumeratorTests = class(TutlEnumeratorTests)
  47. protected
  48. procedure Generate(const aData: array of Integer); override;
  49. public
  50. procedure SetUp; override;
  51. end;
  52. implementation
  53. uses
  54. uutlFilter, uutlComparer;
  55. type
  56. TIntArrayEnumerator = specialize TutlArrayEnumerator<Integer>;
  57. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  58. //TutlEnumeratorTests///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  59. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  60. function TutlEnumeratorTests.GenerateOther(const aData: array of Integer): IIntEnumerator;
  61. var
  62. i: Integer;
  63. arr: TIntArrayEnumerator.TArray;
  64. begin
  65. SetLength(arr, Length(aData));
  66. for i := low(aData) to high(aData) do
  67. arr[i] := aData[i];
  68. result := TIntArrayEnumerator.Create(arr);
  69. end;
  70. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  71. procedure TutlEnumeratorTests.Iterate_1to5_1to5;
  72. begin
  73. Generate([1, 2, 3, 4, 5]);
  74. fEnumerator.Reset;
  75. AssertTrue (fEnumerator.MoveNext);
  76. AssertEquals(1, fEnumerator.GetCurrent);
  77. AssertTrue (fEnumerator.MoveNext);
  78. AssertEquals(2, fEnumerator.GetCurrent);
  79. AssertTrue (fEnumerator.MoveNext);
  80. AssertEquals(3, fEnumerator.GetCurrent);
  81. AssertTrue (fEnumerator.MoveNext);
  82. AssertEquals(4, fEnumerator.GetCurrent);
  83. AssertTrue (fEnumerator.MoveNext);
  84. AssertEquals(5, fEnumerator.GetCurrent);
  85. AssertFalse (fEnumerator.MoveNext);
  86. end;
  87. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  88. {$IFDEF UTL_ENUMERATORS}
  89. procedure TutlEnumeratorTests.Count_1to5_5;
  90. var
  91. i: Integer;
  92. begin
  93. Generate([1, 2, 3, 4, 5]);
  94. i := fEnumerator.Count;
  95. AssertEquals(5, i);
  96. end;
  97. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  98. procedure TutlEnumeratorTests.Any_Empty_False;
  99. begin
  100. AssertFalse(fEnumerator.Any);
  101. end;
  102. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  103. procedure TutlEnumeratorTests.Any_1to5_True;
  104. begin
  105. Generate([1, 2, 3, 4, 5]);
  106. AssertTrue(fEnumerator.Any);
  107. end;
  108. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  109. procedure TutlEnumeratorTests.Reverse_1to5_5to1;
  110. var
  111. e: IIntEnumerator;
  112. begin
  113. e := fEnumerator.Reverse;
  114. Generate([1, 2, 3, 4, 5]);
  115. e.Reset;
  116. AssertTrue (e.MoveNext);
  117. AssertEquals(5, e.GetCurrent);
  118. AssertTrue (e.MoveNext);
  119. AssertEquals(4, e.GetCurrent);
  120. AssertTrue (e.MoveNext);
  121. AssertEquals(3, e.GetCurrent);
  122. AssertTrue (e.MoveNext);
  123. AssertEquals(2, e.GetCurrent);
  124. AssertTrue (e.MoveNext);
  125. AssertEquals(1, e.GetCurrent);
  126. AssertFalse (e.MoveNext);
  127. end;
  128. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  129. procedure TutlEnumeratorTests.Skip2_1to5_3to5;
  130. var
  131. e: IIntEnumerator;
  132. begin
  133. e := fEnumerator.Skip(2);
  134. Generate([1, 2, 3, 4, 5]);
  135. e.Reset;
  136. AssertTrue (e.MoveNext);
  137. AssertEquals(3, e.GetCurrent);
  138. AssertTrue (e.MoveNext);
  139. AssertEquals(4, e.GetCurrent);
  140. AssertTrue (e.MoveNext);
  141. AssertEquals(5, e.GetCurrent);
  142. AssertFalse (e.MoveNext);
  143. end;
  144. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  145. procedure TutlEnumeratorTests.Take3_1to5_1to3;
  146. var
  147. e: IIntEnumerator;
  148. begin
  149. e := fEnumerator.Take(3);
  150. Generate([1, 2, 3, 4, 5]);
  151. e.Reset;
  152. AssertTrue (e.MoveNext);
  153. AssertEquals(1, e.GetCurrent);
  154. AssertTrue (e.MoveNext);
  155. AssertEquals(2, e.GetCurrent);
  156. AssertTrue (e.MoveNext);
  157. AssertEquals(3, e.GetCurrent);
  158. AssertFalse (e.MoveNext);
  159. end;
  160. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  161. procedure TutlEnumeratorTests.Skip5_Reverse_0to9_9to5;
  162. var
  163. e: IIntEnumerator;
  164. begin
  165. e := fEnumerator.Skip(5).Reverse;
  166. Generate([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
  167. e.Reset;
  168. AssertTrue (e.MoveNext);
  169. AssertEquals(9, e.GetCurrent);
  170. AssertTrue (e.MoveNext);
  171. AssertEquals(8, e.GetCurrent);
  172. AssertTrue (e.MoveNext);
  173. AssertEquals(7, e.GetCurrent);
  174. AssertTrue (e.MoveNext);
  175. AssertEquals(6, e.GetCurrent);
  176. AssertTrue (e.MoveNext);
  177. AssertEquals(5, e.GetCurrent);
  178. AssertFalse (e.MoveNext);
  179. end;
  180. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  181. procedure TutlEnumeratorTests.Take5_Reverse_0to9_4to0;
  182. var
  183. e: IIntEnumerator;
  184. begin
  185. e := fEnumerator.Take(5).Reverse;
  186. Generate([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
  187. e.Reset;
  188. AssertTrue (e.MoveNext);
  189. AssertEquals(4, e.GetCurrent);
  190. AssertTrue (e.MoveNext);
  191. AssertEquals(3, e.GetCurrent);
  192. AssertTrue (e.MoveNext);
  193. AssertEquals(2, e.GetCurrent);
  194. AssertTrue (e.MoveNext);
  195. AssertEquals(1, e.GetCurrent);
  196. AssertTrue (e.MoveNext);
  197. AssertEquals(0, e.GetCurrent);
  198. AssertFalse (e.MoveNext);
  199. end;
  200. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  201. procedure TutlEnumeratorTests.Reverse_Skip5_0to9_4to0;
  202. var
  203. e: IIntEnumerator;
  204. begin
  205. e := fEnumerator.Reverse.Skip(5);
  206. Generate([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
  207. e.Reset;
  208. AssertTrue (e.MoveNext);
  209. AssertEquals(4, e.GetCurrent);
  210. AssertTrue (e.MoveNext);
  211. AssertEquals(3, e.GetCurrent);
  212. AssertTrue (e.MoveNext);
  213. AssertEquals(2, e.GetCurrent);
  214. AssertTrue (e.MoveNext);
  215. AssertEquals(1, e.GetCurrent);
  216. AssertTrue (e.MoveNext);
  217. AssertEquals(0, e.GetCurrent);
  218. AssertFalse (e.MoveNext);
  219. end;
  220. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  221. procedure TutlEnumeratorTests.Reverse_Take5_0to9_9to5;
  222. var
  223. e: IIntEnumerator;
  224. begin
  225. e := fEnumerator.Reverse.Take(5);
  226. Generate([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
  227. e.Reset;
  228. AssertTrue (e.MoveNext);
  229. AssertEquals(9, e.GetCurrent);
  230. AssertTrue (e.MoveNext);
  231. AssertEquals(8, e.GetCurrent);
  232. AssertTrue (e.MoveNext);
  233. AssertEquals(7, e.GetCurrent);
  234. AssertTrue (e.MoveNext);
  235. AssertEquals(6, e.GetCurrent);
  236. AssertTrue (e.MoveNext);
  237. AssertEquals(5, e.GetCurrent);
  238. AssertFalse (e.MoveNext);
  239. end;
  240. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  241. procedure TutlEnumeratorTests.Contains3_1to5_true;
  242. var
  243. b: Boolean;
  244. begin
  245. Generate([1, 2, 3, 4, 5]);
  246. b := fEnumerator.Contains(3, specialize TutlEqualityComparer<Integer>.Create);
  247. AssertTrue(b);
  248. end;
  249. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  250. procedure TutlEnumeratorTests.Contains9_1to5_false;
  251. var
  252. b: Boolean;
  253. begin
  254. Generate([1, 2, 3, 4, 5]);
  255. b := fEnumerator.Contains(9, specialize TutlEqualityComparer<Integer>.Create);
  256. AssertFalse(b);
  257. end;
  258. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  259. procedure TutlEnumeratorTests.Concat6to8_1to5_1to8;
  260. var
  261. e: IIntEnumerator;
  262. begin
  263. e := fEnumerator.Concat(GenerateOther([6, 7, 8]));
  264. Generate([1, 2, 3, 4, 5]);
  265. e.Reset;
  266. AssertTrue (e.MoveNext);
  267. AssertEquals(1, e.GetCurrent);
  268. AssertTrue (e.MoveNext);
  269. AssertEquals(2, e.GetCurrent);
  270. AssertTrue (e.MoveNext);
  271. AssertEquals(3, e.GetCurrent);
  272. AssertTrue (e.MoveNext);
  273. AssertEquals(4, e.GetCurrent);
  274. AssertTrue (e.MoveNext);
  275. AssertEquals(5, e.GetCurrent);
  276. AssertTrue (e.MoveNext);
  277. AssertEquals(6, e.GetCurrent);
  278. AssertTrue (e.MoveNext);
  279. AssertEquals(7, e.GetCurrent);
  280. AssertTrue (e.MoveNext);
  281. AssertEquals(8, e.GetCurrent);
  282. AssertFalse (e.MoveNext);
  283. end;
  284. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  285. {$IFDEF UTL_ADVANCED_ENUMERATORS}
  286. procedure TutlEnumeratorTests.Sort;
  287. var
  288. e: IIntEnumerator;
  289. begin
  290. e := fEnumerator.Sort(specialize TutlComparer<Integer>.Create);
  291. Generate([5, 8, 2, 6, 9, 4, 2, 6, 8, 4, 2, 5, 8, 4]);
  292. e.Reset;
  293. AssertTrue (e.MoveNext);
  294. AssertEquals(2, e.GetCurrent);
  295. AssertTrue (e.MoveNext);
  296. AssertEquals(2, e.GetCurrent);
  297. AssertTrue (e.MoveNext);
  298. AssertEquals(2, e.GetCurrent);
  299. AssertTrue (e.MoveNext);
  300. AssertEquals(4, e.GetCurrent);
  301. AssertTrue (e.MoveNext);
  302. AssertEquals(4, e.GetCurrent);
  303. AssertTrue (e.MoveNext);
  304. AssertEquals(4, e.GetCurrent);
  305. AssertTrue (e.MoveNext);
  306. AssertEquals(5, e.GetCurrent);
  307. AssertTrue (e.MoveNext);
  308. AssertEquals(5, e.GetCurrent);
  309. AssertTrue (e.MoveNext);
  310. AssertEquals(6, e.GetCurrent);
  311. AssertTrue (e.MoveNext);
  312. AssertEquals(6, e.GetCurrent);
  313. AssertTrue (e.MoveNext);
  314. AssertEquals(8, e.GetCurrent);
  315. AssertTrue (e.MoveNext);
  316. AssertEquals(8, e.GetCurrent);
  317. AssertTrue (e.MoveNext);
  318. AssertEquals(8, e.GetCurrent);
  319. AssertTrue (e.MoveNext);
  320. AssertEquals(9, e.GetCurrent);
  321. AssertFalse (e.MoveNext);
  322. end;
  323. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  324. function IsEven(constref i: Integer): Boolean;
  325. begin
  326. result := (i mod 2) = 0;
  327. end;
  328. procedure TutlEnumeratorTests.Where_IsEven;
  329. var
  330. e: IIntEnumerator;
  331. begin
  332. e := fEnumerator.Where(specialize TutlCallbackFilter<Integer>.Create(@IsEven));
  333. Generate([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
  334. e.Reset;
  335. AssertTrue (e.MoveNext);
  336. AssertEquals(0, e.GetCurrent);
  337. AssertTrue (e.MoveNext);
  338. AssertEquals(2, e.GetCurrent);
  339. AssertTrue (e.MoveNext);
  340. AssertEquals(4, e.GetCurrent);
  341. AssertTrue (e.MoveNext);
  342. AssertEquals(6, e.GetCurrent);
  343. AssertTrue (e.MoveNext);
  344. AssertEquals(8, e.GetCurrent);
  345. AssertFalse (e.MoveNext);
  346. end;
  347. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  348. procedure TutlEnumeratorTests.Distinct;
  349. var
  350. e: IIntEnumerator;
  351. begin
  352. e := fEnumerator.Distinct(specialize TutlComparer<Integer>.Create);
  353. Generate([1, 5, 2, 7, 1, 3, 7, 4, 5, 8]);
  354. e.Reset;
  355. AssertTrue (e.MoveNext);
  356. AssertEquals(1, e.Current);
  357. AssertTrue (e.MoveNext);
  358. AssertEquals(5, e.Current);
  359. AssertTrue (e.MoveNext);
  360. AssertEquals(2, e.Current);
  361. AssertTrue (e.MoveNext);
  362. AssertEquals(7, e.Current);
  363. AssertTrue (e.MoveNext);
  364. AssertEquals(3, e.Current);
  365. AssertTrue (e.MoveNext);
  366. AssertEquals(4, e.Current);
  367. AssertTrue (e.MoveNext);
  368. AssertEquals(8, e.Current);
  369. AssertFalse (e.MoveNext);
  370. end;
  371. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  372. procedure TutlEnumeratorTests.Intersect;
  373. var
  374. e: IIntEnumerator;
  375. begin
  376. e := fEnumerator
  377. .Intersect(GenerateOther([5, 6, 8]), specialize TutlComparer<Integer>.Create);
  378. Generate([1, 6, 4, 8, 2, 5]);
  379. e.Reset;
  380. AssertTrue (e.MoveNext);
  381. AssertEquals(6, e.Current);
  382. AssertTrue (e.MoveNext);
  383. AssertEquals(8, e.Current);
  384. AssertTrue (e.MoveNext);
  385. AssertEquals(5, e.Current);
  386. AssertFalse (e.MoveNext);
  387. end;
  388. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  389. procedure TutlEnumeratorTests.Union;
  390. var
  391. e: IIntEnumerator;
  392. begin
  393. e := fEnumerator
  394. .Union(GenerateOther([9, 3, 4, 6, 7]), specialize TutlComparer<Integer>.Create);
  395. Generate([1, 6, 4, 8, 2, 5]);
  396. e.Reset;
  397. AssertTrue (e.MoveNext);
  398. AssertEquals(1, e.Current);
  399. AssertTrue (e.MoveNext);
  400. AssertEquals(6, e.Current);
  401. AssertTrue (e.MoveNext);
  402. AssertEquals(4, e.Current);
  403. AssertTrue (e.MoveNext);
  404. AssertEquals(8, e.Current);
  405. AssertTrue (e.MoveNext);
  406. AssertEquals(2, e.Current);
  407. AssertTrue (e.MoveNext);
  408. AssertEquals(5, e.Current);
  409. AssertTrue (e.MoveNext);
  410. AssertEquals(9, e.Current);
  411. AssertTrue (e.MoveNext);
  412. AssertEquals(3, e.Current);
  413. AssertTrue (e.MoveNext);
  414. AssertEquals(7, e.Current);
  415. AssertFalse (e.MoveNext);
  416. end;
  417. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  418. procedure TutlEnumeratorTests.Without;
  419. var
  420. e: IIntEnumerator;
  421. begin
  422. e := fEnumerator
  423. .Without(GenerateOther([6, 8, 5]), specialize TutlComparer<Integer>.Create);
  424. Generate([1, 6, 4, 8, 2, 5]);
  425. e.Reset;
  426. AssertTrue (e.MoveNext);
  427. AssertEquals(1, e.Current);
  428. AssertTrue (e.MoveNext);
  429. AssertEquals(4, e.Current);
  430. AssertTrue (e.MoveNext);
  431. AssertEquals(2, e.Current);
  432. AssertFalse (e.MoveNext);
  433. end;
  434. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  435. function ConvertToFloat(constref a: Integer): Single;
  436. begin
  437. result := Single(a) / 2.0;
  438. end;
  439. procedure TutlEnumeratorTests.Select;
  440. var
  441. e: specialize IutlEnumerator<Single>;
  442. begin
  443. e := specialize TutlSelectEnumerator<Integer, Single>.Create(
  444. fEnumerator,
  445. specialize TutlCallbackSelector<Integer, Single>.Create(@ConvertToFloat));
  446. Generate([1, 2, 3, 4, 5]);
  447. e.Reset;
  448. AssertTrue (e.MoveNext);
  449. AssertEquals(0.5, e.Current);
  450. AssertTrue (e.MoveNext);
  451. AssertEquals(1.0, e.Current);
  452. AssertTrue (e.MoveNext);
  453. AssertEquals(1.5, e.Current);
  454. AssertTrue (e.MoveNext);
  455. AssertEquals(2.0, e.Current);
  456. AssertTrue (e.MoveNext);
  457. AssertEquals(2.5, e.Current);
  458. AssertFalse (e.MoveNext);
  459. end;
  460. {$ENDIF}
  461. {$ENDIF}
  462. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  463. //TutlArrayEnumeratorTests//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  464. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  465. procedure TutlArrayEnumeratorTests.Generate(const aData: array of Integer);
  466. var
  467. i: Integer;
  468. arr: TIntArrayEnumerator.TArray;
  469. begin
  470. SetLength(arr, Length(aData));
  471. for i := low(aData) to high(aData) do
  472. arr[i] := aData[i];
  473. (fEnumerator as TIntArrayEnumerator).Data := arr;
  474. end;
  475. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  476. procedure TutlArrayEnumeratorTests.SetUp;
  477. begin
  478. fEnumerator := TIntArrayEnumerator.Create;
  479. end;
  480. initialization
  481. RegisterTest(TutlArrayEnumeratorTests.Suite);
  482. end.