diff options
Diffstat (limited to 'subprojects/store-query/src/test/java/tools/refinery/store/query/utils/OrderStatisticTreeTest.java')
-rw-r--r-- | subprojects/store-query/src/test/java/tools/refinery/store/query/utils/OrderStatisticTreeTest.java | 634 |
1 files changed, 634 insertions, 0 deletions
diff --git a/subprojects/store-query/src/test/java/tools/refinery/store/query/utils/OrderStatisticTreeTest.java b/subprojects/store-query/src/test/java/tools/refinery/store/query/utils/OrderStatisticTreeTest.java new file mode 100644 index 00000000..cbb48603 --- /dev/null +++ b/subprojects/store-query/src/test/java/tools/refinery/store/query/utils/OrderStatisticTreeTest.java | |||
@@ -0,0 +1,634 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2021 Rodion Efremov | ||
3 | * Copyright (c) 2023 The Refinery Authors <https://refinery.tools/> | ||
4 | * | ||
5 | * SPDX-License-Identifier: MIT OR EPL-2.0 | ||
6 | */ | ||
7 | package tools.refinery.store.query.utils; | ||
8 | |||
9 | import org.junit.jupiter.api.BeforeEach; | ||
10 | import org.junit.jupiter.api.Test; | ||
11 | import org.junit.jupiter.params.ParameterizedTest; | ||
12 | import org.junit.jupiter.params.provider.Arguments; | ||
13 | import org.junit.jupiter.params.provider.MethodSource; | ||
14 | |||
15 | import java.util.*; | ||
16 | import java.util.stream.Stream; | ||
17 | |||
18 | import static org.junit.jupiter.api.Assertions.*; | ||
19 | |||
20 | /** | ||
21 | * Tests for an order statistic tree which is based on AVL-trees. | ||
22 | * <p> | ||
23 | * This class was copied into <i>Refinery</i> from | ||
24 | * <a href="https://github.com/coderodde/OrderStatisticTree/tree/546c343b9f5d868e394a079ff32691c9dbfd83e3">https://github.com/coderodde/OrderStatisticTree</a> | ||
25 | * and is available under the | ||
26 | * <a href="https://github.com/coderodde/OrderStatisticTree/blob/master/LICENSE">MIT License</a>. | ||
27 | * We also migrated the code to Junit 5, cleaned up some linter warnings, and made the tests deterministic by fixing | ||
28 | * the random seeds. | ||
29 | * | ||
30 | * @author Rodion "rodde" Efremov | ||
31 | * @version based on 1.6 (Feb 11, 2016) | ||
32 | */ | ||
33 | class OrderStatisticTreeTest { | ||
34 | private final OrderStatisticTree<Integer> tree = new OrderStatisticTree<>(); | ||
35 | |||
36 | private final TreeSet<Integer> set = new TreeSet<>(); | ||
37 | |||
38 | @BeforeEach | ||
39 | void before() { | ||
40 | tree.clear(); | ||
41 | set.clear(); | ||
42 | } | ||
43 | |||
44 | @Test | ||
45 | void testAdd() { | ||
46 | assertEquals(set.isEmpty(), tree.isEmpty()); | ||
47 | |||
48 | for (int i = 10; i < 30; i += 2) { | ||
49 | assertTrue(tree.isHealthy()); | ||
50 | assertEquals(set.contains(i), tree.contains(i)); | ||
51 | assertEquals(set.add(i), tree.add(i)); | ||
52 | assertEquals(set.add(i), tree.add(i)); | ||
53 | assertEquals(set.contains(i), tree.contains(i)); | ||
54 | assertTrue(tree.isHealthy()); | ||
55 | } | ||
56 | |||
57 | assertEquals(set.isEmpty(), tree.isEmpty()); | ||
58 | } | ||
59 | |||
60 | @Test | ||
61 | void testAddAll() { | ||
62 | for (int i = 0; i < 10; ++i) { | ||
63 | assertEquals(set.add(i), tree.add(i)); | ||
64 | } | ||
65 | |||
66 | Collection<Integer> coll = Arrays.asList(10, 9, 7, 11, 12); | ||
67 | |||
68 | assertEquals(set.addAll(coll), tree.addAll(coll)); | ||
69 | assertEquals(set.size(), tree.size()); | ||
70 | |||
71 | for (int i = -10; i < 20; ++i) { | ||
72 | assertEquals(set.contains(i), tree.contains(i)); | ||
73 | } | ||
74 | } | ||
75 | |||
76 | @Test | ||
77 | void testClear() { | ||
78 | for (int i = 0; i < 2000; ++i) { | ||
79 | set.add(i); | ||
80 | tree.add(i); | ||
81 | } | ||
82 | |||
83 | assertEquals(set.size(), tree.size()); | ||
84 | set.clear(); | ||
85 | tree.clear(); | ||
86 | // We expect {@code tree.size()} to always be 0, but we also test for it. | ||
87 | //noinspection ConstantValue | ||
88 | assertEquals(0, tree.size()); | ||
89 | } | ||
90 | |||
91 | @Test | ||
92 | void testContains() { | ||
93 | for (int i = 100; i < 200; i += 3) { | ||
94 | assertTrue(tree.isHealthy()); | ||
95 | assertEquals(set.add(i), tree.add(i)); | ||
96 | assertTrue(tree.isHealthy()); | ||
97 | } | ||
98 | |||
99 | assertEquals(set.size(), tree.size()); | ||
100 | |||
101 | for (int i = 0; i < 300; ++i) { | ||
102 | assertEquals(set.contains(i), tree.contains(i)); | ||
103 | } | ||
104 | } | ||
105 | |||
106 | @Test | ||
107 | void testContainsAll() { | ||
108 | for (int i = 0; i < 50; ++i) { | ||
109 | set.add(i); | ||
110 | tree.add(i); | ||
111 | } | ||
112 | |||
113 | Collection<Integer> coll = new HashSet<>(); | ||
114 | |||
115 | for (int i = 10; i < 20; ++i) { | ||
116 | coll.add(i); | ||
117 | } | ||
118 | |||
119 | assertEquals(set.containsAll(coll), tree.containsAll(coll)); | ||
120 | coll.add(100); | ||
121 | assertEquals(set.containsAll(coll), tree.containsAll(coll)); | ||
122 | } | ||
123 | |||
124 | @Test | ||
125 | void testRemove() { | ||
126 | for (int i = 0; i < 200; ++i) { | ||
127 | assertEquals(set.add(i), tree.add(i)); | ||
128 | } | ||
129 | |||
130 | for (int i = 50; i < 150; i += 2) { | ||
131 | assertEquals(set.remove(i), tree.remove(i)); | ||
132 | assertTrue(tree.isHealthy()); | ||
133 | } | ||
134 | |||
135 | for (int i = -100; i < 300; ++i) { | ||
136 | assertEquals(set.contains(i), tree.contains(i)); | ||
137 | } | ||
138 | } | ||
139 | |||
140 | @Test | ||
141 | void testRemoveLast() { | ||
142 | tree.add(1); | ||
143 | tree.remove(1); | ||
144 | assertEquals(0, tree.size()); | ||
145 | } | ||
146 | |||
147 | @Test | ||
148 | void testRemoveAll() { | ||
149 | for (int i = 0; i < 40; ++i) { | ||
150 | set.add(i); | ||
151 | tree.add(i); | ||
152 | } | ||
153 | |||
154 | Collection<Integer> coll = new HashSet<>(); | ||
155 | |||
156 | for (int i = 10; i < 20; ++i) { | ||
157 | coll.add(i); | ||
158 | } | ||
159 | |||
160 | assertEquals(set.removeAll(coll), tree.removeAll(coll)); | ||
161 | |||
162 | for (int i = -10; i < 50; ++i) { | ||
163 | assertEquals(set.contains(i), tree.contains(i)); | ||
164 | } | ||
165 | |||
166 | assertEquals(set.removeAll(coll), tree.removeAll(coll)); | ||
167 | |||
168 | for (int i = -10; i < 50; ++i) { | ||
169 | assertEquals(set.contains(i), tree.contains(i)); | ||
170 | } | ||
171 | } | ||
172 | |||
173 | @Test | ||
174 | void testSize() { | ||
175 | for (int i = 0; i < 200; ++i) { | ||
176 | assertEquals(set.size(), tree.size()); | ||
177 | assertEquals(set.add(i), tree.add(i)); | ||
178 | assertEquals(set.size(), tree.size()); | ||
179 | } | ||
180 | } | ||
181 | |||
182 | @Test | ||
183 | void testIndexOf() { | ||
184 | for (int i = 0; i < 100; ++i) { | ||
185 | assertTrue(tree.add(i * 2)); | ||
186 | } | ||
187 | |||
188 | for (int i = 0; i < 100; ++i) { | ||
189 | assertEquals(i, tree.indexOf(2 * i)); | ||
190 | } | ||
191 | |||
192 | for (int i = 100; i < 150; ++i) { | ||
193 | assertEquals(-1, tree.indexOf(2 * i)); | ||
194 | } | ||
195 | } | ||
196 | |||
197 | @Test | ||
198 | void testEmpty() { | ||
199 | assertEquals(set.isEmpty(), tree.isEmpty()); | ||
200 | set.add(0); | ||
201 | tree.add(0); | ||
202 | assertEquals(set.isEmpty(), tree.isEmpty()); | ||
203 | } | ||
204 | |||
205 | @Test | ||
206 | void testEmptyTreeGetThrowsOnNegativeIndex() { | ||
207 | assertThrows(IndexOutOfBoundsException.class, () -> tree.get(-1)); | ||
208 | } | ||
209 | |||
210 | @Test | ||
211 | void testEmptyTreeSelectThrowsOnTooLargeIndex() { | ||
212 | assertThrows(IndexOutOfBoundsException.class, () -> tree.get(0)); | ||
213 | } | ||
214 | |||
215 | @Test | ||
216 | void testSelectThrowsOnNegativeIndex() { | ||
217 | for (int i = 0; i < 5; ++i) { | ||
218 | tree.add(i); | ||
219 | } | ||
220 | |||
221 | assertThrows(IndexOutOfBoundsException.class, () -> tree.get(-1)); | ||
222 | } | ||
223 | |||
224 | @Test | ||
225 | void testSelectThrowsOnTooLargeIndex() { | ||
226 | for (int i = 0; i < 5; ++i) { | ||
227 | tree.add(i); | ||
228 | } | ||
229 | |||
230 | assertThrows(IndexOutOfBoundsException.class, () -> tree.get(5)); | ||
231 | } | ||
232 | |||
233 | @Test | ||
234 | void testGet() { | ||
235 | for (int i = 0; i < 100; i += 3) { | ||
236 | tree.add(i); | ||
237 | } | ||
238 | |||
239 | for (int i = 0; i < tree.size(); ++i) { | ||
240 | assertEquals(Integer.valueOf(3 * i), tree.get(i)); | ||
241 | } | ||
242 | } | ||
243 | |||
244 | @Test | ||
245 | void findBug() { | ||
246 | tree.add(0); | ||
247 | assertTrue(tree.isHealthy()); | ||
248 | |||
249 | tree.add(-1); | ||
250 | tree.remove(-1); | ||
251 | assertTrue(tree.isHealthy()); | ||
252 | |||
253 | tree.add(1); | ||
254 | tree.remove(1); | ||
255 | assertTrue(tree.isHealthy()); | ||
256 | |||
257 | tree.add(-1); | ||
258 | tree.add(1); | ||
259 | tree.remove(0); | ||
260 | assertTrue(tree.isHealthy()); | ||
261 | |||
262 | tree.clear(); | ||
263 | tree.add(0); | ||
264 | tree.add(-1); | ||
265 | tree.add(10); | ||
266 | tree.add(5); | ||
267 | tree.add(15); | ||
268 | tree.add(11); | ||
269 | tree.add(30); | ||
270 | tree.add(7); | ||
271 | |||
272 | tree.remove(-1); | ||
273 | |||
274 | assertTrue(tree.isHealthy()); | ||
275 | } | ||
276 | |||
277 | @ParameterizedTest(name = "seed = {0}") | ||
278 | @MethodSource("seedSource") | ||
279 | void tryReproduceTheCounterBug(long seed) { | ||
280 | Random random = new Random(seed); | ||
281 | List<Integer> list = new ArrayList<>(); | ||
282 | |||
283 | for (int i = 0; i < 10; ++i) { | ||
284 | int number = random.nextInt(1000); | ||
285 | list.add(number); | ||
286 | tree.add(number); | ||
287 | assertTrue(tree.isHealthy()); | ||
288 | } | ||
289 | |||
290 | for (Integer i : list) { | ||
291 | tree.remove(i); | ||
292 | boolean healthy = tree.isHealthy(); | ||
293 | assertTrue(healthy); | ||
294 | } | ||
295 | } | ||
296 | |||
297 | @Test | ||
298 | void testEmptyIterator() { | ||
299 | var iterator = tree.iterator(); | ||
300 | assertThrows(NoSuchElementException.class, iterator::next); | ||
301 | } | ||
302 | |||
303 | @Test | ||
304 | void testIteratorThrowsOnDoubleRemove() { | ||
305 | for (int i = 10; i < 20; ++i) { | ||
306 | set.add(i); | ||
307 | tree.add(i); | ||
308 | } | ||
309 | |||
310 | Iterator<Integer> iterator1 = set.iterator(); | ||
311 | Iterator<Integer> iterator2 = tree.iterator(); | ||
312 | |||
313 | for (int i = 0; i < 3; ++i) { | ||
314 | assertEquals(iterator1.next(), iterator2.next()); | ||
315 | } | ||
316 | |||
317 | iterator1.remove(); | ||
318 | iterator2.remove(); | ||
319 | |||
320 | assertThrows(IllegalStateException.class, iterator1::remove); | ||
321 | assertThrows(IllegalStateException.class, iterator2::remove); | ||
322 | } | ||
323 | |||
324 | @Test | ||
325 | void testIterator() { | ||
326 | for (int i = 0; i < 5; ++i) { | ||
327 | tree.add(i); | ||
328 | set.add(i); | ||
329 | } | ||
330 | |||
331 | Iterator<Integer> iterator1 = set.iterator(); | ||
332 | Iterator<Integer> iterator2 = tree.iterator(); | ||
333 | |||
334 | for (int i = 0; i < 5; ++i) { | ||
335 | assertEquals(iterator1.hasNext(), iterator2.hasNext()); | ||
336 | assertEquals(iterator1.next(), iterator2.next()); | ||
337 | } | ||
338 | |||
339 | assertEquals(iterator1.hasNext(), iterator2.hasNext()); | ||
340 | |||
341 | assertThrows(NoSuchElementException.class, iterator1::next); | ||
342 | assertThrows(NoSuchElementException.class, iterator2::next); | ||
343 | } | ||
344 | |||
345 | @Test | ||
346 | void testRemoveBeforeNextThrowsEmpty() { | ||
347 | var setIterator = set.iterator(); | ||
348 | assertThrows(IllegalStateException.class, setIterator::remove); | ||
349 | |||
350 | var treeIterator = tree.iterator(); | ||
351 | assertThrows(IllegalStateException.class, treeIterator::remove); | ||
352 | } | ||
353 | |||
354 | @Test | ||
355 | void testRemoveThrowsWithoutNext() { | ||
356 | for (int i = 0; i < 10; ++i) { | ||
357 | tree.add(i); | ||
358 | set.add(i); | ||
359 | } | ||
360 | |||
361 | Iterator<Integer> iterator1 = set.iterator(); | ||
362 | Iterator<Integer> iterator2 = tree.iterator(); | ||
363 | |||
364 | for (int i = 0; i < 4; ++i) { | ||
365 | assertEquals(iterator1.hasNext(), iterator2.hasNext()); | ||
366 | assertEquals(iterator1.next(), iterator2.next()); | ||
367 | } | ||
368 | |||
369 | iterator1.remove(); | ||
370 | iterator2.remove(); | ||
371 | |||
372 | assertThrows(IllegalStateException.class, iterator1::remove); | ||
373 | assertThrows(IllegalStateException.class, iterator2::remove); | ||
374 | } | ||
375 | |||
376 | @Test | ||
377 | void testRetainAll() { | ||
378 | for (int i = 0; i < 100; ++i) { | ||
379 | set.add(i); | ||
380 | tree.add(i); | ||
381 | } | ||
382 | |||
383 | Collection<Integer> coll = Arrays.asList(26, 29, 25); | ||
384 | |||
385 | assertEquals(set.retainAll(coll), tree.retainAll(coll)); | ||
386 | assertEquals(set.size(), tree.size()); | ||
387 | |||
388 | assertTrue(set.containsAll(tree)); | ||
389 | assertTrue(tree.containsAll(set)); | ||
390 | } | ||
391 | |||
392 | @Test | ||
393 | void testIteratorRemove() { | ||
394 | for (int i = 10; i < 16; ++i) { | ||
395 | assertEquals(set.add(i), tree.add(i)); | ||
396 | } | ||
397 | |||
398 | Iterator<Integer> iterator1 = set.iterator(); | ||
399 | Iterator<Integer> iterator2 = tree.iterator(); | ||
400 | |||
401 | assertEquals(iterator1.hasNext(), iterator2.hasNext()); | ||
402 | assertEquals(iterator1.next(), iterator2.next()); | ||
403 | |||
404 | assertEquals(iterator1.hasNext(), iterator2.hasNext()); | ||
405 | assertEquals(iterator1.next(), iterator2.next()); | ||
406 | |||
407 | iterator1.remove(); // remove 11 | ||
408 | iterator2.remove(); | ||
409 | |||
410 | assertEquals(iterator1.hasNext(), iterator2.hasNext()); | ||
411 | assertEquals(iterator1.next(), iterator2.next()); | ||
412 | |||
413 | assertEquals(iterator1.hasNext(), iterator2.hasNext()); | ||
414 | assertEquals(iterator1.next(), iterator2.next()); | ||
415 | |||
416 | iterator1.remove(); // remove 13 | ||
417 | iterator2.remove(); | ||
418 | |||
419 | assertEquals(set.size(), tree.size()); | ||
420 | |||
421 | for (int i = 10; i < 16; ++i) { | ||
422 | assertEquals(set.contains(i), tree.contains(i)); | ||
423 | } | ||
424 | } | ||
425 | |||
426 | @ParameterizedTest(name = "seed = {0}") | ||
427 | @MethodSource("seedSource") | ||
428 | void testIteratorBruteForce(long seed) { | ||
429 | for (int i = 0; i < 1000; ++i) { | ||
430 | assertEquals(set.add(i), tree.add(i)); | ||
431 | } | ||
432 | |||
433 | Iterator<Integer> iterator1 = set.iterator(); | ||
434 | Iterator<Integer> iterator2 = tree.iterator(); | ||
435 | |||
436 | Random random = new Random(seed); | ||
437 | |||
438 | while (true) { | ||
439 | if (!iterator1.hasNext()) { | ||
440 | assertFalse(iterator2.hasNext()); | ||
441 | break; | ||
442 | } | ||
443 | |||
444 | boolean toRemove = random.nextBoolean(); | ||
445 | |||
446 | if (toRemove) { | ||
447 | boolean thrown = false; | ||
448 | |||
449 | try { | ||
450 | iterator1.remove(); | ||
451 | } catch (IllegalStateException ex) { | ||
452 | thrown = true; | ||
453 | } | ||
454 | |||
455 | if (thrown) { | ||
456 | assertThrows(IllegalStateException.class, iterator2::remove); | ||
457 | } else { | ||
458 | iterator2.remove(); | ||
459 | } | ||
460 | } else { | ||
461 | assertEquals(iterator1.hasNext(), iterator2.hasNext()); | ||
462 | |||
463 | if (iterator1.hasNext()) { | ||
464 | assertEquals(iterator1.next(), iterator2.next()); | ||
465 | } else { | ||
466 | break; | ||
467 | } | ||
468 | } | ||
469 | } | ||
470 | |||
471 | assertEquals(set.size(), tree.size()); | ||
472 | assertTrue(tree.isHealthy()); | ||
473 | assertTrue(set.containsAll(tree)); | ||
474 | assertTrue(tree.containsAll(set)); | ||
475 | } | ||
476 | |||
477 | @Test | ||
478 | void testIteratorConcurrentModification() { | ||
479 | for (int i = 0; i < 100; ++i) { | ||
480 | set.add(i); | ||
481 | tree.add(i); | ||
482 | } | ||
483 | |||
484 | Iterator<Integer> iterator1 = set.iterator(); | ||
485 | Iterator<Integer> iterator2 = tree.iterator(); | ||
486 | |||
487 | set.remove(10); | ||
488 | tree.remove(10); | ||
489 | |||
490 | assertEquals(iterator1.hasNext(), iterator2.hasNext()); | ||
491 | |||
492 | boolean thrown = false; | ||
493 | |||
494 | try { | ||
495 | iterator1.next(); | ||
496 | } catch (ConcurrentModificationException ex) { | ||
497 | thrown = true; | ||
498 | } | ||
499 | |||
500 | if (thrown) { | ||
501 | assertThrows(ConcurrentModificationException.class, iterator2::next); | ||
502 | } else { | ||
503 | iterator2.next(); | ||
504 | } | ||
505 | } | ||
506 | |||
507 | @Test | ||
508 | void testIteratorConcurrentRemove() { | ||
509 | for (int i = 10; i < 20; ++i) { | ||
510 | set.add(i); | ||
511 | tree.add(i); | ||
512 | } | ||
513 | |||
514 | Iterator<Integer> iterator1 = set.iterator(); | ||
515 | Iterator<Integer> iterator2 = tree.iterator(); | ||
516 | |||
517 | for (int i = 0; i < 4; ++i) { | ||
518 | iterator1.next(); | ||
519 | iterator2.next(); | ||
520 | } | ||
521 | |||
522 | // None of them contains 2, should not change the modification count. | ||
523 | set.remove(2); | ||
524 | tree.remove(2); | ||
525 | |||
526 | iterator1.remove(); | ||
527 | iterator2.remove(); | ||
528 | |||
529 | iterator1.next(); | ||
530 | iterator2.next(); | ||
531 | |||
532 | set.remove(12); | ||
533 | tree.remove(12); | ||
534 | |||
535 | // Both of them should throw. | ||
536 | assertThrows(ConcurrentModificationException.class, iterator1::remove); | ||
537 | assertThrows(ConcurrentModificationException.class, iterator2::remove); | ||
538 | } | ||
539 | |||
540 | @Test | ||
541 | void testConcurrentOrIllegalStateOnRemove() { | ||
542 | for (int i = 0; i < 10; ++i) { | ||
543 | set.add(i); | ||
544 | tree.add(i); | ||
545 | } | ||
546 | |||
547 | Iterator<Integer> iterator1 = set.iterator(); | ||
548 | Iterator<Integer> iterator2 = tree.iterator(); | ||
549 | |||
550 | set.add(100); | ||
551 | tree.add(100); | ||
552 | |||
553 | assertThrows(IllegalStateException.class, iterator1::remove); | ||
554 | assertThrows(IllegalStateException.class, iterator2::remove); | ||
555 | } | ||
556 | |||
557 | @Test | ||
558 | void testConcurrentIterators() { | ||
559 | for (int i = 0; i < 10; ++i) { | ||
560 | set.add(i); | ||
561 | tree.add(i); | ||
562 | } | ||
563 | |||
564 | Iterator<Integer> iterator1a = set.iterator(); | ||
565 | Iterator<Integer> iterator1b = set.iterator(); | ||
566 | Iterator<Integer> iterator2a = tree.iterator(); | ||
567 | Iterator<Integer> iterator2b = tree.iterator(); | ||
568 | |||
569 | for (int i = 0; i < 3; ++i) { | ||
570 | iterator1a.next(); | ||
571 | iterator2a.next(); | ||
572 | } | ||
573 | |||
574 | iterator1a.remove(); | ||
575 | iterator2a.remove(); | ||
576 | |||
577 | assertEquals(iterator1b.hasNext(), iterator2b.hasNext()); | ||
578 | |||
579 | assertThrows(ConcurrentModificationException.class, iterator1b::next); | ||
580 | assertThrows(ConcurrentModificationException.class, iterator2b::next); | ||
581 | } | ||
582 | |||
583 | @ParameterizedTest(name = "seed = {0}") | ||
584 | @MethodSource("seedSource") | ||
585 | void testToArray(long seed) { | ||
586 | Random r = new Random(seed); | ||
587 | |||
588 | for (int i = 0; i < 50; ++i) { | ||
589 | int num = r.nextInt(); | ||
590 | set.add(num); | ||
591 | tree.add(num); | ||
592 | } | ||
593 | |||
594 | assertArrayEquals(set.toArray(), tree.toArray()); | ||
595 | } | ||
596 | |||
597 | @Test | ||
598 | void testToArrayGeneric() { | ||
599 | for (int i = 0; i < 100; ++i) { | ||
600 | set.add(i); | ||
601 | tree.add(i); | ||
602 | } | ||
603 | |||
604 | Integer[] array1before = new Integer[99]; | ||
605 | Integer[] array2before = new Integer[99]; | ||
606 | |||
607 | Integer[] array1after = set.toArray(array1before); | ||
608 | Integer[] array2after = tree.toArray(array2before); | ||
609 | |||
610 | assertNotSame(array1before, array1after); | ||
611 | assertNotSame(array2before, array2after); | ||
612 | assertArrayEquals(array1after, array2after); | ||
613 | |||
614 | set.remove(1); | ||
615 | tree.remove(1); | ||
616 | |||
617 | array1after = set.toArray(array1before); | ||
618 | array2after = tree.toArray(array2before); | ||
619 | |||
620 | assertSame(array1before, array1after); | ||
621 | assertSame(array2before, array2after); | ||
622 | assertArrayEquals(array1after, array2after); | ||
623 | } | ||
624 | |||
625 | static Stream<Arguments> seedSource() { | ||
626 | return Stream.of( | ||
627 | Arguments.of(0L), | ||
628 | Arguments.of(1L), | ||
629 | Arguments.of(2L), | ||
630 | Arguments.of(3L), | ||
631 | Arguments.of(4L) | ||
632 | ); | ||
633 | } | ||
634 | } | ||