1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.collections4.list;
18
19 import static org.junit.jupiter.api.Assertions.assertEquals;
20 import static org.junit.jupiter.api.Assertions.assertFalse;
21 import static org.junit.jupiter.api.Assertions.assertThrows;
22 import static org.junit.jupiter.api.Assertions.assertTrue;
23
24 import java.io.IOException;
25 import java.io.Serializable;
26 import java.lang.reflect.InvocationTargetException;
27 import java.lang.reflect.Method;
28 import java.util.AbstractCollection;
29 import java.util.ArrayList;
30 import java.util.Arrays;
31 import java.util.Collection;
32 import java.util.Collections;
33 import java.util.ConcurrentModificationException;
34 import java.util.Iterator;
35 import java.util.List;
36 import java.util.ListIterator;
37 import java.util.NoSuchElementException;
38
39 import org.apache.commons.collections4.BulkTest;
40 import org.apache.commons.collections4.collection.AbstractCollectionTest;
41 import org.apache.commons.collections4.iterators.AbstractListIteratorTest;
42 import org.apache.commons.lang3.StringUtils;
43 import org.junit.jupiter.api.Test;
44
45
46
47
48
49
50
51
52
53
54
55
56 public abstract class AbstractListTest<E> extends AbstractCollectionTest<E> {
57
58 public static class BulkTestSubList<E> extends AbstractListTest<E> {
59
60 private final AbstractListTest<E> outer;
61
62 public BulkTestSubList(final AbstractListTest<E> outer) {
63 super(StringUtils.EMPTY);
64 this.outer = outer;
65 }
66
67 @Override
68 @SuppressWarnings("unchecked")
69 public E[] getFullElements() {
70 final List<E> l = Arrays.asList(outer.getFullElements());
71 return (E[]) l.subList(3, l.size() - 3).toArray();
72 }
73
74 @Override
75 public E[] getOtherElements() {
76 return outer.getOtherElements();
77 }
78
79 @Override
80 public boolean isAddSupported() {
81 return outer.isAddSupported();
82 }
83
84 @Override
85 public boolean isRemoveSupported() {
86 return outer.isRemoveSupported();
87 }
88
89 @Override
90 public boolean isSetSupported() {
91 return outer.isSetSupported();
92 }
93
94 @Override
95 public boolean isTestSerialization() {
96 return false;
97 }
98
99 @Override
100 public List<E> makeFullCollection() {
101 final int size = getFullElements().length;
102 return outer.makeFullCollection().subList(3, size - 3);
103 }
104
105 @Override
106 public List<E> makeObject() {
107 return outer.makeFullCollection().subList(4, 4);
108 }
109
110 @Override
111 public void resetEmpty() {
112 outer.resetFull();
113 this.setCollection(outer.getCollection().subList(4, 4));
114 this.setConfirmed(outer.getConfirmed().subList(4, 4));
115 }
116
117 @Override
118 public void resetFull() {
119 outer.resetFull();
120 final int size = outer.getConfirmed().size();
121 this.setCollection(outer.getCollection().subList(3, size - 3));
122 this.setConfirmed(outer.getConfirmed().subList(3, size - 3));
123 }
124
125 @Override
126 public void verify() {
127 super.verify();
128 outer.verify();
129 }
130 }
131
132 public class TestListIterator extends AbstractListIteratorTest<E> {
133 public TestListIterator() {
134 super("TestListIterator");
135 }
136
137 @Override
138 public E addSetValue() {
139 return AbstractListTest.this.getOtherElements()[0];
140 }
141
142 @Override
143 public ListIterator<E> makeEmptyIterator() {
144 resetEmpty();
145 return AbstractListTest.this.getCollection().listIterator();
146 }
147
148 @Override
149 public ListIterator<E> makeObject() {
150 resetFull();
151 return AbstractListTest.this.getCollection().listIterator();
152 }
153
154 @Override
155 public boolean supportsAdd() {
156 return AbstractListTest.this.isAddSupported();
157 }
158
159 @Override
160 public boolean supportsRemove() {
161 return AbstractListTest.this.isRemoveSupported();
162 }
163
164 @Override
165 public boolean supportsSet() {
166 return AbstractListTest.this.isSetSupported();
167 }
168 }
169
170
171
172
173
174
175 public AbstractListTest(final String testName) {
176 super(testName);
177 }
178
179
180
181
182
183
184
185 private void backwardTest(final ListIterator<E> iter, int i) {
186 final List<E> list = getCollection();
187
188 while (i > 0) {
189 assertTrue(iter.hasPrevious(),
190 "Iterator should have previous, i:" + i);
191 assertEquals(i, iter.nextIndex(),
192 "Iterator.nextIndex should work, i:" + i);
193 assertEquals(i - 1, iter.previousIndex(),
194 "Iterator.previousIndex should work, i:" + i);
195 final E o = iter.previous();
196 assertEquals(list.get(i - 1), o,
197 "Iterator returned correct element");
198 i--;
199 }
200
201 assertFalse(iter.hasPrevious(), "Iterator shouldn't have previous");
202 final int nextIndex = iter.nextIndex();
203 assertEquals(0, nextIndex, "nextIndex should be 0");
204 final int prevIndex = iter.previousIndex();
205 assertEquals(-1, prevIndex, "previousIndex should be -1");
206
207 assertThrows(NoSuchElementException.class, () -> iter.previous(),
208 "Exhausted iterator should raise NoSuchElement");
209 }
210
211 public BulkTest bulkTestListIterator() {
212 return new TestListIterator();
213 }
214
215
216
217
218
219
220
221
222
223
224
225 public BulkTest bulkTestSubList() {
226 if (getFullElements().length - 6 < 10) {
227 return null;
228 }
229 return new BulkTestSubList<>(this);
230 }
231
232
233
234
235
236 protected void failFastAll(final List<E> list) {
237 final Method[] methods = List.class.getMethods();
238 for (final Method method : methods) {
239 failFastMethod(list, method);
240 }
241 }
242
243
244
245
246
247
248
249
250
251
252
253
254
255 protected void failFastMethod(final List<E> list, final Method m) {
256 if (m.getName().equals("equals")) {
257 return;
258 }
259
260 final E element = getOtherElements()[0];
261 final Collection<E> c = Collections.singleton(element);
262
263 final Class<?>[] types = m.getParameterTypes();
264 final Object[] params = new Object[types.length];
265 for (int i = 0; i < params.length; i++) {
266 if (types[i] == Integer.TYPE) {
267 params[i] = Integer.valueOf(0);
268 } else if (types[i] == Collection.class) {
269 params[i] = c;
270 } else if (types[i] == Object.class) {
271 params[i] = element;
272 } else if (types[i] == Object[].class) {
273 params[i] = new Object[0];
274 }
275 }
276
277 final InvocationTargetException thrown = assertThrows(InvocationTargetException.class, () -> m.invoke(list, params),
278 m.getName() + " should raise ConcurrentModification");
279 assertTrue(thrown.getTargetException() instanceof ConcurrentModificationException,
280 m.getName() + " raised unexpected " + thrown.getTargetException());
281 }
282
283
284
285
286
287
288
289 private void forwardTest(final ListIterator<E> iter, int i) {
290 final List<E> list = getCollection();
291 final int max = getFullElements().length;
292
293 while (i < max) {
294 assertTrue(iter.hasNext(), "Iterator should have next");
295 assertEquals(i, iter.nextIndex(),
296 "Iterator.nextIndex should work");
297 assertEquals(i - 1, iter.previousIndex(),
298 "Iterator.previousIndex should work");
299 final Object o = iter.next();
300 assertEquals(list.get(i), o, "Iterator returned correct element");
301 i++;
302 }
303
304 assertFalse(iter.hasNext(), "Iterator shouldn't have next");
305 assertEquals(max, iter.nextIndex(), "nextIndex should be size");
306 assertEquals(max - 1, iter.previousIndex(), "previousIndex should be size - 1");
307
308 assertThrows(NoSuchElementException.class, () -> iter.next(),
309 "Exhausted iterator should raise NoSuchElement");
310 }
311
312
313
314
315
316
317 @Override
318 public List<E> getCollection() {
319 return (List<E>) super.getCollection();
320 }
321
322
323
324
325
326
327 @Override
328 public List<E> getConfirmed() {
329 return (List<E>) super.getConfirmed();
330 }
331
332
333
334
335 @Override
336 public boolean isEqualsCheckable() {
337 return true;
338 }
339
340
341
342
343
344
345
346
347 public boolean isSetSupported() {
348 return true;
349 }
350
351
352
353
354 @Override
355 public Collection<E> makeConfirmedCollection() {
356 final ArrayList<E> list = new ArrayList<>();
357 return list;
358 }
359
360
361
362
363 @Override
364 public Collection<E> makeConfirmedFullCollection() {
365 return new ArrayList<>(Arrays.asList(getFullElements()));
366 }
367
368
369
370
371 @Override
372 public List<E> makeFullCollection() {
373
374 final List<E> list = makeObject();
375 list.addAll(Arrays.asList(getFullElements()));
376 return list;
377 }
378
379
380
381
382
383
384 @Override
385 public abstract List<E> makeObject();
386
387
388
389
390
391 @Test
392 @SuppressWarnings("unchecked")
393 public void testEmptyListCompatibility() throws IOException, ClassNotFoundException {
394
395
396
397
398
399
400
401
402
403 final List<E> list = makeObject();
404 if (list instanceof Serializable && !skipSerializedCanonicalTests()
405 && isTestSerialization()) {
406 final List<E> list2 = (List<E>) readExternalFormFromDisk(getCanonicalEmptyCollectionName(list));
407 assertEquals(0, list2.size(), "List is empty");
408 assertEquals(list, list2);
409 }
410 }
411
412 @Test
413 @SuppressWarnings("unchecked")
414 public void testEmptyListSerialization() throws IOException, ClassNotFoundException {
415 final List<E> list = makeObject();
416 if (!(list instanceof Serializable && isTestSerialization())) {
417 return;
418 }
419
420 final byte[] object = writeExternalFormToBytes((Serializable) list);
421 final List<E> list2 = (List<E>) readExternalFormFromBytes(object);
422
423 assertEquals(0, list.size(), "Both lists are empty");
424 assertEquals(0, list2.size(), "Both lists are empty");
425 }
426
427
428
429
430
431 @Test
432 @SuppressWarnings("unchecked")
433 public void testFullListCompatibility() throws IOException, ClassNotFoundException {
434
435
436
437
438
439
440
441
442
443 final List<E> list = makeFullCollection();
444 if (list instanceof Serializable && !skipSerializedCanonicalTests() && isTestSerialization()) {
445 final List<E> list2 = (List<E>) readExternalFormFromDisk(getCanonicalFullCollectionName(list));
446 if (list2.size() == 4) {
447
448 return;
449 }
450 assertEquals(list.size(), list2.size(), "List is the right size");
451 assertEquals(list, list2);
452 }
453 }
454
455 @Test
456 @SuppressWarnings("unchecked")
457 public void testFullListSerialization() throws IOException, ClassNotFoundException {
458 final List<E> list = makeFullCollection();
459 final int size = getFullElements().length;
460 if (!(list instanceof Serializable && isTestSerialization())) {
461 return;
462 }
463
464 final byte[] object = writeExternalFormToBytes((Serializable) list);
465 final List<E> list2 = (List<E>) readExternalFormFromBytes(object);
466
467 assertEquals(size, list.size(), "Both lists are same size");
468 assertEquals(size, list2.size(), "Both lists are same size");
469 }
470
471
472
473
474 @Test
475 public void testListAddByIndex() {
476 if (!isAddSupported()) {
477 return;
478 }
479
480 final E element = getOtherElements()[0];
481 final int max = getFullElements().length;
482
483 for (int i = 0; i <= max; i++) {
484 resetFull();
485 getCollection().add(i, element);
486 getConfirmed().add(i, element);
487 verify();
488 }
489 }
490
491
492
493
494
495 @Test
496 public void testListAddByIndexBoundsChecking() {
497 if (!isAddSupported()) {
498 return;
499 }
500
501 final E element = getOtherElements()[0];
502
503 final List<E> finalList0 = makeObject();
504 assertThrows(IndexOutOfBoundsException.class, () -> finalList0.add(Integer.MIN_VALUE, element),
505 "List.add should throw IndexOutOfBoundsException [Integer.MIN_VALUE]");
506
507 final List<E> finalList1 = makeObject();
508 assertThrows(IndexOutOfBoundsException.class, () -> finalList1.add(-1, element),
509 "List.add should throw IndexOutOfBoundsException [-1]");
510
511 final List<E> finalList2 = makeObject();
512 assertThrows(IndexOutOfBoundsException.class, () -> finalList2.add(1, element),
513 "List.add should throw IndexOutOfBoundsException [1]");
514
515 final List<E> finalList3 = makeObject();
516 assertThrows(IndexOutOfBoundsException.class, () -> finalList3.add(Integer.MAX_VALUE, element),
517 "List.add should throw IndexOutOfBoundsException [Integer.MAX_VALUE]");
518 }
519
520
521
522
523
524 @Test
525 public void testListAddByIndexBoundsChecking2() {
526 if (!isAddSupported()) {
527 return;
528 }
529
530 final E element = getOtherElements()[0];
531
532 final List<E> finalList0 = makeFullCollection();
533 assertThrows(IndexOutOfBoundsException.class, () -> finalList0.add(Integer.MIN_VALUE, element),
534 "List.add should throw IndexOutOfBoundsException [Integer.MIN_VALUE]");
535
536 final List<E> finalList1 = makeFullCollection();
537 assertThrows(IndexOutOfBoundsException.class, () -> finalList1.add(-1, element),
538 "List.add should throw IndexOutOfBoundsException [-1]");
539
540 final List<E> finalList2 = makeFullCollection();
541 assertThrows(IndexOutOfBoundsException.class, () -> finalList2.add(finalList2.size() + 1, element),
542 "List.add should throw IndexOutOfBoundsException [size + 1]");
543
544 final List<E> finalList3 = makeFullCollection();
545 assertThrows(IndexOutOfBoundsException.class, () -> finalList3.add(Integer.MAX_VALUE, element),
546 "List.add should throw IndexOutOfBoundsException [Integer.MAX_VALUE]");
547 }
548
549
550
551
552 @Test
553 public void testListEquals() {
554 resetEmpty();
555 List<E> list = getCollection();
556 assertTrue(list.equals(getConfirmed()), "Empty lists should be equal");
557 verify();
558 assertTrue(list.equals(list), "Empty list should equal self");
559 verify();
560
561 List<E> list2 = Arrays.asList(getFullElements());
562 assertFalse(list.equals(list2), "Empty list shouldn't equal full");
563 verify();
564
565 list2 = Arrays.asList(getOtherElements());
566 assertFalse(list.equals(list2), "Empty list shouldn't equal other");
567 verify();
568
569 resetFull();
570 list = getCollection();
571 assertTrue(list.equals(getConfirmed()), "Full lists should be equal");
572 verify();
573 assertTrue(list.equals(list), "Full list should equal self");
574 verify();
575
576 list2 = makeObject();
577 assertFalse(list.equals(list2), "Full list shouldn't equal empty");
578 verify();
579
580 list2 = Arrays.asList(getOtherElements());
581 assertFalse(list.equals(list2), "Full list shouldn't equal other");
582 verify();
583
584 list2 = Arrays.asList(getFullElements());
585 if (list2.size() < 2 && isAddSupported()) {
586
587 list.addAll(Arrays.asList(getOtherElements()));
588 getConfirmed().addAll(Arrays.asList(getOtherElements()));
589 list2 = new ArrayList<>(list2);
590 list2.addAll(Arrays.asList(getOtherElements()));
591 }
592 if (list2.size() > 1) {
593 Collections.reverse(list2);
594 assertFalse(list.equals(list2), "Full list shouldn't equal full list with same elements but different order");
595 verify();
596 }
597
598 resetFull();
599 list = getCollection();
600 assertFalse(list.isEmpty(), "List shouldn't equal String");
601 verify();
602
603 final List<E> listForC = Arrays.asList(getFullElements());
604 final Collection<E> c = new AbstractCollection<E>() {
605 @Override
606 public Iterator<E> iterator() {
607 return listForC.iterator();
608 }
609
610 @Override
611 public int size() {
612 return listForC.size();
613 }
614 };
615
616 assertFalse(list.equals(c), "List shouldn't equal nonlist with same elements in same order");
617 verify();
618 }
619
620
621
622
623 @Test
624 public void testListGetByIndex() {
625 resetFull();
626 final List<E> list = getCollection();
627 final E[] elements = getFullElements();
628 for (int i = 0; i < elements.length; i++) {
629 assertEquals(elements[i], list.get(i), "List should contain correct elements");
630 verify();
631 }
632 }
633
634
635
636
637
638 @Test
639 public void testListGetByIndexBoundsChecking() {
640 final List<E> list = makeObject();
641
642 assertThrows(IndexOutOfBoundsException.class, () -> list.get(Integer.MIN_VALUE),
643 "List.get should throw IndexOutOfBoundsException [Integer.MIN_VALUE]");
644
645 assertThrows(IndexOutOfBoundsException.class, () -> list.get(-1),
646 "List.get should throw IndexOutOfBoundsException [-1]");
647
648 assertThrows(IndexOutOfBoundsException.class, () -> list.get(0),
649 "List.get should throw IndexOutOfBoundsException [0]");
650
651 assertThrows(IndexOutOfBoundsException.class, () -> list.get(1),
652 "List.get should throw IndexOutOfBoundsException [1]");
653
654 assertThrows(IndexOutOfBoundsException.class, () -> list.get(Integer.MAX_VALUE),
655 "List.get should throw IndexOutOfBoundsException [Integer.MAX_VALUE]");
656 }
657
658
659
660
661
662 @Test
663 public void testListGetByIndexBoundsChecking2() {
664 final List<E> list = makeFullCollection();
665
666 assertThrows(IndexOutOfBoundsException.class, () -> list.get(Integer.MIN_VALUE),
667 "List.get should throw IndexOutOfBoundsException [Integer.MIN_VALUE]");
668
669 assertThrows(IndexOutOfBoundsException.class, () -> list.get(-1),
670 "List.get should throw IndexOutOfBoundsException [-1]");
671
672 assertThrows(IndexOutOfBoundsException.class, () -> list.get(getFullElements().length),
673 "List.get should throw IndexOutOfBoundsException [size]");
674
675 assertThrows(IndexOutOfBoundsException.class, () -> list.get(Integer.MAX_VALUE),
676 "List.get should throw IndexOutOfBoundsException [Integer.MAX_VALUE]");
677 }
678
679
680
681
682 @Test
683 public void testListHashCode() {
684 resetEmpty();
685 int hash1 = getCollection().hashCode();
686 int hash2 = getConfirmed().hashCode();
687 assertEquals(hash1, hash2, "Empty lists should have equal hashCodes");
688 verify();
689
690 resetFull();
691 hash1 = getCollection().hashCode();
692 hash2 = getConfirmed().hashCode();
693 assertEquals(hash1, hash2, "Full lists should have equal hashCodes");
694 verify();
695 }
696
697
698
699
700 @Test
701 public void testListIndexOf() {
702 resetFull();
703 final List<E> list1 = getCollection();
704 final List<E> list2 = getConfirmed();
705
706 for (final E element : list2) {
707 assertEquals(list1.indexOf(element),
708 list2.indexOf(element), "indexOf should return correct result");
709 verify();
710 }
711
712 final E[] other = getOtherElements();
713 for (final E element : other) {
714 assertEquals(-1, list1.indexOf(element),
715 "indexOf should return -1 for nonexistent element");
716 verify();
717 }
718 }
719
720
721
722
723
724 @Test
725 public void testListIteratorAdd() {
726 if (!isAddSupported()) {
727 return;
728 }
729
730 resetEmpty();
731 final List<E> list1 = getCollection();
732 final List<E> list2 = getConfirmed();
733
734 final E[] elements = getFullElements();
735 ListIterator<E> iter1 = list1.listIterator();
736 ListIterator<E> iter2 = list2.listIterator();
737
738 for (final E element : elements) {
739 iter1.add(element);
740 iter2.add(element);
741 verify();
742 }
743
744 resetFull();
745 iter1 = getCollection().listIterator();
746 iter2 = getConfirmed().listIterator();
747 for (final E element : elements) {
748 iter1.next();
749 iter2.next();
750 iter1.add(element);
751 iter2.add(element);
752 verify();
753 }
754 }
755
756
757
758
759
760 @Test
761 public void testListIteratorSet() {
762 if (!isSetSupported()) {
763 return;
764 }
765
766 final E[] elements = getFullElements();
767
768 resetFull();
769 final ListIterator<E> iter1 = getCollection().listIterator();
770 final ListIterator<E> iter2 = getConfirmed().listIterator();
771 for (final E element : elements) {
772 iter1.next();
773 iter2.next();
774 iter1.set(element);
775 iter2.set(element);
776 verify();
777 }
778 }
779
780
781
782
783 @Test
784 public void testListLastIndexOf() {
785 resetFull();
786 final List<E> list1 = getCollection();
787 final List<E> list2 = getConfirmed();
788
789 for (final E element : list2) {
790 assertEquals(list1.lastIndexOf(element), list2.lastIndexOf(element),
791 "lastIndexOf should return correct result");
792 verify();
793 }
794
795 final E[] other = getOtherElements();
796 for (final E element : other) {
797 assertEquals(-1, list1.lastIndexOf(element),
798 "lastIndexOf should return -1 for nonexistent " + "element");
799 verify();
800 }
801 }
802
803
804
805
806 @Test
807 public void testListListIterator() {
808 resetFull();
809 forwardTest(getCollection().listIterator(), 0);
810 backwardTest(getCollection().listIterator(), 0);
811 }
812
813
814
815
816 @Test
817 public void testListListIteratorByIndex() {
818 resetFull();
819 try {
820 getCollection().listIterator(-1);
821 } catch (final IndexOutOfBoundsException ex) {}
822 resetFull();
823 try {
824 getCollection().listIterator(getCollection().size() + 1);
825 } catch (final IndexOutOfBoundsException ex) {}
826 resetFull();
827 for (int i = 0; i <= getConfirmed().size(); i++) {
828 forwardTest(getCollection().listIterator(i), i);
829 backwardTest(getCollection().listIterator(i), i);
830 }
831 resetFull();
832 for (int i = 0; i <= getConfirmed().size(); i++) {
833 backwardTest(getCollection().listIterator(i), i);
834 }
835 }
836
837
838
839
840 @Test
841 public void testListListIteratorNextRemoveNext() {
842 if (!isRemoveSupported()) {
843 return;
844 }
845 resetFull();
846 if (getCollection().size() < 4) {
847 return;
848 }
849 final ListIterator<E> it = getCollection().listIterator();
850 final E zero = it.next();
851 final E one = it.next();
852 final E two = it.next();
853 assertEquals(zero, getCollection().get(0));
854 assertEquals(one, getCollection().get(1));
855 assertEquals(two, getCollection().get(2));
856 final E three = getCollection().get(3);
857
858 it.remove();
859 assertEquals(zero, getCollection().get(0));
860 assertEquals(one, getCollection().get(1));
861 final E three2 = it.next();
862 assertEquals(three, three2);
863 assertEquals(getCollection().size() > 3, it.hasNext());
864 assertTrue(it.hasPrevious());
865 }
866
867
868
869
870 @Test
871 public void testListListIteratorNextRemovePrevious() {
872 if (!isRemoveSupported()) {
873 return;
874 }
875 resetFull();
876 if (getCollection().size() < 4) {
877 return;
878 }
879 final ListIterator<E> it = getCollection().listIterator();
880 final E zero = it.next();
881 final E one = it.next();
882 final E two = it.next();
883 assertEquals(zero, getCollection().get(0));
884 assertEquals(one, getCollection().get(1));
885 assertEquals(two, getCollection().get(2));
886
887 it.remove();
888 assertEquals(zero, getCollection().get(0));
889 assertEquals(one, getCollection().get(1));
890 final E one2 = it.previous();
891 assertEquals(one, one2);
892 assertTrue(it.hasNext());
893 assertTrue(it.hasPrevious());
894 }
895
896
897
898
899 @Test
900 public void testListListIteratorPreviousRemoveNext() {
901 if (!isRemoveSupported()) {
902 return;
903 }
904 resetFull();
905 if (getCollection().size() < 4) {
906 return;
907 }
908 final ListIterator<E> it = getCollection().listIterator();
909 final E zero = it.next();
910 final E one = it.next();
911 final E two = it.next();
912 final E two2 = it.previous();
913 final E one2 = it.previous();
914 assertEquals(one, one2);
915 assertEquals(two, two2);
916 assertEquals(zero, getCollection().get(0));
917 assertEquals(one, getCollection().get(1));
918 assertEquals(two, getCollection().get(2));
919
920 it.remove();
921 assertEquals(zero, getCollection().get(0));
922 assertEquals(two, getCollection().get(1));
923 final E two3 = it.next();
924 assertEquals(two, two3);
925 assertEquals(getCollection().size() > 2, it.hasNext());
926 assertTrue(it.hasPrevious());
927 }
928
929
930
931
932 @Test
933 public void testListListIteratorPreviousRemovePrevious() {
934 if (!isRemoveSupported()) {
935 return;
936 }
937 resetFull();
938 if (getCollection().size() < 4) {
939 return;
940 }
941 final ListIterator<E> it = getCollection().listIterator();
942 final E zero = it.next();
943 final E one = it.next();
944 final E two = it.next();
945 final E two2 = it.previous();
946 final E one2 = it.previous();
947 assertEquals(one, one2);
948 assertEquals(two, two2);
949 assertEquals(zero, getCollection().get(0));
950 assertEquals(one, getCollection().get(1));
951 assertEquals(two, getCollection().get(2));
952
953 it.remove();
954 assertEquals(zero, getCollection().get(0));
955 assertEquals(two, getCollection().get(1));
956 final E zero3 = it.previous();
957 assertEquals(zero, zero3);
958 assertFalse(it.hasPrevious());
959 assertEquals(getCollection().size() > 2, it.hasNext());
960 }
961
962
963
964
965 @Test
966 public void testListRemoveByIndex() {
967 if (!isRemoveSupported()) {
968 return;
969 }
970
971 final int max = getFullElements().length;
972 for (int i = 0; i < max; i++) {
973 resetFull();
974 final E o1 = getCollection().remove(i);
975 final E o2 = getConfirmed().remove(i);
976 assertEquals(o1, o2, "remove should return correct element");
977 verify();
978 }
979 }
980
981
982
983
984
985 @Test
986 public void testListRemoveByIndexBoundsChecking() {
987 if (!isRemoveSupported()) {
988 return;
989 }
990
991 final List<E> list = makeObject();
992
993 assertThrows(IndexOutOfBoundsException.class, () -> list.remove(Integer.MIN_VALUE),
994 "List.remove should throw IndexOutOfBoundsException [Integer.MIN_VALUE]");
995
996 assertThrows(IndexOutOfBoundsException.class, () -> list.remove(-1),
997 "List.remove should throw IndexOutOfBoundsException [-1]");
998
999 assertThrows(IndexOutOfBoundsException.class, () -> list.remove(0),
1000 "List.remove should throw IndexOutOfBoundsException [0]");
1001
1002 assertThrows(IndexOutOfBoundsException.class, () -> list.remove(1),
1003 "List.remove should throw IndexOutOfBoundsException [1]");
1004
1005 assertThrows(IndexOutOfBoundsException.class, () -> list.remove(Integer.MAX_VALUE),
1006 "List.remove should throw IndexOutOfBoundsException [Integer.MAX_VALUE]");
1007 }
1008
1009
1010
1011
1012
1013 @Test
1014 public void testListRemoveByIndexBoundsChecking2() {
1015 if (!isRemoveSupported()) {
1016 return;
1017 }
1018
1019 final List<E> list = makeFullCollection();
1020
1021 assertThrows(IndexOutOfBoundsException.class, () -> list.remove(Integer.MIN_VALUE),
1022 "List.remove should throw IndexOutOfBoundsException [Integer.MIN_VALUE]");
1023
1024 assertThrows(IndexOutOfBoundsException.class, () -> list.remove(-1),
1025 "List.remove should throw IndexOutOfBoundsException [-1]");
1026
1027 assertThrows(IndexOutOfBoundsException.class, () -> list.remove(getFullElements().length),
1028 "List.remove should throw IndexOutOfBoundsException [size]");
1029
1030 assertThrows(IndexOutOfBoundsException.class, () -> list.remove(Integer.MAX_VALUE),
1031 "List.remove should throw IndexOutOfBoundsException [Integer.MAX_VALUE]");
1032 }
1033
1034
1035
1036
1037 @Test
1038 public void testListSetByIndex() {
1039 if (!isSetSupported()) {
1040 return;
1041 }
1042
1043 resetFull();
1044 final E[] elements = getFullElements();
1045 final E[] other = getOtherElements();
1046
1047 for (int i = 0; i < elements.length; i++) {
1048 final E n = other[i % other.length];
1049 final E v = getCollection().set(i, n);
1050 assertEquals(elements[i], v, "Set should return correct element");
1051 getConfirmed().set(i, n);
1052 verify();
1053 }
1054 }
1055
1056
1057
1058
1059
1060 @Test
1061 public void testListSetByIndexBoundsChecking() {
1062 if (!isSetSupported()) {
1063 return;
1064 }
1065
1066 final List<E> list = makeObject();
1067 final E element = getOtherElements()[0];
1068
1069 assertThrows(IndexOutOfBoundsException.class, () -> list.set(Integer.MIN_VALUE, element),
1070 "List.set should throw IndexOutOfBoundsException [Integer.MIN_VALUE]");
1071
1072 assertThrows(IndexOutOfBoundsException.class, () -> list.set(-1, element),
1073 "List.set should throw IndexOutOfBoundsException [-1]");
1074
1075 assertThrows(IndexOutOfBoundsException.class, () -> list.set(0, element),
1076 "List.set should throw IndexOutOfBoundsException [0]");
1077
1078 assertThrows(IndexOutOfBoundsException.class, () -> list.set(1, element),
1079 "List.set should throw IndexOutOfBoundsException [1]");
1080
1081 assertThrows(IndexOutOfBoundsException.class, () -> list.set(Integer.MAX_VALUE, element),
1082 "List.set should throw IndexOutOfBoundsException [Integer.MAX_VALUE]");
1083 }
1084
1085
1086
1087
1088
1089 @Test
1090 public void testListSetByIndexBoundsChecking2() {
1091 if (!isSetSupported()) {
1092 return;
1093 }
1094
1095 final List<E> list = makeFullCollection();
1096 final E element = getOtherElements()[0];
1097
1098 assertThrows(IndexOutOfBoundsException.class, () -> list.set(Integer.MIN_VALUE, element),
1099 "List.set should throw IndexOutOfBoundsException [Integer.MIN_VALUE]");
1100
1101 assertThrows(IndexOutOfBoundsException.class, () -> list.set(-1, element),
1102 "List.set should throw IndexOutOfBoundsException [-1]");
1103
1104 assertThrows(IndexOutOfBoundsException.class, () -> list.set(getFullElements().length, element),
1105 "List.set should throw IndexOutOfBoundsException [size]");
1106
1107 assertThrows(IndexOutOfBoundsException.class, () -> list.set(Integer.MAX_VALUE, element),
1108 "List.set should throw IndexOutOfBoundsException [Integer.MAX_VALUE]");
1109 }
1110
1111
1112
1113
1114
1115 @Test
1116 public void testListSubListFailFastOnAdd() {
1117 if (!isFailFastSupported()) {
1118 return;
1119 }
1120 if (!isAddSupported()) {
1121 return;
1122 }
1123
1124 resetFull();
1125 final int size = getCollection().size();
1126 List<E> sub = getCollection().subList(1, size);
1127 getCollection().add(getOtherElements()[0]);
1128 failFastAll(sub);
1129
1130 resetFull();
1131 sub = getCollection().subList(1, size);
1132 getCollection().add(0, getOtherElements()[0]);
1133 failFastAll(sub);
1134
1135 resetFull();
1136 sub = getCollection().subList(1, size);
1137 getCollection().addAll(Arrays.asList(getOtherElements()));
1138 failFastAll(sub);
1139
1140 resetFull();
1141 sub = getCollection().subList(1, size);
1142 getCollection().addAll(0, Arrays.asList(getOtherElements()));
1143 failFastAll(sub);
1144 }
1145
1146
1147
1148
1149
1150 @Test
1151 public void testListSubListFailFastOnRemove() {
1152 if (!isFailFastSupported()) {
1153 return;
1154 }
1155 if (!isRemoveSupported()) {
1156 return;
1157 }
1158
1159 resetFull();
1160 final int size = getCollection().size();
1161 List<E> sub = getCollection().subList(1, size);
1162 getCollection().remove(0);
1163 failFastAll(sub);
1164
1165 resetFull();
1166 sub = getCollection().subList(1, size);
1167 getCollection().remove(getFullElements()[2]);
1168 failFastAll(sub);
1169
1170 resetFull();
1171 sub = getCollection().subList(1, size);
1172 getCollection().removeAll(Arrays.asList(getFullElements()));
1173 failFastAll(sub);
1174
1175 resetFull();
1176 sub = getCollection().subList(1, size);
1177 getCollection().retainAll(Arrays.asList(getOtherElements()));
1178 failFastAll(sub);
1179
1180 resetFull();
1181 sub = getCollection().subList(1, size);
1182 getCollection().clear();
1183 failFastAll(sub);
1184 }
1185
1186
1187
1188
1189
1190 @Test
1191 public void testUnsupportedSet() {
1192 if (isSetSupported()) {
1193 return;
1194 }
1195
1196 resetFull();
1197 assertThrows(UnsupportedOperationException.class, () -> getCollection().set(0, getFullElements()[0]),
1198 "Empty collection should not support set.");
1199
1200
1201 verify();
1202 }
1203
1204
1205
1206
1207
1208 @Override
1209 @SuppressWarnings("unchecked")
1210 public void verify() {
1211 super.verify();
1212
1213 final List<E> list1 = getCollection();
1214 final List<E> list2 = getConfirmed();
1215
1216 assertEquals(list1, list2, "List should equal confirmed");
1217 assertEquals(list2, list1, "Confirmed should equal list");
1218
1219 assertEquals(list1.hashCode(), list2.hashCode(), "Hash codes should be equal");
1220
1221 int i = 0;
1222 final Iterator<E> iterator1 = list1.iterator();
1223 final E[] array = (E[]) list1.toArray();
1224 for (Object o2 : list2) {
1225 assertTrue(iterator1.hasNext(), "List iterator should have next");
1226 final Object o1 = iterator1.next();
1227 assertEquals(o1, o2, "Iterator elements should be equal");
1228 o2 = list1.get(i);
1229 assertEquals(o1, o2, "get should return correct element");
1230 o2 = array[i];
1231 assertEquals(o1, o2, "toArray should have correct element");
1232 i++;
1233 }
1234 }
1235
1236 }