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