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 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<>();
937 for (K element : map.keys()) {
938 col.add(element);
939 }
940 final Bag<K> bag = new HashBag<>(col);
941 final int maxK = getSampleKeySize();
942 for (int k = 0; k < maxK; k++) {
943 assertEquals(getSampleCountPerKey(), bag.getCount(makeKey(k)));
944 }
945 assertEquals(getSampleTotalValueCount(), bag.size());
946 }
947
948 @Test
949 public void testKeySetSize() {
950 final MultiValuedMap<K, V> map = makeFullMap();
951 assertEquals(getSampleKeySize(), map.keySet().size());
952 }
953
954 @Test
955 public void testKeysMultiSet() {
956 final MultiValuedMap<K, V> map = makeFullMap();
957 final MultiSet<K> keyMultiSet = map.keys();
958 final int maxK = getSampleKeySize();
959 for (int k = 0; k < maxK; k++) {
960 assertEquals(getSampleCountPerKey(), keyMultiSet.getCount(makeKey(k)));
961 }
962 assertEquals(0, keyMultiSet.getCount("conut"));
963 assertEquals(getSampleTotalValueCount(), keyMultiSet.size());
964 }
965
966 @Test
967 @SuppressWarnings("unchecked")
968 public void testMapEquals() {
969 assumeTrue(isAddSupported());
970 final MultiValuedMap<K, V> one = makeObject();
971 final Integer value = Integer.valueOf(1);
972 one.put((K) "One", (V) value);
973 one.removeMapping("One", value);
974
975 final MultiValuedMap<K, V> two = makeObject();
976 assertEquals(two, one);
977 }
978
979 @Test
980 public void testMapIterator() {
981 resetEmpty();
982 MapIterator<K, V> mapIt = getMap().mapIterator();
983 assertFalse(mapIt.hasNext());
984
985 resetFull();
986 mapIt = getMap().mapIterator();
987 while (mapIt.hasNext()) {
988 final K key = mapIt.next();
989 final V value = mapIt.getValue();
990 assertTrue(getMap().containsMapping(key, value));
991 }
992 }
993
994 @Test
995 public void testMapIteratorRemove() {
996 assumeTrue(isRemoveSupported());
997 resetFull();
998 final MapIterator<K, V> mapIt = getMap().mapIterator();
999 while (mapIt.hasNext()) {
1000 mapIt.next();
1001 mapIt.remove();
1002 }
1003 assertTrue(getMap().isEmpty());
1004 }
1005
1006 @Test
1007 @SuppressWarnings("unchecked")
1008 public void testMapIteratorUnsupportedSet() {
1009 resetFull();
1010 final MapIterator<K, V> mapIt = getMap().mapIterator();
1011 mapIt.next();
1012 assertThrows(UnsupportedOperationException.class, () -> mapIt.setValue((V) "some value"));
1013 }
1014
1015 @Test
1016 public void testMultipleValues() {
1017 final MultiValuedMap<K, V> map = makeFullMap();
1018 final int maxK = getSampleKeySize();
1019 final int maxV = getSampleCountPerKey();
1020 for (int k = 0; k < maxK; k++) {
1021 final Collection<V> col = map.get(makeKey(k));
1022 for (int v = 0; v < maxV; v++) {
1023 assertTrue(col.contains(makeValue(k, v)));
1024 }
1025 }
1026
1027 }
1028
1029 @Test
1030 public void testMultiValuedMapIterator() {
1031 final MultiValuedMap<K, V> map = makeFullMap();
1032 final MapIterator<K, V> it = map.mapIterator();
1033 assertThrows(IllegalStateException.class, () -> it.getKey());
1034 assertThrows(IllegalStateException.class, () -> it.getValue());
1035 if (isAddSupported()) {
1036 assertThrows(IllegalStateException.class, () -> it.setValue((V) "V"));
1037 }
1038 if (!isHashSetValue() && isAddSupported()) {
1039 assertTrue(it.hasNext());
1040 final MultiValuedMap<K, V> dejaVu = makeObject();
1041 while (it.hasNext()) {
1042 final K next = it.next();
1043 assertNotNull(next);
1044 final K itKey = it.getKey();
1045 assertEquals(next, itKey);
1046 final V itValue = it.getValue();
1047 dejaVu.put(itKey, itValue);
1048 assertThrows(UnsupportedOperationException.class, () -> it.setValue((V) "threetrois"));
1049 }
1050 assertEquals(map, dejaVu);
1051 assertEquals(dejaVu, map);
1052 assertThrows(UnsupportedOperationException.class, () -> it.setValue((V) "threetrois"));
1053 }
1054 }
1055
1056 @Test
1057 @SuppressWarnings("unchecked")
1058 public void testNoMappingReturnsEmptyCol() {
1059 final MultiValuedMap<K, V> map = makeFullMap();
1060 assertTrue(map.get((K) "whatever").isEmpty());
1061 }
1062
1063 @Test
1064 @SuppressWarnings("unchecked")
1065 public void testPutAll_KeyIterable() {
1066 assumeTrue(isAddSupported());
1067 final MultiValuedMap<K, V> map = makeObject();
1068 Collection<V> coll = (Collection<V>) Arrays.asList("X", "Y", "Z");
1069
1070 assertTrue(map.putAll((K) "A", coll));
1071 assertEquals(3, map.get((K) "A").size());
1072 assertTrue(map.containsMapping("A", "X"));
1073 assertTrue(map.containsMapping("A", "Y"));
1074 assertTrue(map.containsMapping("A", "Z"));
1075
1076 assertThrows(NullPointerException.class, () -> map.putAll((K) "A", null),
1077 "expecting NullPointerException");
1078
1079 assertEquals(3, map.get((K) "A").size());
1080 assertTrue(map.containsMapping("A", "X"));
1081 assertTrue(map.containsMapping("A", "Y"));
1082 assertTrue(map.containsMapping("A", "Z"));
1083
1084 assertFalse(map.putAll((K) "A", new ArrayList<>()));
1085 assertEquals(3, map.get((K) "A").size());
1086 assertTrue(map.containsMapping("A", "X"));
1087 assertTrue(map.containsMapping("A", "Y"));
1088 assertTrue(map.containsMapping("A", "Z"));
1089
1090 coll = (Collection<V>) Arrays.asList("M");
1091 assertTrue(map.putAll((K) "A", coll));
1092 assertEquals(4, map.get((K) "A").size());
1093 assertTrue(map.containsMapping("A", "X"));
1094 assertTrue(map.containsMapping("A", "Y"));
1095 assertTrue(map.containsMapping("A", "Z"));
1096 assertTrue(map.containsMapping("A", "M"));
1097 }
1098
1099 @Test
1100 @SuppressWarnings("unchecked")
1101 public void testPutAll_Map1() {
1102 assumeTrue(isAddSupported());
1103 final MultiValuedMap<K, V> original = makeObject();
1104 original.put((K) "key", (V) "object1");
1105 original.put((K) "key", (V) "object2");
1106
1107 final MultiValuedMap<K, V> test = makeObject();
1108 test.put((K) "keyA", (V) "objectA");
1109 test.put((K) "key", (V) "object0");
1110 test.putAll(original);
1111
1112 final MultiValuedMap<K, V> originalNull = null;
1113 assertThrows(NullPointerException.class, () -> test.putAll(originalNull),
1114 "expecting NullPointerException");
1115
1116 assertEquals(2, test.keySet().size());
1117 assertEquals(4, test.size());
1118 assertEquals(1, test.get((K) "keyA").size());
1119 assertEquals(3, test.get((K) "key").size());
1120 assertTrue(test.containsValue("objectA"));
1121 assertTrue(test.containsValue("object0"));
1122 assertTrue(test.containsValue("object1"));
1123 assertTrue(test.containsValue("object2"));
1124 }
1125
1126 @Test
1127 @SuppressWarnings("unchecked")
1128 public void testPutAll_Map2() {
1129 assumeTrue(isAddSupported());
1130 final Map<K, V> original = new HashMap<>();
1131 original.put((K) "keyX", (V) "object1");
1132 original.put((K) "keyY", (V) "object2");
1133
1134 final MultiValuedMap<K, V> test = makeObject();
1135 test.put((K) "keyA", (V) "objectA");
1136 test.put((K) "keyX", (V) "object0");
1137 test.putAll(original);
1138
1139 final Map<K, V> originalNull = null;
1140 assertThrows(NullPointerException.class, () -> test.putAll(originalNull),
1141 "expecting NullPointerException");
1142
1143 assertEquals(3, test.keySet().size());
1144 assertEquals(4, test.size());
1145 assertEquals(1, test.get((K) "keyA").size());
1146 assertEquals(2, test.get((K) "keyX").size());
1147 assertEquals(1, test.get((K) "keyY").size());
1148 assertTrue(test.containsValue("objectA"));
1149 assertTrue(test.containsValue("object0"));
1150 assertTrue(test.containsValue("object1"));
1151 assertTrue(test.containsValue("object2"));
1152 }
1153
1154 @Test
1155 @SuppressWarnings("unchecked")
1156 public void testRemove_KeyItem() {
1157 assumeTrue(isAddSupported());
1158 assumeTrue(isRemoveSupported());
1159 final MultiValuedMap<K, V> map = makeObject();
1160 map.put((K) "A", (V) "AA");
1161 map.put((K) "A", (V) "AB");
1162 map.put((K) "A", (V) "AC");
1163 assertFalse(map.removeMapping("C", "CA"));
1164 assertFalse(map.removeMapping("A", "AD"));
1165 assertTrue(map.removeMapping("A", "AC"));
1166 assertTrue(map.removeMapping("A", "AB"));
1167 assertTrue(map.removeMapping("A", "AA"));
1168
1169 }
1170
1171 @Test
1172 @SuppressWarnings("unchecked")
1173 public void testRemoveAllViaEntriesIterator() {
1174 assumeTrue(isRemoveSupported());
1175 final MultiValuedMap<K, V> map = makeFullMap();
1176 for (final Iterator<?> i = map.entries().iterator(); i.hasNext();) {
1177 i.next();
1178 i.remove();
1179 }
1180 assertTrue(map.get((K) "k0").isEmpty());
1181 assertEquals(0, map.size());
1182 }
1183
1184 @Test
1185 @SuppressWarnings("unchecked")
1186 public void testRemoveAllViaValuesIterator() {
1187 assumeTrue(isRemoveSupported());
1188 final MultiValuedMap<K, V> map = makeFullMap();
1189 for (final Iterator<?> i = map.values().iterator(); i.hasNext();) {
1190 i.next();
1191 i.remove();
1192 }
1193 assertTrue(map.get((K) "k0").isEmpty());
1194 assertTrue(map.isEmpty());
1195 }
1196
1197 @Test
1198 public void testRemoveMappingThroughGet() {
1199 assumeTrue(isRemoveSupported());
1200 resetFull();
1201 final MultiValuedMap<K, V> map = getMap();
1202 final int cpk = getSampleCountPerKey();
1203 int expectedCount = getSampleTotalValueCount();
1204 assertEquals(expectedCount, map.size());
1205 for (int k = 0; k < getSampleKeySize(); k++) {
1206 final Object key = makeKey(k);
1207 @SuppressWarnings("unchecked")
1208 Collection<V> col = map.get((K) key);
1209 assertEquals(cpk, col.size());
1210 for (int i = 0; i < cpk; i++) {
1211 final Object value = makeValue(k, i);
1212 assertTrue(col.remove(value), () -> value.toString());
1213 }
1214 for (int i = 0; i < cpk; i++) {
1215 assertFalse(col.remove(makeValue(k, i)));
1216 }
1217 assertFalse(map.containsKey(key));
1218 for (int i = 0; i < cpk; i++) {
1219 assertFalse(map.containsMapping(key, i));
1220 }
1221 for (int i = 0; i < cpk; i++) {
1222 assertFalse(map.containsValue(makeValue(k, i)));
1223 }
1224 expectedCount -= cpk;
1225 assertEquals(expectedCount, map.size());
1226 col = map.remove(key);
1227 assertNotNull(col);
1228 assertEquals(0, col.size());
1229 }
1230 }
1231
1232 @Test
1233 public void testRemoveMappingThroughGetIterator() {
1234 assumeTrue(isRemoveSupported());
1235 resetFull();
1236 final MultiValuedMap<K, V> map = getMap();
1237 int expectedSize = map.size();
1238 final int maxK = getSampleKeySize();
1239 for (int k = 0; k < maxK; k++) {
1240 final String key = makeKey(k);
1241 final int cpk = getSampleCountPerKey();
1242 @SuppressWarnings("unchecked")
1243 final Iterator<V> it = map.get((K) key).iterator();
1244 while (it.hasNext()) {
1245 it.next();
1246 it.remove();
1247 }
1248 assertFalse(map.containsKey(key));
1249 for (int j = 0; j < cpk; j++) {
1250 assertFalse(map.containsMapping(key, makeValue(k + 1, j)));
1251 final Object value = makeValue(k, j);
1252 assertFalse(map.containsMapping(key, value));
1253 assertFalse(map.containsValue(value));
1254 }
1255 expectedSize -= cpk;
1256 assertEquals(expectedSize, map.size());
1257 final Collection<V> coll = map.remove("k0");
1258 assertNotNull(coll);
1259 assertEquals(0, coll.size());
1260 }
1261 }
1262
1263 @Test
1264 public void testRemoveViaValuesRemove() {
1265 assumeTrue(isRemoveSupported());
1266 final MultiValuedMap<K, V> map = makeFullMap();
1267 final Collection<V> values = map.values();
1268 final int maxK = getSampleKeySize();
1269 final int maxV = getSampleCountPerKey();
1270 int expectedSize = map.size();
1271 for (int k = 0; k < maxK; k++) {
1272 for (int v = 0; v < maxV; v++) {
1273 values.remove(makeValue(k, v));
1274 }
1275 assertFalse(map.containsKey(makeKey(k)));
1276 expectedSize -= maxV;
1277 assertEquals(expectedSize, map.size());
1278 }
1279 assertEquals(0, map.size());
1280 }
1281
1282 @Test
1283 public void testSize() {
1284 assertEquals(getSampleTotalValueCount(), makeFullMap().size());
1285 }
1286
1287 @Test
1288 @SuppressWarnings("unchecked")
1289 public void testSize_Key() {
1290 final MultiValuedMap<K, V> map = makeFullMap();
1291 final int maxK = getSampleKeySize();
1292 for (int k = 0; k < maxK; k++) {
1293 assertEquals(getSampleCountPerKey(), map.get((K) makeKey(k)).size());
1294 }
1295 if (!isAddSupported()) {
1296 return;
1297 }
1298 map.put((K) "A", (V) "AA");
1299 assertEquals(1, map.get((K) "A").size());
1300
1301 map.put((K) "B", (V) "BA");
1302 assertEquals(1, map.get((K) "A").size());
1303 assertEquals(1, map.get((K) "B").size());
1304 map.put((K) "B", (V) "BB");
1305 assertEquals(1, map.get((K) "A").size());
1306 assertEquals(2, map.get((K) "B").size());
1307 map.put((K) "B", (V) "BC");
1308 assertEquals(1, map.get((K) "A").size());
1309 assertEquals(3, map.get((K) "B").size());
1310 if (!isRemoveSupported()) {
1311 return;
1312 }
1313 map.remove("A");
1314
1315 assertEquals(3, map.get((K) "B").size());
1316 map.removeMapping("B", "BC");
1317
1318 assertEquals(2, map.get((K) "B").size());
1319 }
1320
1321 @Test
1322 @SuppressWarnings("unchecked")
1323 public void testSizeWithPutRemove() {
1324 assumeTrue(isAddSupported());
1325 assumeTrue(isRemoveSupported());
1326 final MultiValuedMap<K, V> map = makeObject();
1327 assertEquals(0, map.size());
1328 map.put((K) "A", (V) "AA");
1329 assertEquals(1, map.size());
1330 map.put((K) "B", (V) "BA");
1331 assertEquals(2, map.size());
1332 map.put((K) "B", (V) "BB");
1333 assertEquals(3, map.size());
1334 map.put((K) "B", (V) "BC");
1335 assertEquals(4, map.size());
1336 map.remove("A");
1337 assertEquals(3, map.size());
1338 map.removeMapping("B", "BC");
1339 assertEquals(2, map.size());
1340 }
1341
1342 @Test
1343 public void testToString(){
1344 assumeTrue(isAddSupported());
1345 final MultiValuedMap<K, V> map = makeObject();
1346 map.put((K) "A", (V) "X");
1347 map.put((K) "A", (V) "Y");
1348 map.put((K) "A", (V) "Z");
1349 map.put((K) "B", (V) "U");
1350 map.put((K) "B", (V) "V");
1351 map.put((K) "B", (V) "W");
1352 assertTrue(
1353 "{A=[X, Y, Z], B=[U, V, W]}".equals(map.toString()) ||
1354 "{B=[U, V, W], A=[X, Y, Z]}".equals(map.toString())
1355 );
1356
1357 final MultiValuedMap<K, V> originalNull = null;
1358 assertThrows(NullPointerException.class, () -> map.putAll(originalNull),
1359 "expecting NullPointerException");
1360 assertTrue(
1361 "{A=[X, Y, Z], B=[U, V, W]}".equals(map.toString()) ||
1362 "{B=[U, V, W], A=[X, Y, Z]}".equals(map.toString())
1363 );
1364
1365 map.remove("A");
1366 map.remove("B");
1367 assertEquals("{}", map.toString());
1368 }
1369
1370 @Test
1371 @SuppressWarnings("unchecked")
1372 public void testValues() {
1373 final MultiValuedMap<K, V> map = makeFullMap();
1374 final HashSet<V> expected = new HashSet<>();
1375 final int maxK = getSampleKeySize();
1376 final int maxV = getSampleCountPerKey();
1377 for (int k = 0; k < maxK; k++) {
1378 for (int v = 0; v < maxV; v++) {
1379 expected.add((V) makeValue(k, v));
1380 }
1381 }
1382 final Collection<V> c = map.values();
1383 assertEquals(getSampleTotalValueCount(), c.size());
1384 assertEquals(expected, new HashSet<>(c));
1385 }
1386
1387 }