1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.juneau.commons.collections;
18
19 import static org.apache.juneau.commons.utils.CollectionUtils.*;
20 import static org.apache.juneau.junit.bct.BctAssertions.*;
21 import static org.junit.jupiter.api.Assertions.*;
22
23 import org.apache.juneau.*;
24 import org.junit.jupiter.api.*;
25
26 class ControlledArrayList_Test extends TestBase {
27
28 @Nested
29 class A_ConstructorTests extends TestBase {
30
31 @Test
32 void a01_emptyModifiable() {
33 var x = new ControlledArrayList<>(false);
34 assertTrue(x.isModifiable());
35 assertEmpty(x);
36 }
37
38 @Test
39 void a02_emptyUnmodifiable() {
40 var x = new ControlledArrayList<>(true);
41 assertFalse(x.isModifiable());
42 assertEmpty(x);
43 }
44
45 @Test
46 void a03_withInitialListModifiable() {
47 var x = new ControlledArrayList<>(false, l(1, 2, 3));
48 assertTrue(x.isModifiable());
49 assertList(x, 1, 2, 3);
50 }
51
52 @Test
53 void a04_withInitialListUnmodifiable() {
54 var x = new ControlledArrayList<>(true, l(1, 2, 3));
55 assertFalse(x.isModifiable());
56 assertList(x, 1, 2, 3);
57 }
58
59 @Test
60 void a05_withEmptyList() {
61 var x1 = new ControlledArrayList<>(false, l());
62 var x2 = new ControlledArrayList<>(true, l());
63 assertTrue(x1.isModifiable());
64 assertFalse(x2.isModifiable());
65 assertEmpty(x1);
66 assertEmpty(x2);
67 }
68 }
69
70 @Nested
71 class B_ModificationTests extends TestBase {
72
73 @Test
74 void b01_set() {
75 var x1 = new ControlledArrayList<>(false, l(1, 2, 3));
76 var x2 = new ControlledArrayList<>(true, l(1, 2, 3));
77
78 assertEquals(2, x1.set(1, 99));
79 assertThrows(UnsupportedOperationException.class, () -> x2.set(1, 99));
80 x2.overrideSet(1, 99);
81 assertList(x1, 1, 99, 3);
82 assertList(x2, 1, 99, 3);
83 }
84
85 @Test
86 void b02_add() {
87 var x1 = new ControlledArrayList<>(false, l(1, 2));
88 var x2 = new ControlledArrayList<>(true, l(1, 2));
89
90 assertTrue(x1.add(3));
91 assertThrows(UnsupportedOperationException.class, () -> x2.add(3));
92 x2.overrideAdd(3);
93 assertList(x1, 1, 2, 3);
94 assertList(x2, 1, 2, 3);
95 }
96
97 @Test
98 void b03_addAtIndex() {
99 var x1 = new ControlledArrayList<>(false, l(1, 3));
100 var x2 = new ControlledArrayList<>(true, l(1, 3));
101
102 x1.add(1, 2);
103 assertThrows(UnsupportedOperationException.class, () -> x2.add(1, 2));
104 x2.overrideAdd(1, 2);
105 assertList(x1, 1, 2, 3);
106 assertList(x2, 1, 2, 3);
107 }
108
109 @Test
110 void b04_addAll() {
111 var x1 = new ControlledArrayList<>(false, l(1));
112 var x2 = new ControlledArrayList<>(true, l(1));
113
114 assertTrue(x1.addAll(l(2, 3)));
115 assertThrows(UnsupportedOperationException.class, () -> x2.addAll(l(2, 3)));
116 x2.overrideAddAll(l(2, 3));
117 assertList(x1, 1, 2, 3);
118 assertList(x2, 1, 2, 3);
119 }
120
121 @Test
122 void b05_addAllAtIndex() {
123 var x1 = new ControlledArrayList<>(false, l(1, 4));
124 var x2 = new ControlledArrayList<>(true, l(1, 4));
125
126 assertTrue(x1.addAll(1, l(2, 3)));
127 assertThrows(UnsupportedOperationException.class, () -> x2.addAll(1, l(2, 3)));
128 x2.overrideAddAll(1, l(2, 3));
129 assertList(x1, 1, 2, 3, 4);
130 assertList(x2, 1, 2, 3, 4);
131 }
132
133 @Test
134 void b06_removeByIndex() {
135 var x1 = new ControlledArrayList<>(false, l(1, 2, 3));
136 var x2 = new ControlledArrayList<>(true, l(1, 2, 3));
137
138 assertEquals(2, x1.remove(1));
139 assertThrows(UnsupportedOperationException.class, () -> x2.remove(1));
140 x2.overrideRemove(1);
141 assertList(x1, 1, 3);
142 assertList(x2, 1, 3);
143 }
144
145 @Test
146 void b07_removeByObject() {
147 var x1 = new ControlledArrayList<>(false, l(1, 2, 3));
148 var x2 = new ControlledArrayList<>(true, l(1, 2, 3));
149
150 assertTrue(x1.remove((Integer)2));
151 assertThrows(UnsupportedOperationException.class, () -> x2.remove((Integer)2));
152 x2.overrideRemove((Integer)2);
153 assertList(x1, 1, 3);
154 assertList(x2, 1, 3);
155 }
156
157 @Test
158 void b08_removeAll() {
159 var x1 = new ControlledArrayList<>(false, l(1, 2, 3, 4));
160 var x2 = new ControlledArrayList<>(true, l(1, 2, 3, 4));
161
162 assertTrue(x1.removeAll(l(2, 4)));
163 assertThrows(UnsupportedOperationException.class, () -> x2.removeAll(l(2, 4)));
164 x2.overrideRemoveAll(l(2, 4));
165 assertList(x1, 1, 3);
166 assertList(x2, 1, 3);
167 }
168
169 @Test
170 void b09_retainAll() {
171 var x1 = new ControlledArrayList<>(false, l(1, 2, 3, 4));
172 var x2 = new ControlledArrayList<>(true, l(1, 2, 3, 4));
173
174 assertTrue(x1.retainAll(l(2, 4)));
175 assertThrows(UnsupportedOperationException.class, () -> x2.retainAll(l(2, 4)));
176 x2.overrideRetainAll(l(2, 4));
177 assertList(x1, 2, 4);
178 assertList(x2, 2, 4);
179 }
180
181 @Test
182 void b10_clear() {
183 var x1 = new ControlledArrayList<>(false, l(1, 2, 3));
184 var x2 = new ControlledArrayList<>(true, l(1, 2, 3));
185
186 x1.clear();
187 assertThrows(UnsupportedOperationException.class, x2::clear);
188 x2.overrideClear();
189 assertEmpty(x1);
190 assertEmpty(x2);
191 }
192
193 @Test
194 void b11_replaceAll() {
195 var x1 = new ControlledArrayList<>(false, l(1, 2, 3));
196 var x2 = new ControlledArrayList<>(true, l(1, 2, 3));
197
198 x1.replaceAll(x -> x * 2);
199 assertThrows(UnsupportedOperationException.class, () -> x2.replaceAll(x -> x * 2));
200 x2.overrideReplaceAll(x -> x * 2);
201 assertList(x1, 2, 4, 6);
202 assertList(x2, 2, 4, 6);
203 }
204
205 @Test
206 void b12_removeIf() {
207 var x1 = new ControlledArrayList<>(false, l(1, 2, 3, 4));
208 var x2 = new ControlledArrayList<>(true, l(1, 2, 3, 4));
209
210 assertTrue(x1.removeIf(x -> x % 2 == 0));
211 assertThrows(UnsupportedOperationException.class, () -> x2.removeIf(x -> x % 2 == 0));
212 x2.overrideRemoveIf(x -> x % 2 == 0);
213 assertList(x1, 1, 3);
214 assertList(x2, 1, 3);
215 }
216
217 @Test
218 void b13_sort() {
219 var x1 = new ControlledArrayList<>(false, l(3, 1, 4, 2));
220 var x2 = new ControlledArrayList<>(true, l(3, 1, 4, 2));
221
222 x1.sort(null);
223 assertThrows(UnsupportedOperationException.class, () -> x2.sort(null));
224 x2.overrideSort(null);
225 assertList(x1, 1, 2, 3, 4);
226 assertList(x2, 1, 2, 3, 4);
227 }
228
229 @Test
230 void b14_sortWithComparator() {
231 var x1 = new ControlledArrayList<>(false, l(1, 2, 3, 4));
232 var x2 = new ControlledArrayList<>(true, l(1, 2, 3, 4));
233
234 x1.sort((a, b) -> b.compareTo(a));
235 assertThrows(UnsupportedOperationException.class, () -> x2.sort((a, b) -> b.compareTo(a)));
236 x2.overrideSort((a, b) -> b.compareTo(a));
237 assertList(x1, 4, 3, 2, 1);
238 assertList(x2, 4, 3, 2, 1);
239 }
240 }
241
242 @Nested
243 class C_IteratorTests extends TestBase {
244
245 @Test
246 void c01_modifiableIterator() {
247 var x = new ControlledArrayList<>(false, l(1, 2, 3));
248 var it = x.iterator();
249
250 assertTrue(it.hasNext());
251 assertEquals(1, it.next());
252 it.remove();
253 assertList(x, 2, 3);
254
255 assertTrue(it.hasNext());
256 assertEquals(2, it.next());
257 assertTrue(it.hasNext());
258 assertEquals(3, it.next());
259 assertFalse(it.hasNext());
260 }
261
262 @Test
263 void c02_unmodifiableIterator() {
264 var x = new ControlledArrayList<>(true, l(1, 2, 3));
265 var it = x.iterator();
266
267 assertTrue(it.hasNext());
268 assertEquals(1, it.next());
269 assertThrows(UnsupportedOperationException.class, it::remove);
270
271 assertTrue(it.hasNext());
272 assertEquals(2, it.next());
273 assertTrue(it.hasNext());
274 assertEquals(3, it.next());
275 assertFalse(it.hasNext());
276 }
277
278 @Test
279 void c03_iteratorForEachRemaining() {
280 var x1 = new ControlledArrayList<>(false, l(1, 2, 3));
281 var x2 = new ControlledArrayList<>(true, l(1, 2, 3));
282 var list1 = new java.util.ArrayList<Integer>();
283 var list2 = new java.util.ArrayList<Integer>();
284
285 x1.iterator().forEachRemaining(list1::add);
286 x2.iterator().forEachRemaining(list2::add);
287
288 assertList(list1, 1, 2, 3);
289 assertList(list2, 1, 2, 3);
290 }
291
292 @Test
293 void c04_overrideIterator() {
294 var x = new ControlledArrayList<>(true, l(1, 2, 3));
295 var it = x.overrideIterator();
296
297 assertTrue(it.hasNext());
298 assertEquals(1, it.next());
299
300
301
302 var list = new java.util.ArrayList<Integer>();
303 it.forEachRemaining(list::add);
304 assertList(list, 2, 3);
305 }
306
307 @Test
308 void c05_emptyIterator() {
309 var x1 = new ControlledArrayList<>(false);
310 var x2 = new ControlledArrayList<>(true);
311
312 assertFalse(x1.iterator().hasNext());
313 assertFalse(x2.iterator().hasNext());
314 }
315 }
316
317 @Nested
318 class D_ListIteratorTests extends TestBase {
319
320 @Test
321 void d01_modifiableListIterator() {
322 var x = new ControlledArrayList<>(false, l(1, 2, 3));
323 var it = x.listIterator();
324
325 assertTrue(it.hasNext());
326 assertFalse(it.hasPrevious());
327 assertEquals(0, it.nextIndex());
328 assertEquals(-1, it.previousIndex());
329
330 assertEquals(1, it.next());
331 assertTrue(it.hasPrevious());
332 assertEquals(1, it.nextIndex());
333 assertEquals(0, it.previousIndex());
334
335 it.set(99);
336 assertList(x, 99, 2, 3);
337
338 it.add(100);
339 assertList(x, 99, 100, 2, 3);
340
341 assertEquals(2, it.nextIndex());
342 assertEquals(1, it.previousIndex());
343 }
344
345 @Test
346 void d02_unmodifiableListIterator() {
347 var x = new ControlledArrayList<>(true, l(1, 2, 3));
348 var it = x.listIterator();
349
350 assertTrue(it.hasNext());
351 assertFalse(it.hasPrevious());
352 assertEquals(0, it.nextIndex());
353 assertEquals(-1, it.previousIndex());
354
355 assertEquals(1, it.next());
356 assertTrue(it.hasPrevious());
357 assertEquals(1, it.nextIndex());
358 assertEquals(0, it.previousIndex());
359
360 assertThrows(UnsupportedOperationException.class, () -> it.set(99));
361 assertThrows(UnsupportedOperationException.class, () -> it.add(100));
362 assertThrows(UnsupportedOperationException.class, it::remove);
363 }
364
365 @Test
366 void d03_listIteratorWithIndex() {
367 var x = new ControlledArrayList<>(false, l(1, 2, 3, 4));
368 var it = x.listIterator(2);
369
370 assertTrue(it.hasNext());
371 assertTrue(it.hasPrevious());
372 assertEquals(2, it.nextIndex());
373 assertEquals(1, it.previousIndex());
374
375 assertEquals(3, it.next());
376 assertEquals(2, it.previousIndex());
377 assertEquals(3, it.previous());
378 assertEquals(1, it.previousIndex());
379 }
380
381 @Test
382 void d04_listIteratorWithIndexUnmodifiable() {
383 var x = new ControlledArrayList<>(true, l(1, 2, 3, 4));
384 var it = x.listIterator(2);
385
386 assertTrue(it.hasNext());
387 assertTrue(it.hasPrevious());
388 assertEquals(2, it.nextIndex());
389 assertEquals(1, it.previousIndex());
390
391 assertEquals(3, it.next());
392 assertThrows(UnsupportedOperationException.class, () -> it.set(99));
393 assertThrows(UnsupportedOperationException.class, () -> it.add(100));
394 assertThrows(UnsupportedOperationException.class, it::remove);
395 }
396
397 @Test
398 void d05_listIteratorForEachRemaining() {
399 var x1 = new ControlledArrayList<>(false, l(1, 2, 3));
400 var x2 = new ControlledArrayList<>(true, l(1, 2, 3));
401 var list1 = new java.util.ArrayList<Integer>();
402 var list2 = new java.util.ArrayList<Integer>();
403
404 x1.listIterator().forEachRemaining(list1::add);
405 x2.listIterator().forEachRemaining(list2::add);
406
407 assertList(list1, 1, 2, 3);
408 assertList(list2, 1, 2, 3);
409 }
410
411 @Test
412 void d06_overrideListIterator() {
413 var x = new ControlledArrayList<>(true, l(1, 2, 3));
414 var it = x.overrideListIterator(1);
415
416 assertTrue(it.hasNext());
417 assertEquals(2, it.next());
418
419
420
421 assertTrue(it.hasPrevious());
422 assertEquals(1, it.previousIndex());
423 assertEquals(2, it.nextIndex());
424 }
425
426 @Test
427 void d07_listIteratorBidirectional() {
428 var x = new ControlledArrayList<>(false, l(1, 2, 3));
429 var it = x.listIterator();
430
431 assertEquals(1, it.next());
432 assertEquals(2, it.next());
433 assertEquals(2, it.previous());
434 assertEquals(1, it.previous());
435 assertFalse(it.hasPrevious());
436 }
437
438 @Test
439 void d08_listIteratorWithIndex_previous() {
440 var x1 = new ControlledArrayList<>(false, l(1, 2, 3, 4));
441 var x2 = new ControlledArrayList<>(true, l(1, 2, 3, 4));
442
443
444 var it1 = x1.listIterator(2);
445 assertTrue(it1.hasPrevious());
446 assertEquals(1, it1.previousIndex());
447 assertEquals(2, it1.previous());
448 assertEquals(0, it1.previousIndex());
449 assertEquals(1, it1.previous());
450 assertFalse(it1.hasPrevious());
451
452
453 var it2 = x2.listIterator(2);
454 assertTrue(it2.hasPrevious());
455 assertEquals(1, it2.previousIndex());
456 assertEquals(2, it2.previous());
457 assertEquals(0, it2.previousIndex());
458 assertEquals(1, it2.previous());
459 assertFalse(it2.hasPrevious());
460 }
461
462 @Test
463 void d09_listIteratorWithIndex_previousFromEnd() {
464 var x1 = new ControlledArrayList<>(false, l(1, 2, 3));
465 var x2 = new ControlledArrayList<>(true, l(1, 2, 3));
466
467
468 var it1 = x1.listIterator(3);
469 assertFalse(it1.hasNext());
470 assertTrue(it1.hasPrevious());
471 assertEquals(2, it1.previousIndex());
472 assertEquals(3, it1.previous());
473 assertEquals(2, it1.previous());
474 assertEquals(1, it1.previous());
475 assertFalse(it1.hasPrevious());
476
477
478 var it2 = x2.listIterator(3);
479 assertFalse(it2.hasNext());
480 assertTrue(it2.hasPrevious());
481 assertEquals(2, it2.previousIndex());
482 assertEquals(3, it2.previous());
483 assertEquals(2, it2.previous());
484 assertEquals(1, it2.previous());
485 assertFalse(it2.hasPrevious());
486 }
487
488 @Test
489 void d10_listIteratorWithIndex_previousBidirectional() {
490 var x1 = new ControlledArrayList<>(false, l(1, 2, 3, 4));
491 var x2 = new ControlledArrayList<>(true, l(1, 2, 3, 4));
492
493
494 var it1 = x1.listIterator(2);
495 assertEquals(3, it1.next());
496 assertEquals(3, it1.previous());
497 assertEquals(2, it1.previous());
498 assertEquals(2, it1.next());
499 assertEquals(3, it1.next());
500
501
502 var it2 = x2.listIterator(2);
503 assertEquals(3, it2.next());
504 assertEquals(3, it2.previous());
505 assertEquals(2, it2.previous());
506 assertEquals(2, it2.next());
507 assertEquals(3, it2.next());
508 }
509 }
510
511 @Nested
512 class E_SubListTests extends TestBase {
513
514 @Test
515 void e01_subListModifiable() {
516 var x = new ControlledArrayList<>(false, l(1, 2, 3, 4, 5));
517 var sub = (ControlledArrayList<Integer>) x.subList(1, 4);
518
519 assertTrue(sub.isModifiable());
520 assertList(sub, 2, 3, 4);
521
522
523
524 sub.set(0, 99);
525 assertEquals(99, sub.get(0));
526 assertList(sub, 99, 3, 4);
527
528 assertList(x, 1, 2, 3, 4, 5);
529 }
530
531 @Test
532 void e02_subListUnmodifiable() {
533 var x = new ControlledArrayList<>(true, l(1, 2, 3, 4, 5));
534 var sub = (ControlledArrayList<Integer>) x.subList(1, 4);
535
536 assertFalse(sub.isModifiable());
537 assertList(sub, 2, 3, 4);
538
539 assertThrows(UnsupportedOperationException.class, () -> sub.set(0, 99));
540 }
541
542 @Test
543 void e03_subListEmpty() {
544 var x1 = new ControlledArrayList<>(false, l(1, 2, 3));
545 var x2 = new ControlledArrayList<>(true, l(1, 2, 3));
546
547 var sub1 = (ControlledArrayList<Integer>) x1.subList(1, 1);
548 var sub2 = (ControlledArrayList<Integer>) x2.subList(1, 1);
549
550 assertTrue(sub1.isModifiable());
551 assertFalse(sub2.isModifiable());
552 assertEmpty(sub1);
553 assertEmpty(sub2);
554 }
555
556 @Test
557 void e04_subListFullRange() {
558 var x1 = new ControlledArrayList<>(false, l(1, 2, 3));
559 var x2 = new ControlledArrayList<>(true, l(1, 2, 3));
560
561 var sub1 = (ControlledArrayList<Integer>) x1.subList(0, 3);
562 var sub2 = (ControlledArrayList<Integer>) x2.subList(0, 3);
563
564 assertTrue(sub1.isModifiable());
565 assertFalse(sub2.isModifiable());
566 assertList(sub1, 1, 2, 3);
567 assertList(sub2, 1, 2, 3);
568 }
569 }
570
571 @Nested
572 class F_SetUnmodifiableTests extends TestBase {
573
574 @Test
575 void f01_setUnmodifiable() {
576 var x = new ControlledArrayList<>(false, l(1, 2, 3));
577
578 assertTrue(x.isModifiable());
579 x.set(0, 99);
580
581 var result = x.setUnmodifiable();
582 assertSame(x, result);
583 assertFalse(x.isModifiable());
584
585 assertThrows(UnsupportedOperationException.class, () -> x.set(0, 100));
586 assertThrows(UnsupportedOperationException.class, () -> x.add(4));
587 assertThrows(UnsupportedOperationException.class, () -> x.remove(0));
588 }
589
590 @Test
591 void f02_setUnmodifiableAlreadyUnmodifiable() {
592 var x = new ControlledArrayList<>(true, l(1, 2, 3));
593
594 assertFalse(x.isModifiable());
595 x.setUnmodifiable();
596 assertFalse(x.isModifiable());
597 }
598 }
599
600 @Nested
601 class G_EdgeCaseTests extends TestBase {
602
603 @Test
604 void g01_emptyListOperations() {
605 var x1 = new ControlledArrayList<>(false);
606 var x2 = new ControlledArrayList<>(true);
607
608 assertFalse(x1.addAll(l()));
609 assertThrows(UnsupportedOperationException.class, () -> x2.addAll(l()));
610
611 assertFalse(x1.removeAll(l()));
612 assertThrows(UnsupportedOperationException.class, () -> x2.removeAll(l()));
613
614 assertFalse(x1.retainAll(l()));
615 assertThrows(UnsupportedOperationException.class, () -> x2.retainAll(l()));
616
617 assertFalse(x1.remove((Integer)1));
618 assertThrows(UnsupportedOperationException.class, () -> x2.remove((Integer)1));
619 }
620
621 @Test
622 void g02_singleElementList() {
623 var x1 = new ControlledArrayList<>(false, l(42));
624 var x2 = new ControlledArrayList<>(true, l(42));
625
626 assertEquals(42, x1.get(0));
627 assertEquals(42, x2.get(0));
628
629 x1.set(0, 99);
630 assertThrows(UnsupportedOperationException.class, () -> x2.set(0, 99));
631 x2.overrideSet(0, 99);
632
633 assertEquals(99, x1.remove(0));
634 assertThrows(UnsupportedOperationException.class, () -> x2.remove(0));
635 x2.overrideRemove(0);
636
637 assertEmpty(x1);
638 assertEmpty(x2);
639 }
640
641 @Test
642 void g03_overrideMethodsWorkWhenUnmodifiable() {
643 var x = new ControlledArrayList<>(true, l(1, 2, 3));
644
645 x.overrideAdd(4);
646 x.overrideAdd(0, 0);
647 x.overrideSet(2, 99);
648 x.overrideRemove(3);
649 x.overrideRemove((Integer)1);
650 x.overrideAddAll(l(5, 6));
651 x.overrideAddAll(0, l(-1));
652 x.overrideRemoveAll(l(0));
653 x.overrideRetainAll(l(2, 99, 5, 6));
654 x.overrideReplaceAll(a -> a * 2);
655 x.overrideRemoveIf(a -> a == 4);
656 x.overrideSort(null);
657 x.overrideClear();
658
659 assertEmpty(x);
660 }
661
662 @Test
663 void g04_isModifiable() {
664 var x1 = new ControlledArrayList<>(false);
665 var x2 = new ControlledArrayList<>(true);
666
667 assertTrue(x1.isModifiable());
668 assertFalse(x2.isModifiable());
669
670 x1.setUnmodifiable();
671 assertFalse(x1.isModifiable());
672 }
673 }
674 }