1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.collections4.multimap;
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.Assumptions.assumeTrue;
26
27 import java.util.ArrayList;
28 import java.util.Arrays;
29 import java.util.Collection;
30 import java.util.HashMap;
31 import java.util.HashSet;
32 import java.util.Iterator;
33 import java.util.List;
34 import java.util.Map;
35 import java.util.Map.Entry;
36 import java.util.Set;
37
38 import org.apache.commons.collections4.AbstractObjectTest;
39 import org.apache.commons.collections4.Bag;
40 import org.apache.commons.collections4.BulkTest;
41 import org.apache.commons.collections4.CollectionUtils;
42 import org.apache.commons.collections4.MapIterator;
43 import org.apache.commons.collections4.MultiSet;
44 import org.apache.commons.collections4.MultiValuedMap;
45 import org.apache.commons.collections4.SetValuedMap;
46 import org.apache.commons.collections4.bag.AbstractBagTest;
47 import org.apache.commons.collections4.bag.HashBag;
48 import org.apache.commons.collections4.collection.AbstractCollectionTest;
49 import org.apache.commons.collections4.map.AbstractMapTest;
50 import org.apache.commons.collections4.multiset.AbstractMultiSetTest;
51 import org.apache.commons.collections4.set.AbstractSetTest;
52 import org.apache.commons.lang3.StringUtils;
53 import org.junit.jupiter.api.Disabled;
54 import org.junit.jupiter.api.Test;
55
56
57
58
59
60
61
62
63 public abstract class AbstractMultiValuedMapTest<K, V> extends AbstractObjectTest {
64
65 public class TestMultiValuedMapAsMap extends AbstractMapTest<K, Collection<V>> {
66
67 public TestMultiValuedMapAsMap() {
68 super(StringUtils.EMPTY);
69 }
70
71 @Override
72 public boolean areEqualElementsDistinguishable() {
73
74
75
76
77 return true;
78 }
79
80 @Override
81 protected int getIterationBehaviour() {
82 return AbstractMultiValuedMapTest.this.getIterationBehaviour();
83 }
84
85 @Override
86 @SuppressWarnings("unchecked")
87 public Collection<V>[] getNewSampleValues() {
88
89
90 final boolean isSetValuedMap = AbstractMultiValuedMapTest.this.makeObject() instanceof SetValuedMap;
91 final int maxV = getSampleTotalValueCount();
92 final int maxK = getSampleKeySize();
93 final V[] sampleValues = (V[]) new Object[maxV];
94 for (int v = 0; v < maxV; v++) {
95
96 sampleValues[v] = makeValue(maxK + 9, v);
97 }
98 final int cpk = getSampleCountPerKey();
99 final Collection<V>[] colArr = new Collection[maxK];
100 for (int i = 0; i < maxK; i++) {
101 final List<V> coll = new ArrayList<>(cpk);
102 for (int j = 0; j < cpk; j++) {
103 coll.add(sampleValues[i * cpk + j]);
104 }
105 colArr[i] = isSetValuedMap ? new HashSet<>(coll) : coll;
106 }
107 return colArr;
108 }
109
110 @Override
111 @SuppressWarnings("unchecked")
112 public K[] getSampleKeys() {
113 final K[] samplekeys = AbstractMultiValuedMapTest.this.getSampleKeys();
114 final int maxK = getSampleKeySize();
115 final int cpk = getSampleCountPerKey();
116 final Object[] finalKeys = new Object[maxK];
117 for (int i = 0; i < maxK; i++) {
118 finalKeys[i] = samplekeys[i * cpk];
119 }
120 return (K[]) finalKeys;
121 }
122
123 @Override
124 @SuppressWarnings("unchecked")
125 public Collection<V>[] getSampleValues() {
126
127
128
129 final boolean isSetValuedMap = AbstractMultiValuedMapTest.this.makeObject() instanceof SetValuedMap;
130 final V[] sampleValues = AbstractMultiValuedMapTest.this.getSampleValues();
131 final int maxK = getSampleKeySize();
132 final int cpk = getSampleCountPerKey();
133 final Collection<V>[] colArr = new Collection[maxK];
134 for (int i = 0; i < maxK; i++) {
135 final List<V> coll = new ArrayList<>(cpk);
136 for (int j = 0; j < cpk; j++) {
137 coll.add(sampleValues[i * cpk + j]);
138 }
139 colArr[i] = isSetValuedMap ? new HashSet<>(coll) : coll;
140 }
141 return colArr;
142 }
143
144 @Override
145 public boolean isAllowNullKey() {
146 return AbstractMultiValuedMapTest.this.isAllowNullKey();
147 }
148
149 @Override
150 public boolean isPutAddSupported() {
151 return false;
152 }
153
154 @Override
155 public boolean isPutChangeSupported() {
156 return false;
157 }
158
159 @Override
160 public boolean isRemoveSupported() {
161 return AbstractMultiValuedMapTest.this.isRemoveSupported();
162 }
163
164 @Override
165 public boolean isTestSerialization() {
166 return false;
167 }
168
169 @Override
170 public Map<K, Collection<V>> makeFullMap() {
171 return AbstractMultiValuedMapTest.this.makeFullMap().asMap();
172 }
173
174 @Override
175 public Map<K, Collection<V>> makeObject() {
176 return AbstractMultiValuedMapTest.this.makeObject().asMap();
177 }
178 }
179
180 public class TestMultiValuedMapEntries extends AbstractCollectionTest<Entry<K, V>> {
181 public TestMultiValuedMapEntries() {
182 super(StringUtils.EMPTY);
183 }
184
185 @SuppressWarnings("unchecked")
186 @Override
187 public Entry<K, V>[] getFullElements() {
188 return makeFullMap().entries().toArray(new Entry[0]);
189 }
190
191 @Override
192 protected int getIterationBehaviour() {
193 return AbstractMultiValuedMapTest.this.getIterationBehaviour();
194 }
195
196 @Override
197 public boolean isAddSupported() {
198
199 return false;
200 }
201
202 @Override
203 public boolean isNullSupported() {
204 return AbstractMultiValuedMapTest.this.isAllowNullKey();
205 }
206
207 @Override
208 public boolean isRemoveSupported() {
209 return AbstractMultiValuedMapTest.this.isRemoveSupported();
210 }
211
212 @Override
213 public boolean isTestSerialization() {
214 return false;
215 }
216
217 @Override
218 public Collection<Entry<K, V>> makeConfirmedCollection() {
219
220 return null;
221 }
222
223 @Override
224 public Collection<Entry<K, V>> makeConfirmedFullCollection() {
225
226 return null;
227 }
228
229 @Override
230 public Collection<Entry<K, V>> makeFullCollection() {
231 return AbstractMultiValuedMapTest.this.makeFullMap().entries();
232 }
233
234 @Override
235 public Collection<Entry<K, V>> makeObject() {
236 return AbstractMultiValuedMapTest.this.makeObject().entries();
237 }
238
239 @Override
240 public void resetEmpty() {
241 AbstractMultiValuedMapTest.this.resetEmpty();
242 setCollection(AbstractMultiValuedMapTest.this.getMap().entries());
243 TestMultiValuedMapEntries.this.setConfirmed(AbstractMultiValuedMapTest.this.getConfirmed().entries());
244 }
245
246 @Override
247 public void resetFull() {
248 AbstractMultiValuedMapTest.this.resetFull();
249 setCollection(AbstractMultiValuedMapTest.this.getMap().entries());
250 TestMultiValuedMapEntries.this.setConfirmed(AbstractMultiValuedMapTest.this.getConfirmed().entries());
251 }
252
253 }
254
255 public class TestMultiValuedMapKeys extends AbstractMultiSetTest<K> {
256
257 public TestMultiValuedMapKeys() {
258 super(StringUtils.EMPTY);
259 }
260
261 @Override
262 public K[] getFullElements() {
263 return getSampleKeys();
264 }
265
266 @Override
267 protected int getIterationBehaviour() {
268 return AbstractMultiValuedMapTest.this.getIterationBehaviour();
269 }
270
271 @Override
272 public boolean isAddSupported() {
273 return false;
274 }
275
276 @Override
277 public boolean isNullSupported() {
278 return AbstractMultiValuedMapTest.this.isAllowNullKey();
279 }
280
281 @Override
282 public boolean isRemoveSupported() {
283 return false;
284 }
285
286 @Override
287 public boolean isTestSerialization() {
288 return false;
289 }
290
291 @Override
292 public MultiSet<K> makeFullCollection() {
293 return AbstractMultiValuedMapTest.this.makeFullMap().keys();
294 }
295
296 @Override
297 public MultiSet<K> makeObject() {
298 return AbstractMultiValuedMapTest.this.makeObject().keys();
299 }
300
301 @Override
302 public void resetEmpty() {
303 AbstractMultiValuedMapTest.this.resetEmpty();
304 setCollection(AbstractMultiValuedMapTest.this.getMap().keys());
305 TestMultiValuedMapKeys.this.setConfirmed(AbstractMultiValuedMapTest.this.getConfirmed().keys());
306 }
307
308 @Override
309 public void resetFull() {
310 AbstractMultiValuedMapTest.this.resetFull();
311 setCollection(AbstractMultiValuedMapTest.this.getMap().keys());
312 TestMultiValuedMapKeys.this.setConfirmed(AbstractMultiValuedMapTest.this.getConfirmed().keys());
313 }
314 }
315
316 public class TestMultiValuedMapKeySet extends AbstractSetTest<K> {
317 public TestMultiValuedMapKeySet() {
318 super(StringUtils.EMPTY);
319 }
320
321 @SuppressWarnings("unchecked")
322 @Override
323 public K[] getFullElements() {
324 return (K[]) AbstractMultiValuedMapTest.this.makeFullMap().keySet().toArray();
325 }
326
327 @Override
328 protected int getIterationBehaviour() {
329 return AbstractMultiValuedMapTest.this.getIterationBehaviour();
330 }
331
332 @Override
333 public boolean isAddSupported() {
334 return false;
335 }
336
337 @Override
338 public boolean isNullSupported() {
339 return AbstractMultiValuedMapTest.this.isAllowNullKey();
340 }
341
342 @Override
343 public boolean isRemoveSupported() {
344 return AbstractMultiValuedMapTest.this.isRemoveSupported();
345 }
346
347 @Override
348 public boolean isTestSerialization() {
349 return false;
350 }
351
352 @Override
353 public Set<K> makeFullCollection() {
354 return AbstractMultiValuedMapTest.this.makeFullMap().keySet();
355 }
356
357 @Override
358 public Set<K> makeObject() {
359 return AbstractMultiValuedMapTest.this.makeObject().keySet();
360 }
361 }
362
363 public class TestMultiValuedMapValues extends AbstractCollectionTest<V> {
364 public TestMultiValuedMapValues() {
365 super(StringUtils.EMPTY);
366 }
367
368 @Override
369 public V[] getFullElements() {
370 return getSampleValues();
371 }
372
373 @Override
374 protected int getIterationBehaviour() {
375 return AbstractMultiValuedMapTest.this.getIterationBehaviour();
376 }
377
378 @Override
379 public boolean isAddSupported() {
380 return false;
381 }
382
383 @Override
384 public boolean isNullSupported() {
385 return AbstractMultiValuedMapTest.this.isAllowNullKey();
386 }
387
388 @Override
389 public boolean isRemoveSupported() {
390 return AbstractMultiValuedMapTest.this.isRemoveSupported();
391 }
392
393 @Override
394 public boolean isTestSerialization() {
395 return false;
396 }
397
398 @Override
399 public Collection<V> makeConfirmedCollection() {
400
401 return null;
402 }
403
404 @Override
405 public Collection<V> makeConfirmedFullCollection() {
406
407 return null;
408 }
409
410 @Override
411 public Collection<V> makeFullCollection() {
412 return AbstractMultiValuedMapTest.this.makeFullMap().values();
413 }
414
415 @Override
416 public Collection<V> makeObject() {
417 return AbstractMultiValuedMapTest.this.makeObject().values();
418 }
419
420 @Override
421 public void resetEmpty() {
422 AbstractMultiValuedMapTest.this.resetEmpty();
423 setCollection(AbstractMultiValuedMapTest.this.getMap().values());
424 TestMultiValuedMapValues.this.setConfirmed(AbstractMultiValuedMapTest.this.getConfirmed().values());
425 }
426
427 @Override
428 public void resetFull() {
429 AbstractMultiValuedMapTest.this.resetFull();
430 setCollection(AbstractMultiValuedMapTest.this.getMap().values());
431 TestMultiValuedMapValues.this.setConfirmed(AbstractMultiValuedMapTest.this.getConfirmed().values());
432 }
433 }
434
435
436 protected MultiValuedMap<K, V> map;
437
438
439 protected MultiValuedMap<K, V> confirmed;
440
441 public AbstractMultiValuedMapTest(final String testName) {
442 super(testName);
443 }
444
445 protected void addSampleMappings(final MultiValuedMap<? super K, ? super V> map) {
446 final K[] keys = getSampleKeys();
447 final V[] values = getSampleValues();
448 for (int i = 0; i < keys.length; i++) {
449 map.put(keys[i], values[i]);
450 }
451 }
452
453 public BulkTest bulkTestAsMap() {
454 return new TestMultiValuedMapAsMap();
455 }
456
457
458
459
460
461
462
463
464
465
466
467 public BulkTest bulkTestMultiValuedMapEntries() {
468 return new TestMultiValuedMapEntries();
469 }
470
471
472
473
474
475
476
477
478
479
480 public BulkTest bulkTestMultiValuedMapKeys() {
481 return new TestMultiValuedMapKeys();
482 }
483
484
485
486
487
488
489
490
491
492 public BulkTest bulkTestMultiValuedMapKeySet() {
493 return new TestMultiValuedMapKeySet();
494 }
495
496
497
498
499
500
501
502
503
504
505 public BulkTest bulkTestMultiValuedMapValues() {
506 return new TestMultiValuedMapValues();
507 }
508
509 @Override
510 public String getCompatibilityVersion() {
511 return "4.1";
512 }
513
514 public MultiValuedMap<K, V> getConfirmed() {
515 return confirmed;
516 }
517
518
519
520
521
522
523
524
525
526 protected int getIterationBehaviour() {
527 return 0;
528 }
529
530 public MultiValuedMap<K, V> getMap() {
531 return map;
532 }
533
534 public int getSampleCountPerKey() {
535 return 8;
536 }
537
538
539
540
541
542
543
544
545 @SuppressWarnings("unchecked")
546 public K[] getSampleKeys() {
547 final Object[] result = new Object[getSampleTotalValueCount()];
548 final int cpk = getSampleCountPerKey();
549 int k = 0;
550 for (int i = 0; i < result.length; i += cpk, k++) {
551 final K key = makeKey(k);
552 for (int j = 0; j < cpk; j++) {
553 result[i + j] = key;
554 }
555 }
556 return (K[]) result;
557 }
558
559 public int getSampleKeySize() {
560 return 256;
561 }
562
563 public int getSampleTotalValueCount() {
564 return getSampleCountPerKey() * getSampleKeySize();
565 }
566
567
568
569
570
571
572
573 @SuppressWarnings("unchecked")
574 public V[] getSampleValues() {
575 final Object[] result = new Object[getSampleTotalValueCount()];
576 final int cpk = getSampleCountPerKey();
577 int k = 0;
578 for (int i = 0; i < result.length; i += cpk, k++) {
579 for (int j = 0; j < cpk; j++) {
580 result[i + j] = makeValue(k, j);
581 }
582 }
583 return (V[]) result;
584 }
585
586
587
588
589
590
591
592
593
594
595 public boolean isAddSupported() {
596 return true;
597 }
598
599
600
601
602
603
604
605
606
607 public boolean isAllowNullKey() {
608 return true;
609 }
610
611
612
613
614
615
616
617
618
619 public boolean isHashSetValue() {
620 return false;
621 }
622
623
624
625
626
627
628
629
630
631
632 public boolean isRemoveSupported() {
633 return true;
634 }
635
636 @Override
637 public boolean isTestSerialization() {
638 return true;
639 }
640
641
642
643
644
645
646
647 public MultiValuedMap<K, V> makeConfirmedMap() {
648 return new ArrayListValuedHashMap<>();
649 }
650
651 protected MultiValuedMap<K, V> makeFullMap() {
652 final MultiValuedMap<K, V> map = makeObject();
653 addSampleMappings(map);
654 return map;
655 }
656
657 <E> E makeKey(final int key) {
658 return (E) new StringBuilder("k").append(key).toString();
659 }
660
661 @Override
662 public abstract MultiValuedMap<K, V> makeObject();
663
664 <E> E makeValue(final int key, final int value) {
665 return (E) new StringBuilder("v").append(key).append('_').append(value).toString();
666 }
667
668
669
670
671 public void resetEmpty() {
672 this.map = makeObject();
673 this.confirmed = makeConfirmedMap();
674 }
675
676
677
678
679 public void resetFull() {
680 this.map = makeFullMap();
681 this.confirmed = makeConfirmedMap();
682 final K[] k = getSampleKeys();
683 final V[] v = getSampleValues();
684 for (int i = 0; i < k.length; i++) {
685 confirmed.put(k[i], v[i]);
686 }
687 }
688
689
690
691
692
693
694
695
696 public void setConfirmed(final MultiValuedMap<K, V> map) {
697 this.confirmed = map;
698 }
699
700 @Test
701 @SuppressWarnings("unchecked")
702 public void testAddMappingThroughGet() {
703 assumeTrue(isAddSupported());
704 resetEmpty();
705 final MultiValuedMap<K, V> map = getMap();
706 final Collection<V> col1 = map.get((K) "k0");
707 final Collection<V> col2 = map.get((K) "k0");
708 assertTrue(col1.isEmpty());
709 assertTrue(col2.isEmpty());
710 assertEquals(0, map.size());
711 col1.add((V) "v1_1");
712 col2.add((V) "v0_1");
713 assertTrue(map.containsKey("k0"));
714 assertTrue(map.containsMapping("k0", "v1_1"));
715 assertTrue(map.containsMapping("k0", "v0_1"));
716 assertTrue(map.containsValue("v1_1"));
717 assertTrue(map.containsValue("v0_1"));
718 assertTrue(col1.contains("v0_1"));
719 assertTrue(col2.contains("v1_1"));
720 }
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747 @Test
748 public void testAsMapGet_Empty() {
749 resetEmpty();
750 final Map<K, Collection<V>> mapCol = getMap().asMap();
751 assertNull(mapCol.get("k0"));
752 assertEquals(0, mapCol.size());
753 }
754
755 @Test
756 public void testAsMapGet_Full() {
757 resetFull();
758 final Map<K, Collection<V>> mapCol = getMap().asMap();
759 final int maxK = getSampleKeySize();
760 final int maxV = getSampleCountPerKey();
761 for (int k = 0; k < maxK; k++) {
762 final Collection<V> col = mapCol.get(makeKey(k));
763 for (int v = 0; v < maxV; v++) {
764 assertTrue(col.contains(makeValue(k, v)));
765 }
766 }
767 }
768
769 @Test
770 public void testAsMapRemove() {
771 assumeTrue(isRemoveSupported());
772 resetFull();
773 final Map<K, Collection<V>> mapCol = getMap().asMap();
774 final int maxK = getSampleKeySize();
775 int expectedSize = getMap().size();
776 for (int k = 0; k < maxK; k++) {
777 final K key = makeKey(k);
778 mapCol.remove(key);
779 assertFalse(getMap().containsKey(key));
780 expectedSize -= getSampleCountPerKey();
781 assertEquals(expectedSize, getMap().size());
782 }
783 assertFalse(getMap().containsKey("k0"));
784 assertEquals(0, getMap().size());
785 }
786
787 @Test
788 public void testContainsValue() {
789 final MultiValuedMap<K, V> map = makeFullMap();
790 final int maxK = getSampleKeySize();
791 final int maxV = getSampleCountPerKey();
792 for (int k = 0; k < maxK; k++) {
793 for (int v = 0; v < maxV; v++) {
794 assertTrue(map.containsValue(makeValue(k, v)));
795 }
796 }
797 assertFalse(map.containsValue("quatro"));
798 }
799
800 @Test
801 @SuppressWarnings("unchecked")
802 public void testContainsValue_Key() {
803 final MultiValuedMap<K, V> map = makeFullMap();
804 final int maxK = getSampleKeySize();
805 final int maxV = getSampleCountPerKey();
806 for (int k = 0; k < maxK; k++) {
807 for (int v = 0; v < maxV; v++) {
808 assertTrue(map.containsMapping(makeKey(k), makeValue(k, v))); }
809 }
810 assertFalse(map.containsMapping("k1", "2"));
811 if (!isAddSupported()) {
812 return;
813 }
814 map.put((K) "A", (V) "AA");
815 assertTrue(map.containsMapping("A", "AA"));
816 assertFalse(map.containsMapping("A", "AB"));
817 }
818
819
820
821
822 @Test
823 public void testEmptyMapCompatibility() throws Exception {
824 final MultiValuedMap<?, ?> map = makeObject();
825 final MultiValuedMap<?, ?> map2 =
826 (MultiValuedMap<?, ?>) readExternalFormFromDisk(getCanonicalEmptyCollectionName(map));
827 assertEquals(0, map2.size(), "Map is empty");
828 }
829
830 @Test
831 public void testEntriesCollectionIterator() {
832 final MultiValuedMap<K, V> map = makeFullMap();
833 final Collection<V> values = new ArrayList<>(map.values());
834 for (final Entry<K, V> entry : map.entries()) {
835 assertTrue(map.containsMapping(entry.getKey(), entry.getValue()));
836 assertTrue(values.contains(entry.getValue()));
837 if (isRemoveSupported()) {
838 assertTrue(values.remove(entry.getValue()));
839 }
840 }
841 if (isRemoveSupported()) {
842 assertTrue(values.isEmpty());
843 }
844 }
845
846 @SuppressWarnings({ "rawtypes", "unchecked" })
847 @Test
848 @Disabled("There is no code to create this test fixture?")
849 public void testFullMapCompatibility() throws Exception {
850 final MultiValuedMap map = makeFullMap();
851 final MultiValuedMap map2 =
852 (MultiValuedMap) readExternalFormFromDisk(getCanonicalFullCollectionName(map));
853 assertEquals(map.size(), map2.size(), "Map is the right size");
854 for (final Object key : map.keySet()) {
855 assertTrue(CollectionUtils.isEqualCollection(map.get(key), map2.get(key)),
856 "Map had inequal elements");
857 if (isRemoveSupported()) {
858 map2.remove(key);
859 }
860 }
861 if (isRemoveSupported()) {
862 assertEquals(0, map2.size(), "Map had extra values");
863 }
864 }
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889 @Test
890 @SuppressWarnings("unchecked")
891 public void testGet() {
892 final MultiValuedMap<K, V> map = makeFullMap();
893 final int maxK = getSampleKeySize();
894 final int maxV = getSampleCountPerKey();
895 for (int k = 0; k < maxK; k++) {
896 for (int v = 0; v < maxV; v++) {
897 assertTrue(map.get((K) makeKey(k)).contains(makeValue(k, v)));
898 }
899 }
900 }
901
902 @Test
903 public void testKeyContainsValue() {
904 final MultiValuedMap<K, V> map = makeFullMap();
905 final int maxK = getSampleKeySize();
906 final int maxV = getSampleCountPerKey();
907 for (int k = 0; k < maxK; k++) {
908 for (int v = 0; v < maxV; v++) {
909 assertTrue(map.containsMapping(makeKey(k), makeValue(k, v)));
910 }
911 }
912 assertFalse(map.containsMapping("k", "v"));
913 }
914
915 @Test
916 @SuppressWarnings({ "unchecked", "cast" })
917 public void testKeysBagContainsAll() {
918 final MultiValuedMap<K, V> map = makeFullMap();
919 final MultiSet<K> keyMultiSet = map.keys();
920
921 final List<String> col = new ArrayList<>();
922 final int maxK = getSampleKeySize();
923 for (int k = 0; k < maxK; k++) {
924 col.add(makeKey(k));
925 }
926 for (int k = 0; k < maxK; k++) {
927 col.add(makeKey(k));
928 }
929
930 assertTrue(keyMultiSet.containsAll((Collection<K>) col));
931 }
932
933 @Test
934 public void testKeysBagIterator() {
935 final MultiValuedMap<K, V> map = makeFullMap();
936 final Collection<K> col = new ArrayList<>(map.keys());
937 final Bag<K> bag = new HashBag<>(col);
938 final int maxK = getSampleKeySize();
939 for (int k = 0; k < maxK; k++) {
940 assertEquals(getSampleCountPerKey(), bag.getCount(makeKey(k)));
941 }
942 assertEquals(getSampleTotalValueCount(), bag.size());
943 }
944
945 @Test
946 public void testKeySetSize() {
947 final MultiValuedMap<K, V> map = makeFullMap();
948 assertEquals(getSampleKeySize(), map.keySet().size());
949 }
950
951 @Test
952 public void testKeysMultiSet() {
953 final MultiValuedMap<K, V> map = makeFullMap();
954 final MultiSet<K> keyMultiSet = map.keys();
955 final int maxK = getSampleKeySize();
956 for (int k = 0; k < maxK; k++) {
957 assertEquals(getSampleCountPerKey(), keyMultiSet.getCount(makeKey(k)));
958 }
959 assertEquals(0, keyMultiSet.getCount("conut"));
960 assertEquals(getSampleTotalValueCount(), keyMultiSet.size());
961 }
962
963 @Test
964 @SuppressWarnings("unchecked")
965 public void testMapEquals() {
966 assumeTrue(isAddSupported());
967 final MultiValuedMap<K, V> one = makeObject();
968 final Integer value = Integer.valueOf(1);
969 one.put((K) "One", (V) value);
970 one.removeMapping("One", value);
971
972 final MultiValuedMap<K, V> two = makeObject();
973 assertEquals(two, one);
974 }
975
976 @Test
977 public void testMapIterator() {
978 resetEmpty();
979 MapIterator<K, V> mapIt = getMap().mapIterator();
980 assertFalse(mapIt.hasNext());
981
982 resetFull();
983 mapIt = getMap().mapIterator();
984 while (mapIt.hasNext()) {
985 final K key = mapIt.next();
986 final V value = mapIt.getValue();
987 assertTrue(getMap().containsMapping(key, value));
988 }
989 }
990
991 @Test
992 public void testMapIteratorRemove() {
993 assumeTrue(isRemoveSupported());
994 resetFull();
995 final MapIterator<K, V> mapIt = getMap().mapIterator();
996 while (mapIt.hasNext()) {
997 mapIt.next();
998 mapIt.remove();
999 }
1000 assertTrue(getMap().isEmpty());
1001 }
1002
1003 @Test
1004 @SuppressWarnings("unchecked")
1005 public void testMapIteratorUnsupportedSet() {
1006 resetFull();
1007 final MapIterator<K, V> mapIt = getMap().mapIterator();
1008 mapIt.next();
1009 assertThrows(UnsupportedOperationException.class, () -> mapIt.setValue((V) "some value"));
1010 }
1011
1012 @Test
1013 public void testMultipleValues() {
1014 final MultiValuedMap<K, V> map = makeFullMap();
1015 final int maxK = getSampleKeySize();
1016 final int maxV = getSampleCountPerKey();
1017 for (int k = 0; k < maxK; k++) {
1018 final Collection<V> col = map.get(makeKey(k));
1019 for (int v = 0; v < maxV; v++) {
1020 assertTrue(col.contains(makeValue(k, v)));
1021 }
1022 }
1023
1024 }
1025
1026 @Test
1027 public void testMultiValuedMapIterator() {
1028 final MultiValuedMap<K, V> map = makeFullMap();
1029 final MapIterator<K, V> it = map.mapIterator();
1030 assertThrows(IllegalStateException.class, () -> it.getKey());
1031 assertThrows(IllegalStateException.class, () -> it.getValue());
1032 if (isAddSupported()) {
1033 assertThrows(IllegalStateException.class, () -> it.setValue((V) "V"));
1034 }
1035 if (!isHashSetValue() && isAddSupported()) {
1036 assertTrue(it.hasNext());
1037 final MultiValuedMap<K, V> dejaVu = makeObject();
1038 while (it.hasNext()) {
1039 final K next = it.next();
1040 assertNotNull(next);
1041 final K itKey = it.getKey();
1042 assertEquals(next, itKey);
1043 final V itValue = it.getValue();
1044 dejaVu.put(itKey, itValue);
1045 assertThrows(UnsupportedOperationException.class, () -> it.setValue((V) "threetrois"));
1046 }
1047 assertEquals(map, dejaVu);
1048 assertEquals(dejaVu, map);
1049 assertThrows(UnsupportedOperationException.class, () -> it.setValue((V) "threetrois"));
1050 }
1051 }
1052
1053 @Test
1054 @SuppressWarnings("unchecked")
1055 public void testNoMappingReturnsEmptyCol() {
1056 final MultiValuedMap<K, V> map = makeFullMap();
1057 assertTrue(map.get((K) "whatever").isEmpty());
1058 }
1059
1060 @Test
1061 @SuppressWarnings("unchecked")
1062 public void testPutAll_KeyIterable() {
1063 assumeTrue(isAddSupported());
1064 final MultiValuedMap<K, V> map = makeObject();
1065 Collection<V> coll = (Collection<V>) Arrays.asList("X", "Y", "Z");
1066
1067 assertTrue(map.putAll((K) "A", coll));
1068 assertEquals(3, map.get((K) "A").size());
1069 assertTrue(map.containsMapping("A", "X"));
1070 assertTrue(map.containsMapping("A", "Y"));
1071 assertTrue(map.containsMapping("A", "Z"));
1072
1073 assertThrows(NullPointerException.class, () -> map.putAll((K) "A", null),
1074 "expecting NullPointerException");
1075
1076 assertEquals(3, map.get((K) "A").size());
1077 assertTrue(map.containsMapping("A", "X"));
1078 assertTrue(map.containsMapping("A", "Y"));
1079 assertTrue(map.containsMapping("A", "Z"));
1080
1081 assertFalse(map.putAll((K) "A", new ArrayList<>()));
1082 assertEquals(3, map.get((K) "A").size());
1083 assertTrue(map.containsMapping("A", "X"));
1084 assertTrue(map.containsMapping("A", "Y"));
1085 assertTrue(map.containsMapping("A", "Z"));
1086
1087 coll = (Collection<V>) Arrays.asList("M");
1088 assertTrue(map.putAll((K) "A", coll));
1089 assertEquals(4, map.get((K) "A").size());
1090 assertTrue(map.containsMapping("A", "X"));
1091 assertTrue(map.containsMapping("A", "Y"));
1092 assertTrue(map.containsMapping("A", "Z"));
1093 assertTrue(map.containsMapping("A", "M"));
1094 }
1095
1096 @Test
1097 @SuppressWarnings("unchecked")
1098 public void testPutAll_Map1() {
1099 assumeTrue(isAddSupported());
1100 final MultiValuedMap<K, V> original = makeObject();
1101 original.put((K) "key", (V) "object1");
1102 original.put((K) "key", (V) "object2");
1103
1104 final MultiValuedMap<K, V> test = makeObject();
1105 test.put((K) "keyA", (V) "objectA");
1106 test.put((K) "key", (V) "object0");
1107 test.putAll(original);
1108
1109 final MultiValuedMap<K, V> originalNull = null;
1110 assertThrows(NullPointerException.class, () -> test.putAll(originalNull),
1111 "expecting NullPointerException");
1112
1113 assertEquals(2, test.keySet().size());
1114 assertEquals(4, test.size());
1115 assertEquals(1, test.get((K) "keyA").size());
1116 assertEquals(3, test.get((K) "key").size());
1117 assertTrue(test.containsValue("objectA"));
1118 assertTrue(test.containsValue("object0"));
1119 assertTrue(test.containsValue("object1"));
1120 assertTrue(test.containsValue("object2"));
1121 }
1122
1123 @Test
1124 @SuppressWarnings("unchecked")
1125 public void testPutAll_Map2() {
1126 assumeTrue(isAddSupported());
1127 final Map<K, V> original = new HashMap<>();
1128 original.put((K) "keyX", (V) "object1");
1129 original.put((K) "keyY", (V) "object2");
1130
1131 final MultiValuedMap<K, V> test = makeObject();
1132 test.put((K) "keyA", (V) "objectA");
1133 test.put((K) "keyX", (V) "object0");
1134 test.putAll(original);
1135
1136 final Map<K, V> originalNull = null;
1137 assertThrows(NullPointerException.class, () -> test.putAll(originalNull),
1138 "expecting NullPointerException");
1139
1140 assertEquals(3, test.keySet().size());
1141 assertEquals(4, test.size());
1142 assertEquals(1, test.get((K) "keyA").size());
1143 assertEquals(2, test.get((K) "keyX").size());
1144 assertEquals(1, test.get((K) "keyY").size());
1145 assertTrue(test.containsValue("objectA"));
1146 assertTrue(test.containsValue("object0"));
1147 assertTrue(test.containsValue("object1"));
1148 assertTrue(test.containsValue("object2"));
1149 }
1150
1151 @Test
1152 @SuppressWarnings("unchecked")
1153 public void testRemove_KeyItem() {
1154 assumeTrue(isAddSupported());
1155 assumeTrue(isRemoveSupported());
1156 final MultiValuedMap<K, V> map = makeObject();
1157 map.put((K) "A", (V) "AA");
1158 map.put((K) "A", (V) "AB");
1159 map.put((K) "A", (V) "AC");
1160 assertFalse(map.removeMapping("C", "CA"));
1161 assertFalse(map.removeMapping("A", "AD"));
1162 assertTrue(map.removeMapping("A", "AC"));
1163 assertTrue(map.removeMapping("A", "AB"));
1164 assertTrue(map.removeMapping("A", "AA"));
1165
1166 }
1167
1168 @Test
1169 @SuppressWarnings("unchecked")
1170 public void testRemoveAllViaEntriesIterator() {
1171 assumeTrue(isRemoveSupported());
1172 final MultiValuedMap<K, V> map = makeFullMap();
1173 for (final Iterator<?> i = map.entries().iterator(); i.hasNext();) {
1174 i.next();
1175 i.remove();
1176 }
1177 assertTrue(map.get((K) "k0").isEmpty());
1178 assertEquals(0, map.size());
1179 }
1180
1181 @Test
1182 @SuppressWarnings("unchecked")
1183 public void testRemoveAllViaValuesIterator() {
1184 assumeTrue(isRemoveSupported());
1185 final MultiValuedMap<K, V> map = makeFullMap();
1186 for (final Iterator<?> i = map.values().iterator(); i.hasNext();) {
1187 i.next();
1188 i.remove();
1189 }
1190 assertTrue(map.get((K) "k0").isEmpty());
1191 assertTrue(map.isEmpty());
1192 }
1193
1194 @Test
1195 public void testRemoveMappingThroughGet() {
1196 assumeTrue(isRemoveSupported());
1197 resetFull();
1198 final MultiValuedMap<K, V> map = getMap();
1199 final int cpk = getSampleCountPerKey();
1200 int expectedCount = getSampleTotalValueCount();
1201 assertEquals(expectedCount, map.size());
1202 for (int k = 0; k < getSampleKeySize(); k++) {
1203 final Object key = makeKey(k);
1204 @SuppressWarnings("unchecked")
1205 Collection<V> col = map.get((K) key);
1206 assertEquals(cpk, col.size());
1207 for (int i = 0; i < cpk; i++) {
1208 final Object value = makeValue(k, i);
1209 assertTrue(col.remove(value), () -> value.toString());
1210 }
1211 for (int i = 0; i < cpk; i++) {
1212 assertFalse(col.remove(makeValue(k, i)));
1213 }
1214 assertFalse(map.containsKey(key));
1215 for (int i = 0; i < cpk; i++) {
1216 assertFalse(map.containsMapping(key, i));
1217 }
1218 for (int i = 0; i < cpk; i++) {
1219 assertFalse(map.containsValue(makeValue(k, i)));
1220 }
1221 expectedCount -= cpk;
1222 assertEquals(expectedCount, map.size());
1223 col = map.remove(key);
1224 assertNotNull(col);
1225 assertEquals(0, col.size());
1226 }
1227 }
1228
1229 @Test
1230 public void testRemoveMappingThroughGetIterator() {
1231 assumeTrue(isRemoveSupported());
1232 resetFull();
1233 final MultiValuedMap<K, V> map = getMap();
1234 int expectedSize = map.size();
1235 final int maxK = getSampleKeySize();
1236 for (int k = 0; k < maxK; k++) {
1237 final String key = makeKey(k);
1238 final int cpk = getSampleCountPerKey();
1239 @SuppressWarnings("unchecked")
1240 final Iterator<V> it = map.get((K) key).iterator();
1241 while (it.hasNext()) {
1242 it.next();
1243 it.remove();
1244 }
1245 assertFalse(map.containsKey(key));
1246 for (int j = 0; j < cpk; j++) {
1247 assertFalse(map.containsMapping(key, makeValue(k + 1, j)));
1248 final Object value = makeValue(k, j);
1249 assertFalse(map.containsMapping(key, value));
1250 assertFalse(map.containsValue(value));
1251 }
1252 expectedSize -= cpk;
1253 assertEquals(expectedSize, map.size());
1254 final Collection<V> coll = map.remove("k0");
1255 assertNotNull(coll);
1256 assertEquals(0, coll.size());
1257 }
1258 }
1259
1260 @Test
1261 public void testRemoveViaValuesRemove() {
1262 assumeTrue(isRemoveSupported());
1263 final MultiValuedMap<K, V> map = makeFullMap();
1264 final Collection<V> values = map.values();
1265 final int maxK = getSampleKeySize();
1266 final int maxV = getSampleCountPerKey();
1267 int expectedSize = map.size();
1268 for (int k = 0; k < maxK; k++) {
1269 for (int v = 0; v < maxV; v++) {
1270 values.remove(makeValue(k, v));
1271 }
1272 assertFalse(map.containsKey(makeKey(k)));
1273 expectedSize -= maxV;
1274 assertEquals(expectedSize, map.size());
1275 }
1276 assertEquals(0, map.size());
1277 }
1278
1279 @Test
1280 public void testSize() {
1281 assertEquals(getSampleTotalValueCount(), makeFullMap().size());
1282 }
1283
1284 @Test
1285 @SuppressWarnings("unchecked")
1286 public void testSize_Key() {
1287 final MultiValuedMap<K, V> map = makeFullMap();
1288 final int maxK = getSampleKeySize();
1289 for (int k = 0; k < maxK; k++) {
1290 assertEquals(getSampleCountPerKey(), map.get((K) makeKey(k)).size());
1291 }
1292 if (!isAddSupported()) {
1293 return;
1294 }
1295 map.put((K) "A", (V) "AA");
1296 assertEquals(1, map.get((K) "A").size());
1297
1298 map.put((K) "B", (V) "BA");
1299 assertEquals(1, map.get((K) "A").size());
1300 assertEquals(1, map.get((K) "B").size());
1301 map.put((K) "B", (V) "BB");
1302 assertEquals(1, map.get((K) "A").size());
1303 assertEquals(2, map.get((K) "B").size());
1304 map.put((K) "B", (V) "BC");
1305 assertEquals(1, map.get((K) "A").size());
1306 assertEquals(3, map.get((K) "B").size());
1307 if (!isRemoveSupported()) {
1308 return;
1309 }
1310 map.remove("A");
1311
1312 assertEquals(3, map.get((K) "B").size());
1313 map.removeMapping("B", "BC");
1314
1315 assertEquals(2, map.get((K) "B").size());
1316 }
1317
1318 @Test
1319 @SuppressWarnings("unchecked")
1320 public void testSizeWithPutRemove() {
1321 assumeTrue(isAddSupported());
1322 assumeTrue(isRemoveSupported());
1323 final MultiValuedMap<K, V> map = makeObject();
1324 assertEquals(0, map.size());
1325 map.put((K) "A", (V) "AA");
1326 assertEquals(1, map.size());
1327 map.put((K) "B", (V) "BA");
1328 assertEquals(2, map.size());
1329 map.put((K) "B", (V) "BB");
1330 assertEquals(3, map.size());
1331 map.put((K) "B", (V) "BC");
1332 assertEquals(4, map.size());
1333 map.remove("A");
1334 assertEquals(3, map.size());
1335 map.removeMapping("B", "BC");
1336 assertEquals(2, map.size());
1337 }
1338
1339 @Test
1340 public void testToString() {
1341 assumeTrue(isAddSupported());
1342 final MultiValuedMap<K, V> map = makeObject();
1343 map.put((K) "A", (V) "X");
1344 map.put((K) "A", (V) "Y");
1345 map.put((K) "A", (V) "Z");
1346 map.put((K) "B", (V) "U");
1347 map.put((K) "B", (V) "V");
1348 map.put((K) "B", (V) "W");
1349 assertTrue("{A=[X, Y, Z], B=[U, V, W]}".equals(map.toString()) || "{B=[U, V, W], A=[X, Y, Z]}".equals(map.toString()));
1350
1351 final MultiValuedMap<K, V> originalNull = null;
1352 assertThrows(NullPointerException.class, () -> map.putAll(originalNull), "expecting NullPointerException");
1353 assertTrue("{A=[X, Y, Z], B=[U, V, W]}".equals(map.toString()) || "{B=[U, V, W], A=[X, Y, Z]}".equals(map.toString()));
1354
1355 map.remove("A");
1356 map.remove("B");
1357 assertEquals("{}", map.toString());
1358 }
1359
1360 @Test
1361 @SuppressWarnings("unchecked")
1362 public void testValues() {
1363 final MultiValuedMap<K, V> map = makeFullMap();
1364 final HashSet<V> expected = new HashSet<>();
1365 final int maxK = getSampleKeySize();
1366 final int maxV = getSampleCountPerKey();
1367 for (int k = 0; k < maxK; k++) {
1368 for (int v = 0; v < maxV; v++) {
1369 expected.add((V) makeValue(k, v));
1370 }
1371 }
1372 final Collection<V> c = map.values();
1373 assertEquals(getSampleTotalValueCount(), c.size());
1374 assertEquals(expected, new HashSet<>(c));
1375 }
1376
1377 }