1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.collections4.collection;
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.assertNotNull;
22 import static org.junit.jupiter.api.Assertions.assertNull;
23 import static org.junit.jupiter.api.Assertions.assertThrows;
24 import static org.junit.jupiter.api.Assertions.assertTrue;
25 import static org.junit.jupiter.api.Assertions.fail;
26
27 import java.io.ByteArrayInputStream;
28 import java.io.ByteArrayOutputStream;
29 import java.io.ObjectInputStream;
30 import java.io.ObjectOutputStream;
31 import java.io.Serializable;
32 import java.lang.reflect.Array;
33 import java.util.ArrayList;
34 import java.util.Arrays;
35 import java.util.Collection;
36 import java.util.Collections;
37 import java.util.ConcurrentModificationException;
38 import java.util.HashMap;
39 import java.util.HashSet;
40 import java.util.Iterator;
41 import java.util.List;
42 import java.util.Map;
43 import java.util.NoSuchElementException;
44 import java.util.Objects;
45 import java.util.function.Predicate;
46
47 import org.apache.commons.collections4.AbstractObjectTest;
48 import org.apache.commons.lang3.ArrayUtils;
49 import org.apache.commons.lang3.StringUtils;
50 import org.junit.jupiter.api.Test;
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140 public abstract class AbstractCollectionTest<E> extends AbstractObjectTest {
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157 public static final int UNORDERED = 0x1;
158
159
160
161
162
163
164
165
166
167 protected static void assertNotCollectionContains(final Collection<?> coll, final Object element) {
168 try {
169 assertFalse(coll.contains(element));
170 } catch (final ClassCastException | NullPointerException e) {
171
172 }
173 }
174
175
176
177
178
179
180 protected static void assertNotCollectionContainsAll(final Collection<?> coll, final Collection<?> sub) {
181 try {
182 assertFalse(coll.containsAll(sub));
183 } catch (final ClassCastException | NullPointerException e) {
184
185 }
186 }
187
188
189
190
191
192
193 protected static void assertNotRemoveAllFromCollection(final Collection<?> coll, final Collection<?> sub) {
194 try {
195 assertFalse(coll.removeAll(sub));
196 } catch (final ClassCastException | NullPointerException e) {
197
198 }
199 }
200
201
202
203
204
205
206 protected static void assertNotRemoveFromCollection(final Collection<?> coll, final Object element) {
207 try {
208 assertFalse(coll.remove(element));
209 } catch (final ClassCastException | NullPointerException e) {
210
211 }
212 }
213
214
215
216
217
218
219
220
221
222
223
224 private static void assertUnorderedArrayEquals(final Object[] a1, final Object[] a2, final String msg) {
225 assertEquals(a1.length, a2.length, () -> msg + ": length");
226 final int size = a1.length;
227
228 final boolean[] matched = new boolean[size];
229 NEXT_OBJECT:
230 for (final Object o : a1) {
231 for (int i = 0; i < size; i++) {
232 if (matched[i]) {
233
234 continue;
235 }
236 if (Objects.equals(o, a2[i])) {
237
238 matched[i] = true;
239
240 continue NEXT_OBJECT;
241 }
242 }
243 fail(msg + ": array 2 does not have object: " + o);
244 }
245 }
246
247
248
249
250 private Collection<E> collection;
251
252
253
254
255
256
257
258
259
260 private Collection<E> confirmed;
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284 public boolean areEqualElementsDistinguishable() {
285 return false;
286 }
287
288
289
290
291 public Map.Entry<E, E> cloneMapEntry(final Map.Entry<E, E> entry) {
292 final HashMap<E, E> map = new HashMap<>();
293 map.put(entry.getKey(), entry.getValue());
294 return map.entrySet().iterator().next();
295 }
296
297 public Collection<E> getCollection() {
298 return collection;
299 }
300
301 public Collection<E> getConfirmed() {
302 return confirmed;
303 }
304
305
306
307
308
309
310
311
312
313
314
315 @SuppressWarnings("unchecked")
316 public E[] getFullElements() {
317 if (isNullSupported()) {
318 final ArrayList<E> list = new ArrayList<>(Arrays.asList(getFullNonNullElements()));
319 list.add(4, null);
320 return (E[]) list.toArray();
321 }
322 return getFullNonNullElements().clone();
323 }
324
325
326
327
328
329
330
331
332
333 @SuppressWarnings("unchecked")
334 public E[] getFullNonNullElements() {
335 return (E[]) new Object[] {
336 StringUtils.EMPTY,
337 "One",
338 Integer.valueOf(2),
339 "Three",
340 Integer.valueOf(4),
341 "One",
342 Double.valueOf(5),
343 Float.valueOf(6),
344 "Seven",
345 "Eight",
346 "Nine",
347 Integer.valueOf(10),
348 Short.valueOf((short) 11),
349 Long.valueOf(12),
350 "Thirteen",
351 "14",
352 "15",
353 Byte.valueOf((byte) 16)
354 };
355 }
356
357
358
359
360
361
362
363 public Object[] getFullNonNullStringElements() {
364 return new Object[] {
365 "If", "the", "dull", "substance", "of", "my", "flesh", "were",
366 "thought", "Injurious", "distance", "could", "not", "stop", "my", "way",
367 };
368 }
369
370
371
372
373
374
375
376
377
378 protected int getIterationBehaviour() {
379 return 0;
380 }
381
382
383
384
385
386
387
388
389
390
391 public E[] getOtherElements() {
392 return getOtherNonNullElements();
393 }
394
395
396
397
398
399
400 @SuppressWarnings("unchecked")
401 public E[] getOtherNonNullElements() {
402 return (E[]) new Object[] {
403 Integer.valueOf(0),
404 Float.valueOf(0),
405 Double.valueOf(0),
406 "Zero",
407 Short.valueOf((short) 0),
408 Byte.valueOf((byte) 0),
409 Long.valueOf(0),
410 Character.valueOf('\u0000'),
411 "0"
412 };
413 }
414
415
416
417
418
419
420
421 public Object[] getOtherNonNullStringElements() {
422 return new Object[] {
423 "For", "then", "despite", "space", "I", "would", "be",
424 "brought", "From", "limits", "far", "remote", "where", "thou", "dost", "stay"
425 };
426 }
427
428
429
430
431
432
433
434
435
436 public boolean isAddSupported() {
437 return true;
438 }
439
440
441
442
443
444 @Override
445 public boolean isEqualsCheckable() {
446 return false;
447 }
448
449
450
451
452
453 public boolean isFailFastSupported() {
454 return false;
455 }
456
457
458
459
460
461 public boolean isNullSupported() {
462 return true;
463 }
464
465
466
467
468
469
470
471
472
473
474 public boolean isRemoveSupported() {
475 return true;
476 }
477
478
479
480
481
482
483
484
485 public abstract Collection<E> makeConfirmedCollection();
486
487
488
489
490
491
492
493
494
495 public abstract Collection<E> makeConfirmedFullCollection();
496
497
498
499
500
501
502
503
504
505 public Collection<E> makeFullCollection() {
506 final Collection<E> c = makeObject();
507 c.addAll(Arrays.asList(getFullElements()));
508 return c;
509 }
510
511
512
513
514 @Override
515 public abstract Collection<E> makeObject();
516
517
518
519
520
521
522 public void resetEmpty() {
523 this.setCollection(makeObject());
524 this.setConfirmed(makeConfirmedCollection());
525 }
526
527
528
529
530
531
532 public void resetFull() {
533 this.setCollection(makeFullCollection());
534 this.setConfirmed(makeConfirmedFullCollection());
535 }
536
537
538
539
540
541 public void setCollection(final Collection<E> collection) {
542 this.collection = collection;
543 }
544
545
546
547
548
549 public void setConfirmed(final Collection<E> confirmed) {
550 this.confirmed = confirmed;
551 }
552
553
554
555
556
557 @Test
558 public void testCollectionAdd() {
559 if (!isAddSupported()) {
560 return;
561 }
562
563 final E[] elements = getFullElements();
564 for (final E element : elements) {
565 resetEmpty();
566 final boolean r = getCollection().add(element);
567 getConfirmed().add(element);
568 verify();
569 assertTrue(r, "Empty collection changed after add");
570 assertEquals(1, getCollection().size(), "Collection size is 1 after first add");
571 }
572
573 resetEmpty();
574 int size = 0;
575 for (final E element : elements) {
576 final boolean r = getCollection().add(element);
577 getConfirmed().add(element);
578 verify();
579 if (r) {
580 size++;
581 }
582 assertEquals(size, getCollection().size(), "Collection size should grow after add");
583 assertTrue(getCollection().contains(element), "Collection should contain added element");
584 }
585 }
586
587
588
589
590 @Test
591 public void testCollectionAddAll() {
592 if (!isAddSupported()) {
593 return;
594 }
595
596 resetEmpty();
597 E[] elements = getFullElements();
598 boolean r = getCollection().addAll(Arrays.asList(elements));
599 getConfirmed().addAll(Arrays.asList(elements));
600 verify();
601 assertTrue(r, "Empty collection should change after addAll");
602 for (final E element : elements) {
603 assertTrue(getCollection().contains(element), "Collection should contain added element");
604 }
605
606 resetFull();
607 int size = getCollection().size();
608 elements = getOtherElements();
609 r = getCollection().addAll(Arrays.asList(elements));
610 getConfirmed().addAll(Arrays.asList(elements));
611 verify();
612 assertTrue(r, "Full collection should change after addAll");
613 for (final E element : elements) {
614 assertTrue(getCollection().contains(element),
615 "Full collection should contain added element");
616 }
617 assertEquals(size + elements.length, getCollection().size(), "Size should increase after addAll");
618
619 resetFull();
620 size = getCollection().size();
621 r = getCollection().addAll(Arrays.asList(getFullElements()));
622 getConfirmed().addAll(Arrays.asList(getFullElements()));
623 verify();
624 if (r) {
625 assertTrue(size < getCollection().size(), "Size should increase if addAll returns true");
626 } else {
627 assertEquals(size, getCollection().size(), "Size should not change if addAll returns false");
628 }
629 }
630
631
632
633
634 @Test
635 public void testCollectionClear() {
636 if (!isRemoveSupported()) {
637 return;
638 }
639
640 resetEmpty();
641 getCollection().clear();
642 verify();
643
644 resetFull();
645 getCollection().clear();
646 getConfirmed().clear();
647 verify();
648 }
649
650
651
652
653 @Test
654 public void testCollectionContains() {
655 Object[] elements;
656
657 resetEmpty();
658 elements = getFullElements();
659 for (int i = 0; i < elements.length; i++) {
660 assertFalse(getCollection().contains(elements[i]), "Empty collection shouldn't contain element[" + i + "]");
661 }
662
663 verify();
664
665 elements = getOtherElements();
666 for (int i = 0; i < elements.length; i++) {
667 assertFalse(getCollection().contains(elements[i]), "Empty collection shouldn't contain element[" + i + "]");
668 }
669
670 verify();
671
672 resetFull();
673 elements = getFullElements();
674 for (int i = 0; i < elements.length; i++) {
675 assertTrue(getCollection().contains(elements[i]),
676 "Full collection should contain element[" + i + "]");
677 }
678
679 verify();
680
681 resetFull();
682 elements = getOtherElements();
683 for (final Object element : elements) {
684 assertFalse(getCollection().contains(element), "Full collection shouldn't contain element");
685 }
686 }
687
688
689
690
691 @Test
692 public void testCollectionContainsAll() {
693 resetEmpty();
694 Collection<E> col = new HashSet<>();
695 assertTrue(getCollection().containsAll(col),
696 "Every Collection should contain all elements of an " + "empty Collection.");
697 col.addAll(Arrays.asList(getOtherElements()));
698 assertFalse(getCollection().containsAll(col),
699 "Empty Collection shouldn't contain all elements of " + "a non-empty Collection.");
700
701 verify();
702
703 resetFull();
704 assertFalse(getCollection().containsAll(col), "Full collection shouldn't contain other elements");
705
706 col.clear();
707 col.addAll(Arrays.asList(getFullElements()));
708 assertTrue(getCollection().containsAll(col),
709 "Full collection should containAll full elements");
710
711 verify();
712
713 final int min = getFullElements().length < 4 ? 0 : 2;
714 final int max = getFullElements().length == 1 ? 1 :
715 getFullElements().length <= 5 ? getFullElements().length - 1 : 5;
716 col = Arrays.asList(getFullElements()).subList(min, max);
717 assertTrue(getCollection().containsAll(col),
718 "Full collection should containAll partial full elements");
719 assertTrue(getCollection().containsAll(getCollection()),
720 "Full collection should containAll itself");
721
722 verify();
723
724 col = new ArrayList<>(Arrays.asList(getFullElements()));
725 col.addAll(Arrays.asList(getFullElements()));
726 assertTrue(getCollection().containsAll(col),
727 "Full collection should containAll duplicate full elements");
728
729
730 verify();
731 }
732
733
734
735
736 @Test
737 public void testCollectionIsEmpty() {
738 resetEmpty();
739 assertTrue(getCollection().isEmpty(), "New Collection should be empty.");
740
741 verify();
742
743 resetFull();
744 assertFalse(getCollection().isEmpty(), "Full collection shouldn't be empty");
745
746 verify();
747 }
748
749
750
751
752 @Test
753 public void testCollectionIterator() {
754 resetEmpty();
755 Iterator<E> it1 = getCollection().iterator();
756 assertFalse(it1.hasNext(), "Iterator for empty Collection shouldn't have next.");
757 final Iterator<E> finalIt1 = it1;
758 assertThrows(NoSuchElementException.class, () -> finalIt1.next(),
759 "Iterator at end of Collection should throw NoSuchElementException when next is called.");
760
761 verify();
762
763 resetFull();
764 it1 = getCollection().iterator();
765 for (final E element : getCollection()) {
766 assertTrue(it1.hasNext(), "Iterator for full collection should haveNext");
767 it1.next();
768 }
769 assertFalse(it1.hasNext(), "Iterator should be finished");
770
771 final ArrayList<E> list = new ArrayList<>();
772 it1 = getCollection().iterator();
773 for (int i = 0; i < getCollection().size(); i++) {
774 final E next = it1.next();
775 assertTrue(getCollection().contains(next),
776 "Collection should contain element returned by its iterator");
777 list.add(next);
778 }
779 final Iterator<E> finalIt2 = it1;
780 assertThrows(NoSuchElementException.class, () -> finalIt2.next(),
781 "iterator.next() should raise NoSuchElementException after it finishes");
782
783 verify();
784 }
785
786
787
788
789 @Test
790 public void testCollectionIteratorFailFast() {
791 if (!isFailFastSupported()) {
792 return;
793 }
794
795 if (isAddSupported()) {
796 resetFull();
797 final Iterator<E> iter0 = getCollection().iterator();
798 final E o = getOtherElements()[0];
799 getCollection().add(o);
800 getConfirmed().add(o);
801 assertThrows(ConcurrentModificationException.class, () -> iter0.next(),
802 "next after add should raise ConcurrentModification");
803 verify();
804
805 resetFull();
806 final Iterator<E> iter = getCollection().iterator();
807 getCollection().addAll(Arrays.asList(getOtherElements()));
808 getConfirmed().addAll(Arrays.asList(getOtherElements()));
809 assertThrows(ConcurrentModificationException.class, () -> iter.next(),
810 "next after addAll should raise ConcurrentModification");
811 verify();
812 }
813
814 if (!isRemoveSupported()) {
815 return;
816 }
817
818 resetFull();
819 final Iterator<E> iter = getCollection().iterator();
820 getCollection().clear();
821 try {
822 iter.next();
823 fail("next after clear should raise ConcurrentModification");
824 } catch (final ConcurrentModificationException | NoSuchElementException e) {
825
826
827 }
828
829 resetFull();
830 final Iterator<E> iter0 = getCollection().iterator();
831 getCollection().remove(getFullElements()[0]);
832 assertThrows(ConcurrentModificationException.class, () -> iter0.next(),
833 "next after remove should raise ConcurrentModification");
834
835 resetFull();
836 final Iterator<E> iter1 = getCollection().iterator();
837 getCollection().removeIf(e -> false);
838 assertThrows(ConcurrentModificationException.class, () -> iter1.next(),
839 "next after removeIf should raise ConcurrentModification");
840
841 resetFull();
842 final Iterator<E> iter2 = getCollection().iterator();
843 final List<E> sublist = Arrays.asList(getFullElements()).subList(2, 5);
844 getCollection().removeAll(sublist);
845 assertThrows(ConcurrentModificationException.class, () -> iter2.next(),
846 "next after removeAll should raise ConcurrentModification");
847
848 resetFull();
849 final Iterator<E> iter3 = getCollection().iterator();
850 final List<E> sublist3 = Arrays.asList(getFullElements()).subList(2, 5);
851 getCollection().retainAll(sublist3);
852 assertThrows(ConcurrentModificationException.class, () -> iter3.next(),
853 "next after retainAll should raise ConcurrentModification");
854 }
855
856
857
858
859 @Test
860 @SuppressWarnings("unchecked")
861 public void testCollectionIteratorRemove() {
862 if (!isRemoveSupported()) {
863 return;
864 }
865
866 resetEmpty();
867 assertThrows(IllegalStateException.class, () -> getCollection().iterator().remove(),
868 "New iterator.remove should raise IllegalState");
869 verify();
870
871 final Iterator<E> iter0 = getCollection().iterator();
872 iter0.hasNext();
873 assertThrows(IllegalStateException.class, () -> iter0.remove(),
874 "New iterator.remove should raise IllegalState even after hasNext");
875 verify();
876
877 resetFull();
878 int size = getCollection().size();
879 Iterator<E> iter = getCollection().iterator();
880 while (iter.hasNext()) {
881 Object o = iter.next();
882
883
884 if (o instanceof Map.Entry) {
885 o = cloneMapEntry((Map.Entry<E, E>) o);
886 }
887 iter.remove();
888
889
890
891
892
893
894
895
896
897 if (!areEqualElementsDistinguishable()) {
898 getConfirmed().remove(o);
899 verify();
900 }
901
902 size--;
903 assertEquals(size, getCollection().size(),
904 "Collection should shrink by one after iterator.remove");
905 }
906 assertTrue(getCollection().isEmpty(), "Collection should be empty after iterator purge");
907
908 resetFull();
909 iter = getCollection().iterator();
910 iter.next();
911 iter.remove();
912 final Iterator<E> finalIter = iter;
913 assertThrows(IllegalStateException.class, () -> finalIter.remove(),
914 "Second iter.remove should raise IllegalState");
915 }
916
917
918
919
920 @Test
921 public void testCollectionRemove() {
922 if (!isRemoveSupported()) {
923 return;
924 }
925
926 resetEmpty();
927 final E[] elements = getFullElements();
928 for (final E element : elements) {
929 assertFalse(getCollection().remove(element), "Shouldn't remove nonexistent element");
930 verify();
931 }
932
933 final E[] other = getOtherElements();
934
935 resetFull();
936 for (final E element : other) {
937 assertFalse(getCollection().remove(element), "Shouldn't remove nonexistent other element");
938 verify();
939 }
940
941 final int size = getCollection().size();
942 for (final E element : elements) {
943 resetFull();
944 assertTrue(getCollection().remove(element),
945 "Collection should remove extant element: " + element);
946
947
948
949
950
951
952
953
954
955 if (!areEqualElementsDistinguishable()) {
956 getConfirmed().remove(element);
957 verify();
958 }
959
960 assertEquals(size - 1, getCollection().size(), "Collection should shrink after remove");
961 }
962 }
963
964
965
966
967 @Test
968 public void testCollectionRemoveAll() {
969 if (!isRemoveSupported()) {
970 return;
971 }
972
973 resetEmpty();
974 assertFalse(getCollection().removeAll(Collections.EMPTY_SET), "Empty collection removeAll should return false for empty input");
975 verify();
976
977 assertFalse(getCollection().removeAll(new ArrayList<>(getCollection())), "Empty collection removeAll should return false for nonempty input");
978 verify();
979
980 resetFull();
981 assertFalse(getCollection().removeAll(Collections.EMPTY_SET), "Full collection removeAll should return false for empty input");
982 verify();
983
984 assertFalse(getCollection().removeAll(Arrays.asList(getOtherElements())), "Full collection removeAll should return false for other elements");
985 verify();
986
987 assertTrue(getCollection().removeAll(new HashSet<>(getCollection())),
988 "Full collection removeAll should return true for full elements");
989 getConfirmed().removeAll(new HashSet<>(getConfirmed()));
990 verify();
991
992 resetFull();
993 final int size = getCollection().size();
994 final int min = getFullElements().length < 4 ? 0 : 2;
995 final int max = getFullElements().length == 1 ? 1 :
996 getFullElements().length <= 5 ? getFullElements().length - 1 : 5;
997 final Collection<E> all = Arrays.asList(getFullElements()).subList(min, max);
998 assertTrue(getCollection().removeAll(all), "Full collection removeAll should work");
999 getConfirmed().removeAll(all);
1000 verify();
1001
1002 assertTrue(getCollection().size() < size, "Collection should shrink after removeAll");
1003 for (final E element : all) {
1004 assertFalse(getCollection().contains(element), "Collection shouldn't contain removed element");
1005 }
1006 }
1007
1008
1009
1010
1011 @Test
1012 public void testCollectionRemoveIf() {
1013 if (!isRemoveSupported()) {
1014 return;
1015 }
1016
1017 resetEmpty();
1018 assertFalse(getCollection().removeIf(e -> false), "Empty collection removeIf should return false for a predicate that returns only false");
1019 verify();
1020
1021 assertFalse(getCollection().removeIf(e -> true), "Empty collection removeIf should return false for a predicate that returns only true");
1022 verify();
1023
1024 resetFull();
1025 assertFalse(getCollection().removeIf(e -> false), "Full collection removeIf should return false for a predicate that returns only false");
1026 verify();
1027
1028 assertTrue(getCollection().removeIf(e -> true), "Full collection removeIf should return true for a predicate that returns only true");
1029 getConfirmed().removeIf(e -> true);
1030 verify();
1031
1032 resetFull();
1033 final List<E> elements = Arrays.asList(getFullElements());
1034
1035 final int mid = getFullElements().length / 2;
1036 final E target = elements.get(mid);
1037
1038 final int size = getCollection().size();
1039 final int targetCount = Collections.frequency(elements, target);
1040
1041 final Predicate<E> filter = target::equals;
1042
1043 assertTrue(getCollection().removeIf(filter), "Full collection removeIf should work");
1044 getConfirmed().removeIf(filter);
1045 verify();
1046
1047 assertEquals(getCollection().size(), size - targetCount, "Collection should shrink after removeIf");
1048 assertFalse(getCollection().contains(target), "Collection shouldn't contain removed element");
1049 }
1050
1051
1052
1053
1054 @Test
1055 public void testCollectionRetainAll() {
1056 if (!isRemoveSupported()) {
1057 return;
1058 }
1059
1060 resetEmpty();
1061 final List<E> elements = Arrays.asList(getFullElements());
1062 final List<E> other = Arrays.asList(getOtherElements());
1063
1064 assertFalse(getCollection().retainAll(Collections.EMPTY_SET), "Empty retainAll() should return false");
1065 verify();
1066
1067 assertFalse(getCollection().retainAll(elements), "Empty retainAll() should return false");
1068 verify();
1069
1070 resetFull();
1071 assertTrue(getCollection().retainAll(Collections.EMPTY_SET),
1072 "Collection should change from retainAll empty");
1073 getConfirmed().retainAll(Collections.EMPTY_SET);
1074 verify();
1075
1076 resetFull();
1077 assertTrue(getCollection().retainAll(other), "Collection changed from retainAll other");
1078 getConfirmed().retainAll(other);
1079 verify();
1080
1081 resetFull();
1082 int size = getCollection().size();
1083 assertFalse(getCollection().retainAll(elements), "Collection shouldn't change from retainAll elements");
1084 verify();
1085 assertEquals(size, getCollection().size(), "Collection size shouldn't change");
1086
1087 if (getFullElements().length > 1) {
1088 resetFull();
1089 size = getCollection().size();
1090 final int min = getFullElements().length < 4 ? 0 : 2;
1091 final int max = getFullElements().length <= 5 ? getFullElements().length - 1 : 5;
1092 assertTrue(getCollection().retainAll(elements.subList(min, max)),
1093 "Collection should changed by partial retainAll");
1094 getConfirmed().retainAll(elements.subList(min, max));
1095 verify();
1096
1097 for (final E element : getCollection()) {
1098 assertTrue(elements.subList(min, max).contains(element), "Collection only contains retained element");
1099 }
1100 }
1101
1102 resetFull();
1103 final HashSet<E> set = new HashSet<>(elements);
1104 size = getCollection().size();
1105 assertFalse(getCollection().retainAll(set),
1106 "Collection shouldn't change from retainAll without " + "duplicate elements");
1107 verify();
1108 assertEquals(size, getCollection().size(),
1109 "Collection size didn't change from nonduplicate " + "retainAll");
1110 }
1111
1112
1113
1114
1115 @Test
1116 public void testCollectionSize() {
1117 resetEmpty();
1118 assertEquals(0, getCollection().size(), "Size of new Collection is 0.");
1119
1120 resetFull();
1121 assertFalse(getCollection().isEmpty(), "Size of full collection should be greater than zero");
1122 }
1123
1124
1125
1126
1127 @Test
1128 public void testCollectionToArray() {
1129 resetEmpty();
1130 assertEquals(0, getCollection().toArray().length,
1131 "Empty Collection should return empty array for toArray");
1132
1133 resetFull();
1134 final Object[] array = getCollection().toArray();
1135 assertEquals(array.length, getCollection().size(),
1136 "Full collection toArray should be same size as collection");
1137 final Object[] confirmedArray = getConfirmed().toArray();
1138 assertEquals(confirmedArray.length, array.length, "length of array from confirmed collection should "
1139 + "match the length of the collection's array");
1140 final boolean[] matched = new boolean[array.length];
1141
1142 for (int i = 0; i < array.length; i++) {
1143 assertTrue(getCollection().contains(array[i]),
1144 "Collection should contain element in toArray");
1145
1146 boolean match = false;
1147
1148 for (int j = 0; j < array.length; j++) {
1149
1150 if (matched[j]) {
1151 continue;
1152 }
1153 if (Objects.equals(array[i], confirmedArray[j])) {
1154 matched[j] = true;
1155 match = true;
1156 break;
1157 }
1158 }
1159 if (!match) {
1160 fail("element " + i + " in returned array should be found "
1161 + "in the confirmed collection's array");
1162 }
1163 }
1164 for (final boolean element : matched) {
1165 assertTrue(element, "Collection should return all its elements in " + "toArray");
1166 }
1167 }
1168
1169
1170
1171
1172 @Test
1173 public void testCollectionToArray2() {
1174 resetEmpty();
1175 Object[] a = { new Object(), null, null };
1176 Object[] array = getCollection().toArray(a);
1177 assertEquals(array, a, "Given array shouldn't shrink");
1178 assertNull(a[0], "Last element should be set to null");
1179 verify();
1180
1181 resetFull();
1182 assertThrows(ArrayStoreException.class, () -> getCollection().toArray(new Void[0]),
1183 "toArray(new Void[0]) should raise ArrayStore");
1184 verify();
1185
1186
1187 assertThrows(NullPointerException.class, () -> getCollection().toArray((Object[]) null),
1188 "toArray(null) should raise NPE");
1189 verify();
1190
1191 array = getCollection().toArray(ArrayUtils.EMPTY_OBJECT_ARRAY);
1192 a = getCollection().toArray();
1193
1194 if ((getIterationBehaviour() & UNORDERED) != 0) {
1195 assertUnorderedArrayEquals(array, a, "toArray(Object[]) and toArray()");
1196 } else {
1197 assertEquals(Arrays.asList(array), Arrays.asList(a), "toArrays should be equal");
1198 }
1199
1200
1201 final HashSet<Class<?>> classes = new HashSet<>();
1202 for (final Object element : array) {
1203 classes.add(element == null ? null : element.getClass());
1204 }
1205 if (classes.size() > 1) {
1206 return;
1207 }
1208
1209 Class<?> cl = classes.iterator().next();
1210 if (Map.Entry.class.isAssignableFrom(cl)) {
1211 cl = Map.Entry.class;
1212 }
1213 a = (Object[]) Array.newInstance(cl, 0);
1214 array = getCollection().toArray(a);
1215 assertEquals(a.getClass(), array.getClass(),
1216 "toArray(Object[]) should return correct array type");
1217
1218 if ((getIterationBehaviour() & UNORDERED) != 0) {
1219 assertUnorderedArrayEquals(array, getCollection().toArray(), "type-specific toArray(T[]) and toArray()");
1220 } else {
1221 assertEquals(Arrays.asList(array),
1222 Arrays.asList(getCollection().toArray()),
1223 "type-specific toArrays should be equal");
1224 }
1225 verify();
1226 }
1227
1228
1229
1230
1231 @Test
1232 public void testCollectionToString() {
1233 resetEmpty();
1234 assertNotNull(getCollection().toString(), "toString shouldn't return null");
1235
1236 resetFull();
1237 assertNotNull(getCollection().toString(), "toString shouldn't return null");
1238 }
1239
1240 @Test
1241 @Override
1242 public void testSerializeDeserializeThenCompare() throws Exception {
1243 Object obj = makeObject();
1244 if (obj instanceof Serializable && isTestSerialization()) {
1245 final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
1246 final ObjectOutputStream out = new ObjectOutputStream(buffer);
1247 out.writeObject(obj);
1248 out.close();
1249
1250 final ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(buffer.toByteArray()));
1251 final Object dest = in.readObject();
1252 in.close();
1253 if (isEqualsCheckable()) {
1254 assertEquals(obj, dest, "obj != deserialize(serialize(obj)) - EMPTY Collection");
1255 }
1256 }
1257 obj = makeFullCollection();
1258 if (obj instanceof Serializable && isTestSerialization()) {
1259 final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
1260 final ObjectOutputStream out = new ObjectOutputStream(buffer);
1261 out.writeObject(obj);
1262 out.close();
1263
1264 final ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(buffer.toByteArray()));
1265 final Object dest = in.readObject();
1266 in.close();
1267 if (isEqualsCheckable()) {
1268 assertEquals(obj, dest, "obj != deserialize(serialize(obj)) - FULL Collection");
1269 }
1270 }
1271 }
1272
1273
1274
1275
1276
1277 @Test
1278 public void testUnsupportedAdd() {
1279 if (isAddSupported()) {
1280 return;
1281 }
1282
1283 resetEmpty();
1284 assertThrows(UnsupportedOperationException.class, () -> getCollection().add(getFullNonNullElements()[0]),
1285 "Empty collection should not support add.");
1286
1287
1288 verify();
1289
1290 assertThrows(UnsupportedOperationException.class, () -> getCollection().addAll(Arrays.asList(getFullElements())),
1291 "Empty collection should not support addAll.");
1292
1293
1294 verify();
1295
1296 resetFull();
1297 assertThrows(UnsupportedOperationException.class, () -> getCollection().add(getFullNonNullElements()[0]),
1298 "Full collection should not support add.");
1299
1300
1301 verify();
1302
1303 assertThrows(UnsupportedOperationException.class, () -> getCollection().addAll(Arrays.asList(getOtherElements())),
1304 "Full collection should not support addAll.");
1305
1306
1307 verify();
1308 }
1309
1310
1311
1312
1313
1314 @Test
1315 public void testUnsupportedRemove() {
1316 if (isRemoveSupported()) {
1317 return;
1318 }
1319
1320 resetEmpty();
1321 assertThrows(UnsupportedOperationException.class, () -> getCollection().clear(),
1322 "clear should raise UnsupportedOperationException");
1323 verify();
1324
1325 assertThrows(UnsupportedOperationException.class, () -> getCollection().remove(null),
1326 "remove should raise UnsupportedOperationException");
1327 verify();
1328
1329 assertThrows(UnsupportedOperationException.class, () -> getCollection().removeIf(e -> true),
1330 "removeIf should raise UnsupportedOperationException");
1331 verify();
1332
1333 assertThrows(UnsupportedOperationException.class, () -> getCollection().removeAll(null),
1334 "removeAll should raise UnsupportedOperationException");
1335 verify();
1336
1337 assertThrows(UnsupportedOperationException.class, () -> getCollection().retainAll(null),
1338 "retainAll should raise UnsupportedOperationException");
1339 verify();
1340
1341 resetFull();
1342 final Iterator<E> iterator = getCollection().iterator();
1343 iterator.next();
1344 assertThrows(UnsupportedOperationException.class, () -> iterator.remove(),
1345 "iterator.remove should raise UnsupportedOperationException");
1346 verify();
1347
1348 }
1349
1350
1351
1352
1353
1354 public void verify() {
1355 final int confirmedSize = getConfirmed().size();
1356 assertEquals(confirmedSize, getCollection().size(),
1357 "Collection size should match confirmed collection's");
1358 assertEquals(getConfirmed().isEmpty(), getCollection().isEmpty(),
1359 "Collection isEmpty() result should match confirmed collection's");
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371 final Object[] confirmedValues = new Object[confirmedSize];
1372
1373 Iterator<E> iter;
1374
1375 iter = getConfirmed().iterator();
1376 int pos = 0;
1377 while (iter.hasNext()) {
1378 confirmedValues[pos++] = iter.next();
1379 }
1380
1381
1382
1383 final boolean[] matched = new boolean[confirmedSize];
1384
1385
1386
1387 iter = getCollection().iterator();
1388 while (iter.hasNext()) {
1389 final Object o = iter.next();
1390 boolean match = false;
1391 for (int i = 0; i < confirmedSize; i++) {
1392 if (matched[i]) {
1393
1394 continue;
1395 }
1396 if (Objects.equals(o, confirmedValues[i])) {
1397
1398 matched[i] = true;
1399 match = true;
1400 break;
1401 }
1402 }
1403
1404 if (!match) {
1405 fail("Collection should not contain a value that the "
1406 + "confirmed collection does not have: " + o + "\nTest: " + getCollection()
1407 + "\nReal: " + getConfirmed());
1408 }
1409 }
1410
1411
1412 for (int i = 0; i < confirmedSize; i++) {
1413 if (!matched[i]) {
1414
1415 fail("Collection should contain all values that are in the confirmed collection"
1416 + "\nTest: " + getCollection() + "\nReal: " + getConfirmed());
1417 }
1418 }
1419 }
1420
1421 }