1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package com.google.common.collect.testing;
18
19 import static java.util.Collections.singleton;
20
21 import com.google.common.annotations.GwtCompatible;
22
23 import junit.framework.TestCase;
24
25 import java.util.Arrays;
26 import java.util.Collection;
27 import java.util.Collections;
28 import java.util.HashSet;
29 import java.util.Iterator;
30 import java.util.Map;
31 import java.util.Map.Entry;
32 import java.util.Set;
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50 @GwtCompatible
51 public abstract class MapInterfaceTest<K, V> extends TestCase {
52
53
54 private static final class IncompatibleKeyType {
55 @Override public String toString() {
56 return "IncompatibleKeyType";
57 }
58 }
59
60 protected final boolean supportsPut;
61 protected final boolean supportsRemove;
62 protected final boolean supportsClear;
63 protected final boolean allowsNullKeys;
64 protected final boolean allowsNullValues;
65 protected final boolean supportsIteratorRemove;
66
67
68
69
70
71
72
73
74 protected abstract Map<K, V> makeEmptyMap()
75 throws UnsupportedOperationException;
76
77
78
79
80
81
82
83
84 protected abstract Map<K, V> makePopulatedMap()
85 throws UnsupportedOperationException;
86
87
88
89
90
91
92
93
94
95 protected abstract K getKeyNotInPopulatedMap()
96 throws UnsupportedOperationException;
97
98
99
100
101
102
103
104
105
106 protected abstract V getValueNotInPopulatedMap()
107 throws UnsupportedOperationException;
108
109
110
111
112
113 protected MapInterfaceTest(
114 boolean allowsNullKeys,
115 boolean allowsNullValues,
116 boolean supportsPut,
117 boolean supportsRemove,
118 boolean supportsClear) {
119 this(allowsNullKeys, allowsNullValues, supportsPut, supportsRemove,
120 supportsClear, supportsRemove);
121 }
122
123
124
125
126 protected MapInterfaceTest(
127 boolean allowsNullKeys,
128 boolean allowsNullValues,
129 boolean supportsPut,
130 boolean supportsRemove,
131 boolean supportsClear,
132 boolean supportsIteratorRemove) {
133 this.supportsPut = supportsPut;
134 this.supportsRemove = supportsRemove;
135 this.supportsClear = supportsClear;
136 this.allowsNullKeys = allowsNullKeys;
137 this.allowsNullValues = allowsNullValues;
138 this.supportsIteratorRemove = supportsIteratorRemove;
139 }
140
141
142
143
144
145
146
147 protected Map<K, V> makeEitherMap() {
148 try {
149 return makePopulatedMap();
150 } catch (UnsupportedOperationException e) {
151 return makeEmptyMap();
152 }
153 }
154
155 protected final boolean supportsValuesHashCode(Map<K, V> map) {
156
157 Collection<V> values = map.values();
158 for (V value : values) {
159 if (value != null) {
160 try {
161 value.hashCode();
162 } catch (Exception e) {
163 return false;
164 }
165 return true;
166 }
167 }
168 return true;
169 }
170
171
172
173
174
175
176
177
178
179 protected final void assertInvariants(Map<K, V> map) {
180 Set<K> keySet = map.keySet();
181 Collection<V> valueCollection = map.values();
182 Set<Entry<K, V>> entrySet = map.entrySet();
183
184 assertEquals(map.size() == 0, map.isEmpty());
185 assertEquals(map.size(), keySet.size());
186 assertEquals(keySet.size() == 0, keySet.isEmpty());
187 assertEquals(!keySet.isEmpty(), keySet.iterator().hasNext());
188
189 int expectedKeySetHash = 0;
190 for (K key : keySet) {
191 V value = map.get(key);
192 expectedKeySetHash += key != null ? key.hashCode() : 0;
193 assertTrue(map.containsKey(key));
194 assertTrue(map.containsValue(value));
195 assertTrue(valueCollection.contains(value));
196 assertTrue(valueCollection.containsAll(Collections.singleton(value)));
197 assertTrue(entrySet.contains(mapEntry(key, value)));
198 assertTrue(allowsNullKeys || (key != null));
199 }
200 assertEquals(expectedKeySetHash, keySet.hashCode());
201
202 assertEquals(map.size(), valueCollection.size());
203 assertEquals(valueCollection.size() == 0, valueCollection.isEmpty());
204 assertEquals(
205 !valueCollection.isEmpty(), valueCollection.iterator().hasNext());
206 for (V value : valueCollection) {
207 assertTrue(map.containsValue(value));
208 assertTrue(allowsNullValues || (value != null));
209 }
210
211 assertEquals(map.size(), entrySet.size());
212 assertEquals(entrySet.size() == 0, entrySet.isEmpty());
213 assertEquals(!entrySet.isEmpty(), entrySet.iterator().hasNext());
214 assertFalse(entrySet.contains("foo"));
215
216 boolean supportsValuesHashCode = supportsValuesHashCode(map);
217 if (supportsValuesHashCode) {
218 int expectedEntrySetHash = 0;
219 for (Entry<K, V> entry : entrySet) {
220 assertTrue(map.containsKey(entry.getKey()));
221 assertTrue(map.containsValue(entry.getValue()));
222 int expectedHash =
223 (entry.getKey() == null ? 0 : entry.getKey().hashCode()) ^
224 (entry.getValue() == null ? 0 : entry.getValue().hashCode());
225 assertEquals(expectedHash, entry.hashCode());
226 expectedEntrySetHash += expectedHash;
227 }
228 assertEquals(expectedEntrySetHash, entrySet.hashCode());
229 assertTrue(entrySet.containsAll(new HashSet<Entry<K, V>>(entrySet)));
230 assertTrue(entrySet.equals(new HashSet<Entry<K, V>>(entrySet)));
231 }
232
233 Object[] entrySetToArray1 = entrySet.toArray();
234 assertEquals(map.size(), entrySetToArray1.length);
235 assertTrue(Arrays.asList(entrySetToArray1).containsAll(entrySet));
236
237 Entry<?, ?>[] entrySetToArray2 = new Entry<?, ?>[map.size() + 2];
238 entrySetToArray2[map.size()] = mapEntry("foo", 1);
239 assertSame(entrySetToArray2, entrySet.toArray(entrySetToArray2));
240 assertNull(entrySetToArray2[map.size()]);
241 assertTrue(Arrays.asList(entrySetToArray2).containsAll(entrySet));
242
243 Object[] valuesToArray1 = valueCollection.toArray();
244 assertEquals(map.size(), valuesToArray1.length);
245 assertTrue(Arrays.asList(valuesToArray1).containsAll(valueCollection));
246
247 Object[] valuesToArray2 = new Object[map.size() + 2];
248 valuesToArray2[map.size()] = "foo";
249 assertSame(valuesToArray2, valueCollection.toArray(valuesToArray2));
250 assertNull(valuesToArray2[map.size()]);
251 assertTrue(Arrays.asList(valuesToArray2).containsAll(valueCollection));
252
253 if (supportsValuesHashCode) {
254 int expectedHash = 0;
255 for (Entry<K, V> entry : entrySet) {
256 expectedHash += entry.hashCode();
257 }
258 assertEquals(expectedHash, map.hashCode());
259 }
260
261 assertMoreInvariants(map);
262 }
263
264
265
266
267
268
269
270
271 protected void assertMoreInvariants(Map<K, V> map) {
272 }
273
274 public void testClear() {
275 final Map<K, V> map;
276 try {
277 map = makePopulatedMap();
278 } catch (UnsupportedOperationException e) {
279 return;
280 }
281
282 if (supportsClear) {
283 map.clear();
284 assertTrue(map.isEmpty());
285 } else {
286 try {
287 map.clear();
288 fail("Expected UnsupportedOperationException.");
289 } catch (UnsupportedOperationException e) {
290
291 }
292 }
293 assertInvariants(map);
294 }
295
296 public void testContainsKey() {
297 final Map<K, V> map;
298 final K unmappedKey;
299 try {
300 map = makePopulatedMap();
301 unmappedKey = getKeyNotInPopulatedMap();
302 } catch (UnsupportedOperationException e) {
303 return;
304 }
305 assertFalse(map.containsKey(unmappedKey));
306 try {
307 assertFalse(map.containsKey(new IncompatibleKeyType()));
308 } catch (ClassCastException tolerated) {}
309 assertTrue(map.containsKey(map.keySet().iterator().next()));
310 if (allowsNullKeys) {
311 map.containsKey(null);
312 } else {
313 try {
314 map.containsKey(null);
315 } catch (NullPointerException optional) {
316 }
317 }
318 assertInvariants(map);
319 }
320
321 public void testContainsValue() {
322 final Map<K, V> map;
323 final V unmappedValue;
324 try {
325 map = makePopulatedMap();
326 unmappedValue = getValueNotInPopulatedMap();
327 } catch (UnsupportedOperationException e) {
328 return;
329 }
330 assertFalse(map.containsValue(unmappedValue));
331 assertTrue(map.containsValue(map.values().iterator().next()));
332 if (allowsNullValues) {
333 map.containsValue(null);
334 } else {
335 try {
336 map.containsKey(null);
337 } catch (NullPointerException optional) {
338 }
339 }
340 assertInvariants(map);
341 }
342
343 public void testEntrySet() {
344 final Map<K, V> map;
345 final Set<Entry<K, V>> entrySet;
346 try {
347 map = makePopulatedMap();
348 } catch (UnsupportedOperationException e) {
349 return;
350 }
351 assertInvariants(map);
352
353 entrySet = map.entrySet();
354 final K unmappedKey;
355 final V unmappedValue;
356 try {
357 unmappedKey = getKeyNotInPopulatedMap();
358 unmappedValue = getValueNotInPopulatedMap();
359 } catch (UnsupportedOperationException e) {
360 return;
361 }
362 for (Entry<K, V> entry : entrySet) {
363 assertFalse(unmappedKey.equals(entry.getKey()));
364 assertFalse(unmappedValue.equals(entry.getValue()));
365 }
366 }
367
368 public void testEntrySetForEmptyMap() {
369 final Map<K, V> map;
370 try {
371 map = makeEmptyMap();
372 } catch (UnsupportedOperationException e) {
373 return;
374 }
375 assertInvariants(map);
376 }
377
378 public void testEntrySetContainsEntryIncompatibleKey() {
379 final Map<K, V> map;
380 final Set<Entry<K, V>> entrySet;
381 try {
382 map = makeEitherMap();
383 } catch (UnsupportedOperationException e) {
384 return;
385 }
386 assertInvariants(map);
387
388 entrySet = map.entrySet();
389 final V unmappedValue;
390 try {
391 unmappedValue = getValueNotInPopulatedMap();
392 } catch (UnsupportedOperationException e) {
393 return;
394 }
395 Entry<IncompatibleKeyType, V> entry
396 = mapEntry(new IncompatibleKeyType(), unmappedValue);
397 try {
398 assertFalse(entrySet.contains(entry));
399 } catch (ClassCastException tolerated) {}
400 }
401
402 public void testEntrySetContainsEntryNullKeyPresent() {
403 if (!allowsNullKeys || !supportsPut) {
404 return;
405 }
406 final Map<K, V> map;
407 final Set<Entry<K, V>> entrySet;
408 try {
409 map = makeEitherMap();
410 } catch (UnsupportedOperationException e) {
411 return;
412 }
413 assertInvariants(map);
414
415 entrySet = map.entrySet();
416 final V unmappedValue;
417 try {
418 unmappedValue = getValueNotInPopulatedMap();
419 } catch (UnsupportedOperationException e) {
420 return;
421 }
422
423 map.put(null, unmappedValue);
424 Entry<K, V> entry = mapEntry(null, unmappedValue);
425 assertTrue(entrySet.contains(entry));
426 assertFalse(entrySet.contains(mapEntry(null, null)));
427 }
428
429 public void testEntrySetContainsEntryNullKeyMissing() {
430 final Map<K, V> map;
431 final Set<Entry<K, V>> entrySet;
432 try {
433 map = makeEitherMap();
434 } catch (UnsupportedOperationException e) {
435 return;
436 }
437 assertInvariants(map);
438
439 entrySet = map.entrySet();
440 final V unmappedValue;
441 try {
442 unmappedValue = getValueNotInPopulatedMap();
443 } catch (UnsupportedOperationException e) {
444 return;
445 }
446 Entry<K, V> entry = mapEntry(null, unmappedValue);
447 try {
448 assertFalse(entrySet.contains(entry));
449 } catch (NullPointerException e) {
450 assertFalse(allowsNullKeys);
451 }
452 try {
453 assertFalse(entrySet.contains(mapEntry(null, null)));
454 } catch (NullPointerException e) {
455 assertFalse(allowsNullKeys && allowsNullValues);
456 }
457 }
458
459 public void testEntrySetIteratorRemove() {
460 final Map<K, V> map;
461 try {
462 map = makePopulatedMap();
463 } catch (UnsupportedOperationException e) {
464 return;
465 }
466
467 Set<Entry<K, V>> entrySet = map.entrySet();
468 Iterator<Entry<K, V>> iterator = entrySet.iterator();
469 if (supportsIteratorRemove) {
470 int initialSize = map.size();
471 Entry<K, V> entry = iterator.next();
472 Entry<K, V> entryCopy = Helpers.mapEntry(
473 entry.getKey(), entry.getValue());
474
475 iterator.remove();
476 assertEquals(initialSize - 1, map.size());
477
478
479
480 assertFalse(entrySet.contains(entryCopy));
481 assertInvariants(map);
482 try {
483 iterator.remove();
484 fail("Expected IllegalStateException.");
485 } catch (IllegalStateException e) {
486
487 }
488 } else {
489 try {
490 iterator.next();
491 iterator.remove();
492 fail("Expected UnsupportedOperationException.");
493 } catch (UnsupportedOperationException e) {
494
495 }
496 }
497 assertInvariants(map);
498 }
499
500 public void testEntrySetRemove() {
501 final Map<K, V> map;
502 try {
503 map = makePopulatedMap();
504 } catch (UnsupportedOperationException e) {
505 return;
506 }
507
508 Set<Entry<K, V>> entrySet = map.entrySet();
509 if (supportsRemove) {
510 int initialSize = map.size();
511 boolean didRemove = entrySet.remove(entrySet.iterator().next());
512 assertTrue(didRemove);
513 assertEquals(initialSize - 1, map.size());
514 } else {
515 try {
516 entrySet.remove(entrySet.iterator().next());
517 fail("Expected UnsupportedOperationException.");
518 } catch (UnsupportedOperationException e) {
519
520 }
521 }
522 assertInvariants(map);
523 }
524
525 public void testEntrySetRemoveMissingKey() {
526 final Map<K, V> map;
527 final K key;
528 try {
529 map = makeEitherMap();
530 key = getKeyNotInPopulatedMap();
531 } catch (UnsupportedOperationException e) {
532 return;
533 }
534
535 Set<Entry<K, V>> entrySet = map.entrySet();
536 Entry<K, V> entry
537 = mapEntry(key, getValueNotInPopulatedMap());
538 int initialSize = map.size();
539 if (supportsRemove) {
540 boolean didRemove = entrySet.remove(entry);
541 assertFalse(didRemove);
542 } else {
543 try {
544 boolean didRemove = entrySet.remove(entry);
545 assertFalse(didRemove);
546 } catch (UnsupportedOperationException optional) {}
547 }
548 assertEquals(initialSize, map.size());
549 assertFalse(map.containsKey(key));
550 assertInvariants(map);
551 }
552
553 public void testEntrySetRemoveDifferentValue() {
554 final Map<K, V> map;
555 try {
556 map = makePopulatedMap();
557 } catch (UnsupportedOperationException e) {
558 return;
559 }
560
561 Set<Entry<K, V>> entrySet = map.entrySet();
562 K key = map.keySet().iterator().next();
563 Entry<K, V> entry
564 = mapEntry(key, getValueNotInPopulatedMap());
565 int initialSize = map.size();
566 if (supportsRemove) {
567 boolean didRemove = entrySet.remove(entry);
568 assertFalse(didRemove);
569 } else {
570 try {
571 boolean didRemove = entrySet.remove(entry);
572 assertFalse(didRemove);
573 } catch (UnsupportedOperationException optional) {}
574 }
575 assertEquals(initialSize, map.size());
576 assertTrue(map.containsKey(key));
577 assertInvariants(map);
578 }
579
580 public void testEntrySetRemoveNullKeyPresent() {
581 if (!allowsNullKeys || !supportsPut || !supportsRemove) {
582 return;
583 }
584 final Map<K, V> map;
585 final Set<Entry<K, V>> entrySet;
586 try {
587 map = makeEitherMap();
588 } catch (UnsupportedOperationException e) {
589 return;
590 }
591 assertInvariants(map);
592
593 entrySet = map.entrySet();
594 final V unmappedValue;
595 try {
596 unmappedValue = getValueNotInPopulatedMap();
597 } catch (UnsupportedOperationException e) {
598 return;
599 }
600
601 map.put(null, unmappedValue);
602 assertEquals(unmappedValue, map.get(null));
603 assertTrue(map.containsKey(null));
604 Entry<K, V> entry = mapEntry(null, unmappedValue);
605 assertTrue(entrySet.remove(entry));
606 assertNull(map.get(null));
607 assertFalse(map.containsKey(null));
608 }
609
610 public void testEntrySetRemoveNullKeyMissing() {
611 final Map<K, V> map;
612 try {
613 map = makeEitherMap();
614 } catch (UnsupportedOperationException e) {
615 return;
616 }
617
618 Set<Entry<K, V>> entrySet = map.entrySet();
619 Entry<K, V> entry
620 = mapEntry(null, getValueNotInPopulatedMap());
621 int initialSize = map.size();
622 if (supportsRemove) {
623 try {
624 boolean didRemove = entrySet.remove(entry);
625 assertFalse(didRemove);
626 } catch (NullPointerException e) {
627 assertFalse(allowsNullKeys);
628 }
629 } else {
630 try {
631 boolean didRemove = entrySet.remove(entry);
632 assertFalse(didRemove);
633 } catch (UnsupportedOperationException optional) {}
634 }
635 assertEquals(initialSize, map.size());
636 assertInvariants(map);
637 }
638
639 public void testEntrySetRemoveAll() {
640 final Map<K, V> map;
641 try {
642 map = makePopulatedMap();
643 } catch (UnsupportedOperationException e) {
644 return;
645 }
646
647 Set<Entry<K, V>> entrySet = map.entrySet();
648
649 Entry<K, V> entryToRemove = entrySet.iterator().next();
650 Set<Entry<K, V>> entriesToRemove = singleton(entryToRemove);
651 if (supportsRemove) {
652
653
654
655 Entry<K, V> entryToRemoveCopy = Helpers.mapEntry(
656 entryToRemove.getKey(), entryToRemove.getValue());
657
658 int initialSize = map.size();
659 boolean didRemove = entrySet.removeAll(entriesToRemove);
660 assertTrue(didRemove);
661 assertEquals(initialSize - entriesToRemove.size(), map.size());
662
663
664
665 assertFalse(entrySet.contains(entryToRemoveCopy));
666 } else {
667 try {
668 entrySet.removeAll(entriesToRemove);
669 fail("Expected UnsupportedOperationException.");
670 } catch (UnsupportedOperationException e) {
671
672 }
673 }
674 assertInvariants(map);
675 }
676
677 public void testEntrySetRemoveAllNullFromEmpty() {
678 final Map<K, V> map;
679 try {
680 map = makeEmptyMap();
681 } catch (UnsupportedOperationException e) {
682 return;
683 }
684
685 Set<Entry<K, V>> entrySet = map.entrySet();
686 if (supportsRemove) {
687 try {
688 entrySet.removeAll(null);
689 fail("Expected NullPointerException.");
690 } catch (NullPointerException e) {
691
692 }
693 } else {
694 try {
695 entrySet.removeAll(null);
696 fail("Expected UnsupportedOperationException or NullPointerException.");
697 } catch (UnsupportedOperationException e) {
698
699 } catch (NullPointerException e) {
700
701 }
702 }
703 assertInvariants(map);
704 }
705
706 public void testEntrySetRetainAll() {
707 final Map<K, V> map;
708 try {
709 map = makePopulatedMap();
710 } catch (UnsupportedOperationException e) {
711 return;
712 }
713
714 Set<Entry<K, V>> entrySet = map.entrySet();
715 Set<Entry<K, V>> entriesToRetain =
716 singleton(entrySet.iterator().next());
717 if (supportsRemove) {
718 boolean shouldRemove = (entrySet.size() > entriesToRetain.size());
719 boolean didRemove = entrySet.retainAll(entriesToRetain);
720 assertEquals(shouldRemove, didRemove);
721 assertEquals(entriesToRetain.size(), map.size());
722 for (Entry<K, V> entry : entriesToRetain) {
723 assertTrue(entrySet.contains(entry));
724 }
725 } else {
726 try {
727 entrySet.retainAll(entriesToRetain);
728 fail("Expected UnsupportedOperationException.");
729 } catch (UnsupportedOperationException e) {
730
731 }
732 }
733 assertInvariants(map);
734 }
735
736 public void testEntrySetRetainAllNullFromEmpty() {
737 final Map<K, V> map;
738 try {
739 map = makeEmptyMap();
740 } catch (UnsupportedOperationException e) {
741 return;
742 }
743
744 Set<Entry<K, V>> entrySet = map.entrySet();
745 if (supportsRemove) {
746 try {
747 entrySet.retainAll(null);
748
749 } catch (NullPointerException e) {
750
751 }
752 } else {
753 try {
754 entrySet.retainAll(null);
755
756 } catch (UnsupportedOperationException e) {
757
758 } catch (NullPointerException e) {
759
760 }
761 }
762 assertInvariants(map);
763 }
764
765 public void testEntrySetClear() {
766 final Map<K, V> map;
767 try {
768 map = makePopulatedMap();
769 } catch (UnsupportedOperationException e) {
770 return;
771 }
772
773 Set<Entry<K, V>> entrySet = map.entrySet();
774 if (supportsClear) {
775 entrySet.clear();
776 assertTrue(entrySet.isEmpty());
777 } else {
778 try {
779 entrySet.clear();
780 fail("Expected UnsupportedOperationException.");
781 } catch (UnsupportedOperationException e) {
782
783 }
784 }
785 assertInvariants(map);
786 }
787
788 public void testEntrySetAddAndAddAll() {
789 final Map<K, V> map = makeEitherMap();
790
791 Set<Entry<K, V>> entrySet = map.entrySet();
792 final Entry<K, V> entryToAdd = mapEntry(null, null);
793 try {
794 entrySet.add(entryToAdd);
795 fail("Expected UnsupportedOperationException or NullPointerException.");
796 } catch (UnsupportedOperationException e) {
797
798 } catch (NullPointerException e) {
799
800 }
801 assertInvariants(map);
802
803 try {
804 entrySet.addAll(singleton(entryToAdd));
805 fail("Expected UnsupportedOperationException or NullPointerException.");
806 } catch (UnsupportedOperationException e) {
807
808 } catch (NullPointerException e) {
809
810 }
811 assertInvariants(map);
812 }
813
814 public void testEntrySetSetValue() {
815
816
817 if (!supportsPut) {
818 return;
819 }
820
821 final Map<K, V> map;
822 final V valueToSet;
823 try {
824 map = makePopulatedMap();
825 valueToSet = getValueNotInPopulatedMap();
826 } catch (UnsupportedOperationException e) {
827 return;
828 }
829
830 Set<Entry<K, V>> entrySet = map.entrySet();
831 Entry<K, V> entry = entrySet.iterator().next();
832 final V oldValue = entry.getValue();
833 final V returnedValue = entry.setValue(valueToSet);
834 assertEquals(oldValue, returnedValue);
835 assertTrue(entrySet.contains(
836 mapEntry(entry.getKey(), valueToSet)));
837 assertEquals(valueToSet, map.get(entry.getKey()));
838 assertInvariants(map);
839 }
840
841 public void testEntrySetSetValueSameValue() {
842
843
844 if (!supportsPut) {
845 return;
846 }
847
848 final Map<K, V> map;
849 try {
850 map = makePopulatedMap();
851 } catch (UnsupportedOperationException e) {
852 return;
853 }
854
855 Set<Entry<K, V>> entrySet = map.entrySet();
856 Entry<K, V> entry = entrySet.iterator().next();
857 final V oldValue = entry.getValue();
858 final V returnedValue = entry.setValue(oldValue);
859 assertEquals(oldValue, returnedValue);
860 assertTrue(entrySet.contains(
861 mapEntry(entry.getKey(), oldValue)));
862 assertEquals(oldValue, map.get(entry.getKey()));
863 assertInvariants(map);
864 }
865
866 public void testEqualsForEqualMap() {
867 final Map<K, V> map;
868 try {
869 map = makePopulatedMap();
870 } catch (UnsupportedOperationException e) {
871 return;
872 }
873
874 assertEquals(map, map);
875 assertEquals(makePopulatedMap(), map);
876 assertFalse(map.equals(Collections.emptyMap()));
877
878 assertFalse(map.equals(null));
879 }
880
881 public void testEqualsForLargerMap() {
882 if (!supportsPut) {
883 return;
884 }
885
886 final Map<K, V> map;
887 final Map<K, V> largerMap;
888 try {
889 map = makePopulatedMap();
890 largerMap = makePopulatedMap();
891 largerMap.put(getKeyNotInPopulatedMap(), getValueNotInPopulatedMap());
892 } catch (UnsupportedOperationException e) {
893 return;
894 }
895
896 assertFalse(map.equals(largerMap));
897 }
898
899 public void testEqualsForSmallerMap() {
900 if (!supportsRemove) {
901 return;
902 }
903
904 final Map<K, V> map;
905 final Map<K, V> smallerMap;
906 try {
907 map = makePopulatedMap();
908 smallerMap = makePopulatedMap();
909 smallerMap.remove(smallerMap.keySet().iterator().next());
910 } catch (UnsupportedOperationException e) {
911 return;
912 }
913
914 assertFalse(map.equals(smallerMap));
915 }
916
917 public void testEqualsForEmptyMap() {
918 final Map<K, V> map;
919 try {
920 map = makeEmptyMap();
921 } catch (UnsupportedOperationException e) {
922 return;
923 }
924
925 assertEquals(map, map);
926 assertEquals(makeEmptyMap(), map);
927 assertEquals(Collections.emptyMap(), map);
928 assertFalse(map.equals(Collections.emptySet()));
929
930 assertFalse(map.equals(null));
931 }
932
933 public void testGet() {
934 final Map<K, V> map;
935 try {
936 map = makePopulatedMap();
937 } catch (UnsupportedOperationException e) {
938 return;
939 }
940
941 for (Entry<K, V> entry : map.entrySet()) {
942 assertEquals(entry.getValue(), map.get(entry.getKey()));
943 }
944
945 K unmappedKey = null;
946 try {
947 unmappedKey = getKeyNotInPopulatedMap();
948 } catch (UnsupportedOperationException e) {
949 return;
950 }
951 assertNull(map.get(unmappedKey));
952 }
953
954 public void testGetForEmptyMap() {
955 final Map<K, V> map;
956 K unmappedKey = null;
957 try {
958 map = makeEmptyMap();
959 unmappedKey = getKeyNotInPopulatedMap();
960 } catch (UnsupportedOperationException e) {
961 return;
962 }
963 assertNull(map.get(unmappedKey));
964 }
965
966 public void testGetNull() {
967 Map<K, V> map = makeEitherMap();
968 if (allowsNullKeys) {
969 if (allowsNullValues) {
970
971 } else {
972 assertEquals(map.containsKey(null), map.get(null) != null);
973 }
974 } else {
975 try {
976 map.get(null);
977 } catch (NullPointerException optional) {
978 }
979 }
980 assertInvariants(map);
981 }
982
983 public void testHashCode() {
984 final Map<K, V> map;
985 try {
986 map = makePopulatedMap();
987 } catch (UnsupportedOperationException e) {
988 return;
989 }
990 assertInvariants(map);
991 }
992
993 public void testHashCodeForEmptyMap() {
994 final Map<K, V> map;
995 try {
996 map = makeEmptyMap();
997 } catch (UnsupportedOperationException e) {
998 return;
999 }
1000 assertInvariants(map);
1001 }
1002
1003 public void testPutNewKey() {
1004 final Map<K, V> map = makeEitherMap();
1005 final K keyToPut;
1006 final V valueToPut;
1007 try {
1008 keyToPut = getKeyNotInPopulatedMap();
1009 valueToPut = getValueNotInPopulatedMap();
1010 } catch (UnsupportedOperationException e) {
1011 return;
1012 }
1013 if (supportsPut) {
1014 int initialSize = map.size();
1015 V oldValue = map.put(keyToPut, valueToPut);
1016 assertEquals(valueToPut, map.get(keyToPut));
1017 assertTrue(map.containsKey(keyToPut));
1018 assertTrue(map.containsValue(valueToPut));
1019 assertEquals(initialSize + 1, map.size());
1020 assertNull(oldValue);
1021 } else {
1022 try {
1023 map.put(keyToPut, valueToPut);
1024 fail("Expected UnsupportedOperationException.");
1025 } catch (UnsupportedOperationException e) {
1026
1027 }
1028 }
1029 assertInvariants(map);
1030 }
1031
1032 public void testPutExistingKey() {
1033 final Map<K, V> map;
1034 final K keyToPut;
1035 final V valueToPut;
1036 try {
1037 map = makePopulatedMap();
1038 valueToPut = getValueNotInPopulatedMap();
1039 } catch (UnsupportedOperationException e) {
1040 return;
1041 }
1042 keyToPut = map.keySet().iterator().next();
1043 if (supportsPut) {
1044 int initialSize = map.size();
1045 map.put(keyToPut, valueToPut);
1046 assertEquals(valueToPut, map.get(keyToPut));
1047 assertTrue(map.containsKey(keyToPut));
1048 assertTrue(map.containsValue(valueToPut));
1049 assertEquals(initialSize, map.size());
1050 } else {
1051 try {
1052 map.put(keyToPut, valueToPut);
1053 fail("Expected UnsupportedOperationException.");
1054 } catch (UnsupportedOperationException e) {
1055
1056 }
1057 }
1058 assertInvariants(map);
1059 }
1060
1061 public void testPutNullKey() {
1062 if (!supportsPut) {
1063 return;
1064 }
1065 final Map<K, V> map = makeEitherMap();
1066 final V valueToPut;
1067 try {
1068 valueToPut = getValueNotInPopulatedMap();
1069 } catch (UnsupportedOperationException e) {
1070 return;
1071 }
1072 if (allowsNullKeys) {
1073 final V oldValue = map.get(null);
1074 final V returnedValue = map.put(null, valueToPut);
1075 assertEquals(oldValue, returnedValue);
1076 assertEquals(valueToPut, map.get(null));
1077 assertTrue(map.containsKey(null));
1078 assertTrue(map.containsValue(valueToPut));
1079 } else {
1080 try {
1081 map.put(null, valueToPut);
1082 fail("Expected RuntimeException");
1083 } catch (RuntimeException e) {
1084
1085 }
1086 }
1087 assertInvariants(map);
1088 }
1089
1090 public void testPutNullValue() {
1091 if (!supportsPut) {
1092 return;
1093 }
1094 final Map<K, V> map = makeEitherMap();
1095 final K keyToPut;
1096 try {
1097 keyToPut = getKeyNotInPopulatedMap();
1098 } catch (UnsupportedOperationException e) {
1099 return;
1100 }
1101 if (allowsNullValues) {
1102 int initialSize = map.size();
1103 final V oldValue = map.get(keyToPut);
1104 final V returnedValue = map.put(keyToPut, null);
1105 assertEquals(oldValue, returnedValue);
1106 assertNull(map.get(keyToPut));
1107 assertTrue(map.containsKey(keyToPut));
1108 assertTrue(map.containsValue(null));
1109 assertEquals(initialSize + 1, map.size());
1110 } else {
1111 try {
1112 map.put(keyToPut, null);
1113 fail("Expected RuntimeException");
1114 } catch (RuntimeException e) {
1115
1116 }
1117 }
1118 assertInvariants(map);
1119 }
1120
1121 public void testPutNullValueForExistingKey() {
1122 if (!supportsPut) {
1123 return;
1124 }
1125 final Map<K, V> map;
1126 final K keyToPut;
1127 try {
1128 map = makePopulatedMap();
1129 keyToPut = map.keySet().iterator().next();
1130 } catch (UnsupportedOperationException e) {
1131 return;
1132 }
1133 if (allowsNullValues) {
1134 int initialSize = map.size();
1135 final V oldValue = map.get(keyToPut);
1136 final V returnedValue = map.put(keyToPut, null);
1137 assertEquals(oldValue, returnedValue);
1138 assertNull(map.get(keyToPut));
1139 assertTrue(map.containsKey(keyToPut));
1140 assertTrue(map.containsValue(null));
1141 assertEquals(initialSize, map.size());
1142 } else {
1143 try {
1144 map.put(keyToPut, null);
1145 fail("Expected RuntimeException");
1146 } catch (RuntimeException e) {
1147
1148 }
1149 }
1150 assertInvariants(map);
1151 }
1152
1153 public void testPutAllNewKey() {
1154 final Map<K, V> map = makeEitherMap();
1155 final K keyToPut;
1156 final V valueToPut;
1157 try {
1158 keyToPut = getKeyNotInPopulatedMap();
1159 valueToPut = getValueNotInPopulatedMap();
1160 } catch (UnsupportedOperationException e) {
1161 return;
1162 }
1163 final Map<K, V> mapToPut = Collections.singletonMap(keyToPut, valueToPut);
1164 if (supportsPut) {
1165 int initialSize = map.size();
1166 map.putAll(mapToPut);
1167 assertEquals(valueToPut, map.get(keyToPut));
1168 assertTrue(map.containsKey(keyToPut));
1169 assertTrue(map.containsValue(valueToPut));
1170 assertEquals(initialSize + 1, map.size());
1171 } else {
1172 try {
1173 map.putAll(mapToPut);
1174 fail("Expected UnsupportedOperationException.");
1175 } catch (UnsupportedOperationException e) {
1176
1177 }
1178 }
1179 assertInvariants(map);
1180 }
1181
1182 public void testPutAllExistingKey() {
1183 final Map<K, V> map;
1184 final K keyToPut;
1185 final V valueToPut;
1186 try {
1187 map = makePopulatedMap();
1188 valueToPut = getValueNotInPopulatedMap();
1189 } catch (UnsupportedOperationException e) {
1190 return;
1191 }
1192 keyToPut = map.keySet().iterator().next();
1193 final Map<K, V> mapToPut = Collections.singletonMap(keyToPut, valueToPut);
1194 int initialSize = map.size();
1195 if (supportsPut) {
1196 map.putAll(mapToPut);
1197 assertEquals(valueToPut, map.get(keyToPut));
1198 assertTrue(map.containsKey(keyToPut));
1199 assertTrue(map.containsValue(valueToPut));
1200 } else {
1201 try {
1202 map.putAll(mapToPut);
1203 fail("Expected UnsupportedOperationException.");
1204 } catch (UnsupportedOperationException e) {
1205
1206 }
1207 }
1208 assertEquals(initialSize, map.size());
1209 assertInvariants(map);
1210 }
1211
1212 public void testRemove() {
1213 final Map<K, V> map;
1214 final K keyToRemove;
1215 try {
1216 map = makePopulatedMap();
1217 } catch (UnsupportedOperationException e) {
1218 return;
1219 }
1220 keyToRemove = map.keySet().iterator().next();
1221 if (supportsRemove) {
1222 int initialSize = map.size();
1223 V expectedValue = map.get(keyToRemove);
1224 V oldValue = map.remove(keyToRemove);
1225 assertEquals(expectedValue, oldValue);
1226 assertFalse(map.containsKey(keyToRemove));
1227 assertEquals(initialSize - 1, map.size());
1228 } else {
1229 try {
1230 map.remove(keyToRemove);
1231 fail("Expected UnsupportedOperationException.");
1232 } catch (UnsupportedOperationException e) {
1233
1234 }
1235 }
1236 assertInvariants(map);
1237 }
1238
1239 public void testRemoveMissingKey() {
1240 final Map<K, V> map;
1241 final K keyToRemove;
1242 try {
1243 map = makePopulatedMap();
1244 keyToRemove = getKeyNotInPopulatedMap();
1245 } catch (UnsupportedOperationException e) {
1246 return;
1247 }
1248 if (supportsRemove) {
1249 int initialSize = map.size();
1250 assertNull(map.remove(keyToRemove));
1251 assertEquals(initialSize, map.size());
1252 } else {
1253 try {
1254 map.remove(keyToRemove);
1255 fail("Expected UnsupportedOperationException.");
1256 } catch (UnsupportedOperationException e) {
1257
1258 }
1259 }
1260 assertInvariants(map);
1261 }
1262
1263 public void testSize() {
1264 assertInvariants(makeEitherMap());
1265 }
1266
1267 public void testKeySetRemove() {
1268 final Map<K, V> map;
1269 try {
1270 map = makePopulatedMap();
1271 } catch (UnsupportedOperationException e) {
1272 return;
1273 }
1274
1275 Set<K> keys = map.keySet();
1276 K key = keys.iterator().next();
1277 if (supportsRemove) {
1278 int initialSize = map.size();
1279 keys.remove(key);
1280 assertEquals(initialSize - 1, map.size());
1281 assertFalse(map.containsKey(key));
1282 } else {
1283 try {
1284 keys.remove(key);
1285 fail("Expected UnsupportedOperationException.");
1286 } catch (UnsupportedOperationException e) {
1287
1288 }
1289 }
1290 assertInvariants(map);
1291 }
1292
1293 public void testKeySetRemoveAll() {
1294 final Map<K, V> map;
1295 try {
1296 map = makePopulatedMap();
1297 } catch (UnsupportedOperationException e) {
1298 return;
1299 }
1300
1301 Set<K> keys = map.keySet();
1302 K key = keys.iterator().next();
1303 if (supportsRemove) {
1304 int initialSize = map.size();
1305 assertTrue(keys.removeAll(Collections.singleton(key)));
1306 assertEquals(initialSize - 1, map.size());
1307 assertFalse(map.containsKey(key));
1308 } else {
1309 try {
1310 keys.removeAll(Collections.singleton(key));
1311 fail("Expected UnsupportedOperationException.");
1312 } catch (UnsupportedOperationException e) {
1313
1314 }
1315 }
1316 assertInvariants(map);
1317 }
1318
1319 public void testKeySetRetainAll() {
1320 final Map<K, V> map;
1321 try {
1322 map = makePopulatedMap();
1323 } catch (UnsupportedOperationException e) {
1324 return;
1325 }
1326
1327 Set<K> keys = map.keySet();
1328 K key = keys.iterator().next();
1329 if (supportsRemove) {
1330 keys.retainAll(Collections.singleton(key));
1331 assertEquals(1, map.size());
1332 assertTrue(map.containsKey(key));
1333 } else {
1334 try {
1335 keys.retainAll(Collections.singleton(key));
1336 fail("Expected UnsupportedOperationException.");
1337 } catch (UnsupportedOperationException e) {
1338
1339 }
1340 }
1341 assertInvariants(map);
1342 }
1343
1344 public void testKeySetClear() {
1345 final Map<K, V> map;
1346 try {
1347 map = makeEitherMap();
1348 } catch (UnsupportedOperationException e) {
1349 return;
1350 }
1351
1352 Set<K> keySet = map.keySet();
1353 if (supportsClear) {
1354 keySet.clear();
1355 assertTrue(keySet.isEmpty());
1356 } else {
1357 try {
1358 keySet.clear();
1359 fail("Expected UnsupportedOperationException.");
1360 } catch (UnsupportedOperationException e) {
1361
1362 }
1363 }
1364 assertInvariants(map);
1365 }
1366
1367 public void testKeySetRemoveAllNullFromEmpty() {
1368 final Map<K, V> map;
1369 try {
1370 map = makeEmptyMap();
1371 } catch (UnsupportedOperationException e) {
1372 return;
1373 }
1374
1375 Set<K> keySet = map.keySet();
1376 if (supportsRemove) {
1377 try {
1378 keySet.removeAll(null);
1379 fail("Expected NullPointerException.");
1380 } catch (NullPointerException e) {
1381
1382 }
1383 } else {
1384 try {
1385 keySet.removeAll(null);
1386 fail("Expected UnsupportedOperationException or NullPointerException.");
1387 } catch (UnsupportedOperationException e) {
1388
1389 } catch (NullPointerException e) {
1390
1391 }
1392 }
1393 assertInvariants(map);
1394 }
1395
1396 public void testKeySetRetainAllNullFromEmpty() {
1397 final Map<K, V> map;
1398 try {
1399 map = makeEmptyMap();
1400 } catch (UnsupportedOperationException e) {
1401 return;
1402 }
1403
1404 Set<K> keySet = map.keySet();
1405 if (supportsRemove) {
1406 try {
1407 keySet.retainAll(null);
1408
1409 } catch (NullPointerException e) {
1410
1411 }
1412 } else {
1413 try {
1414 keySet.retainAll(null);
1415
1416 } catch (UnsupportedOperationException e) {
1417
1418 } catch (NullPointerException e) {
1419
1420 }
1421 }
1422 assertInvariants(map);
1423 }
1424
1425 public void testValues() {
1426 final Map<K, V> map;
1427 final Collection<V> valueCollection;
1428 try {
1429 map = makePopulatedMap();
1430 } catch (UnsupportedOperationException e) {
1431 return;
1432 }
1433 assertInvariants(map);
1434
1435 valueCollection = map.values();
1436 final V unmappedValue;
1437 try {
1438 unmappedValue = getValueNotInPopulatedMap();
1439 } catch (UnsupportedOperationException e) {
1440 return;
1441 }
1442 for (V value : valueCollection) {
1443 assertFalse(unmappedValue.equals(value));
1444 }
1445 }
1446
1447 public void testValuesIteratorRemove() {
1448 final Map<K, V> map;
1449 try {
1450 map = makePopulatedMap();
1451 } catch (UnsupportedOperationException e) {
1452 return;
1453 }
1454
1455 Collection<V> valueCollection = map.values();
1456 Iterator<V> iterator = valueCollection.iterator();
1457 if (supportsIteratorRemove) {
1458 int initialSize = map.size();
1459 iterator.next();
1460 iterator.remove();
1461 assertEquals(initialSize - 1, map.size());
1462
1463
1464
1465 assertInvariants(map);
1466 try {
1467 iterator.remove();
1468 fail("Expected IllegalStateException.");
1469 } catch (IllegalStateException e) {
1470
1471 }
1472 } else {
1473 try {
1474 iterator.next();
1475 iterator.remove();
1476 fail("Expected UnsupportedOperationException.");
1477 } catch (UnsupportedOperationException e) {
1478
1479 }
1480 }
1481 assertInvariants(map);
1482 }
1483
1484 public void testValuesRemove() {
1485 final Map<K, V> map;
1486 try {
1487 map = makePopulatedMap();
1488 } catch (UnsupportedOperationException e) {
1489 return;
1490 }
1491
1492 Collection<V> valueCollection = map.values();
1493 if (supportsRemove) {
1494 int initialSize = map.size();
1495 valueCollection.remove(valueCollection.iterator().next());
1496 assertEquals(initialSize - 1, map.size());
1497
1498
1499
1500 } else {
1501 try {
1502 valueCollection.remove(valueCollection.iterator().next());
1503 fail("Expected UnsupportedOperationException.");
1504 } catch (UnsupportedOperationException e) {
1505
1506 }
1507 }
1508 assertInvariants(map);
1509 }
1510
1511 public void testValuesRemoveMissing() {
1512 final Map<K, V> map;
1513 final V valueToRemove;
1514 try {
1515 map = makeEitherMap();
1516 valueToRemove = getValueNotInPopulatedMap();
1517 } catch (UnsupportedOperationException e) {
1518 return;
1519 }
1520
1521 Collection<V> valueCollection = map.values();
1522 int initialSize = map.size();
1523 if (supportsRemove) {
1524 assertFalse(valueCollection.remove(valueToRemove));
1525 } else {
1526 try {
1527 assertFalse(valueCollection.remove(valueToRemove));
1528 } catch (UnsupportedOperationException e) {
1529
1530 }
1531 }
1532 assertEquals(initialSize, map.size());
1533 assertInvariants(map);
1534 }
1535
1536 public void testValuesRemoveAll() {
1537 final Map<K, V> map;
1538 try {
1539 map = makePopulatedMap();
1540 } catch (UnsupportedOperationException e) {
1541 return;
1542 }
1543
1544 Collection<V> valueCollection = map.values();
1545 Set<V> valuesToRemove = singleton(valueCollection.iterator().next());
1546 if (supportsRemove) {
1547 valueCollection.removeAll(valuesToRemove);
1548 for (V value : valuesToRemove) {
1549 assertFalse(valueCollection.contains(value));
1550 }
1551 for (V value : valueCollection) {
1552 assertFalse(valuesToRemove.contains(value));
1553 }
1554 } else {
1555 try {
1556 valueCollection.removeAll(valuesToRemove);
1557 fail("Expected UnsupportedOperationException.");
1558 } catch (UnsupportedOperationException e) {
1559
1560 }
1561 }
1562 assertInvariants(map);
1563 }
1564
1565 public void testValuesRemoveAllNullFromEmpty() {
1566 final Map<K, V> map;
1567 try {
1568 map = makeEmptyMap();
1569 } catch (UnsupportedOperationException e) {
1570 return;
1571 }
1572
1573 Collection<V> values = map.values();
1574 if (supportsRemove) {
1575 try {
1576 values.removeAll(null);
1577
1578 } catch (NullPointerException e) {
1579
1580 }
1581 } else {
1582 try {
1583 values.removeAll(null);
1584
1585 } catch (UnsupportedOperationException e) {
1586
1587 } catch (NullPointerException e) {
1588
1589 }
1590 }
1591 assertInvariants(map);
1592 }
1593
1594 public void testValuesRetainAll() {
1595 final Map<K, V> map;
1596 try {
1597 map = makePopulatedMap();
1598 } catch (UnsupportedOperationException e) {
1599 return;
1600 }
1601
1602 Collection<V> valueCollection = map.values();
1603 Set<V> valuesToRetain = singleton(valueCollection.iterator().next());
1604 if (supportsRemove) {
1605 valueCollection.retainAll(valuesToRetain);
1606 for (V value : valuesToRetain) {
1607 assertTrue(valueCollection.contains(value));
1608 }
1609 for (V value : valueCollection) {
1610 assertTrue(valuesToRetain.contains(value));
1611 }
1612 } else {
1613 try {
1614 valueCollection.retainAll(valuesToRetain);
1615 fail("Expected UnsupportedOperationException.");
1616 } catch (UnsupportedOperationException e) {
1617
1618 }
1619 }
1620 assertInvariants(map);
1621 }
1622
1623 public void testValuesRetainAllNullFromEmpty() {
1624 final Map<K, V> map;
1625 try {
1626 map = makeEmptyMap();
1627 } catch (UnsupportedOperationException e) {
1628 return;
1629 }
1630
1631 Collection<V> values = map.values();
1632 if (supportsRemove) {
1633 try {
1634 values.retainAll(null);
1635
1636 } catch (NullPointerException e) {
1637
1638 }
1639 } else {
1640 try {
1641 values.retainAll(null);
1642
1643 } catch (UnsupportedOperationException e) {
1644
1645 } catch (NullPointerException e) {
1646
1647 }
1648 }
1649 assertInvariants(map);
1650 }
1651
1652 public void testValuesClear() {
1653 final Map<K, V> map;
1654 try {
1655 map = makePopulatedMap();
1656 } catch (UnsupportedOperationException e) {
1657 return;
1658 }
1659
1660 Collection<V> valueCollection = map.values();
1661 if (supportsClear) {
1662 valueCollection.clear();
1663 assertTrue(valueCollection.isEmpty());
1664 } else {
1665 try {
1666 valueCollection.clear();
1667 fail("Expected UnsupportedOperationException.");
1668 } catch (UnsupportedOperationException e) {
1669
1670 }
1671 }
1672 assertInvariants(map);
1673 }
1674
1675 static <K, V> Entry<K, V> mapEntry(K key, V value) {
1676 return Collections.singletonMap(key, value).entrySet().iterator().next();
1677 }
1678 }