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