1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package com.google.common.collect;
18
19 import static com.google.common.collect.testing.Helpers.nefariousMapEntry;
20 import static com.google.common.truth.Truth.assertThat;
21
22 import com.google.common.annotations.GwtCompatible;
23 import com.google.common.base.Supplier;
24
25 import junit.framework.TestCase;
26
27 import java.io.Serializable;
28 import java.util.AbstractMap;
29 import java.util.Arrays;
30 import java.util.Collection;
31 import java.util.Collections;
32 import java.util.Comparator;
33 import java.util.HashMap;
34 import java.util.Iterator;
35 import java.util.LinkedList;
36 import java.util.List;
37 import java.util.Map;
38 import java.util.Queue;
39 import java.util.RandomAccess;
40 import java.util.Set;
41 import java.util.SortedSet;
42
43
44
45
46
47
48
49 @GwtCompatible(emulated = true)
50 public class MapConstraintsTest extends TestCase {
51
52 private static final String TEST_KEY = "test";
53
54 private static final Integer TEST_VALUE = 42;
55
56 static final class TestKeyException extends IllegalArgumentException {
57 private static final long serialVersionUID = 0;
58 }
59
60 static final class TestValueException extends IllegalArgumentException {
61 private static final long serialVersionUID = 0;
62 }
63
64 static final MapConstraint<String, Integer> TEST_CONSTRAINT
65 = new TestConstraint();
66
67 private static final class TestConstraint
68 implements MapConstraint<String, Integer>, Serializable {
69 @Override
70 public void checkKeyValue(String key, Integer value) {
71 if (TEST_KEY.equals(key)) {
72 throw new TestKeyException();
73 }
74 if (TEST_VALUE.equals(value)) {
75 throw new TestValueException();
76 }
77 }
78 private static final long serialVersionUID = 0;
79 }
80
81 public void testNotNull() {
82 MapConstraint<Object, Object> constraint = MapConstraints.notNull();
83 constraint.checkKeyValue("foo", 1);
84 assertEquals("Not null", constraint.toString());
85 try {
86 constraint.checkKeyValue(null, 1);
87 fail("NullPointerException expected");
88 } catch (NullPointerException expected) {}
89 try {
90 constraint.checkKeyValue("foo", null);
91 fail("NullPointerException expected");
92 } catch (NullPointerException expected) {}
93 try {
94 constraint.checkKeyValue(null, null);
95 fail("NullPointerException expected");
96 } catch (NullPointerException expected) {}
97 }
98
99 public void testConstrainedMapLegal() {
100 Map<String, Integer> map = Maps.newLinkedHashMap();
101 Map<String, Integer> constrained = MapConstraints.constrainedMap(
102 map, TEST_CONSTRAINT);
103 map.put(TEST_KEY, TEST_VALUE);
104 constrained.put("foo", 1);
105 map.putAll(ImmutableMap.of("bar", 2));
106 constrained.putAll(ImmutableMap.of("baz", 3));
107 assertTrue(map.equals(constrained));
108 assertTrue(constrained.equals(map));
109 assertEquals(map.entrySet(), constrained.entrySet());
110 assertEquals(map.keySet(), constrained.keySet());
111 assertEquals(HashMultiset.create(map.values()),
112 HashMultiset.create(constrained.values()));
113 assertFalse(map.values() instanceof Serializable);
114 assertEquals(map.toString(), constrained.toString());
115 assertEquals(map.hashCode(), constrained.hashCode());
116 assertThat(map.entrySet()).has().exactly(
117 Maps.immutableEntry(TEST_KEY, TEST_VALUE),
118 Maps.immutableEntry("foo", 1),
119 Maps.immutableEntry("bar", 2),
120 Maps.immutableEntry("baz", 3)).inOrder();
121 }
122
123 public void testConstrainedMapIllegal() {
124 Map<String, Integer> map = Maps.newLinkedHashMap();
125 Map<String, Integer> constrained = MapConstraints.constrainedMap(
126 map, TEST_CONSTRAINT);
127 try {
128 constrained.put(TEST_KEY, TEST_VALUE);
129 fail("TestKeyException expected");
130 } catch (TestKeyException expected) {}
131 try {
132 constrained.put("baz", TEST_VALUE);
133 fail("TestValueException expected");
134 } catch (TestValueException expected) {}
135 try {
136 constrained.put(TEST_KEY, 3);
137 fail("TestKeyException expected");
138 } catch (TestKeyException expected) {}
139 try {
140 constrained.putAll(ImmutableMap.of("baz", 3, TEST_KEY, 4));
141 fail("TestKeyException expected");
142 } catch (TestKeyException expected) {}
143 assertEquals(Collections.emptySet(), map.entrySet());
144 assertEquals(Collections.emptySet(), constrained.entrySet());
145 }
146
147 public void testConstrainedBiMapLegal() {
148 BiMap<String, Integer> map = new AbstractBiMap<String, Integer>(
149 Maps.<String, Integer>newLinkedHashMap(),
150 Maps.<Integer, String>newLinkedHashMap()) {};
151 BiMap<String, Integer> constrained = MapConstraints.constrainedBiMap(
152 map, TEST_CONSTRAINT);
153 map.put(TEST_KEY, TEST_VALUE);
154 constrained.put("foo", 1);
155 map.putAll(ImmutableMap.of("bar", 2));
156 constrained.putAll(ImmutableMap.of("baz", 3));
157 assertTrue(map.equals(constrained));
158 assertTrue(constrained.equals(map));
159 assertEquals(map.entrySet(), constrained.entrySet());
160 assertEquals(map.keySet(), constrained.keySet());
161 assertEquals(map.values(), constrained.values());
162 assertEquals(map.toString(), constrained.toString());
163 assertEquals(map.hashCode(), constrained.hashCode());
164 assertThat(map.entrySet()).has().exactly(
165 Maps.immutableEntry(TEST_KEY, TEST_VALUE),
166 Maps.immutableEntry("foo", 1),
167 Maps.immutableEntry("bar", 2),
168 Maps.immutableEntry("baz", 3)).inOrder();
169 }
170
171 public void testConstrainedBiMapIllegal() {
172 BiMap<String, Integer> map = new AbstractBiMap<String, Integer>(
173 Maps.<String, Integer>newLinkedHashMap(),
174 Maps.<Integer, String>newLinkedHashMap()) {};
175 BiMap<String, Integer> constrained = MapConstraints.constrainedBiMap(
176 map, TEST_CONSTRAINT);
177 try {
178 constrained.put(TEST_KEY, TEST_VALUE);
179 fail("TestKeyException expected");
180 } catch (TestKeyException expected) {}
181 try {
182 constrained.put("baz", TEST_VALUE);
183 fail("TestValueException expected");
184 } catch (TestValueException expected) {}
185 try {
186 constrained.put(TEST_KEY, 3);
187 fail("TestKeyException expected");
188 } catch (TestKeyException expected) {}
189 try {
190 constrained.putAll(ImmutableMap.of("baz", 3, TEST_KEY, 4));
191 fail("TestKeyException expected");
192 } catch (TestKeyException expected) {}
193 try {
194 constrained.forcePut(TEST_KEY, 3);
195 fail("TestKeyException expected");
196 } catch (TestKeyException expected) {}
197 try {
198 constrained.inverse().forcePut(TEST_VALUE, "baz");
199 fail("TestValueException expected");
200 } catch (TestValueException expected) {}
201 try {
202 constrained.inverse().forcePut(3, TEST_KEY);
203 fail("TestKeyException expected");
204 } catch (TestKeyException expected) {}
205 assertEquals(Collections.emptySet(), map.entrySet());
206 assertEquals(Collections.emptySet(), constrained.entrySet());
207 }
208
209 public void testConstrainedMultimapLegal() {
210 Multimap<String, Integer> multimap = LinkedListMultimap.create();
211 Multimap<String, Integer> constrained = MapConstraints.constrainedMultimap(
212 multimap, TEST_CONSTRAINT);
213 multimap.put(TEST_KEY, TEST_VALUE);
214 constrained.put("foo", 1);
215 multimap.get("bar").add(2);
216 constrained.get("baz").add(3);
217 multimap.get("qux").addAll(Arrays.asList(4));
218 constrained.get("zig").addAll(Arrays.asList(5));
219 multimap.putAll("zag", Arrays.asList(6));
220 constrained.putAll("bee", Arrays.asList(7));
221 multimap.putAll(new ImmutableMultimap.Builder<String, Integer>()
222 .put("bim", 8).build());
223 constrained.putAll(new ImmutableMultimap.Builder<String, Integer>()
224 .put("bop", 9).build());
225 multimap.putAll(new ImmutableMultimap.Builder<String, Integer>()
226 .put("dig", 10).build());
227 constrained.putAll(new ImmutableMultimap.Builder<String, Integer>()
228 .put("dag", 11).build());
229 assertTrue(multimap.equals(constrained));
230 assertTrue(constrained.equals(multimap));
231 assertThat(ImmutableList.copyOf(multimap.entries())).isEqualTo(
232 ImmutableList.copyOf(constrained.entries()));
233 assertThat(constrained.asMap().get("foo")).has().item(1);
234 assertNull(constrained.asMap().get("missing"));
235 assertEquals(multimap.asMap(), constrained.asMap());
236 assertEquals(multimap.values(), constrained.values());
237 assertEquals(multimap.keys(), constrained.keys());
238 assertEquals(multimap.keySet(), constrained.keySet());
239 assertEquals(multimap.toString(), constrained.toString());
240 assertEquals(multimap.hashCode(), constrained.hashCode());
241 assertThat(multimap.entries()).has().exactly(
242 Maps.immutableEntry(TEST_KEY, TEST_VALUE),
243 Maps.immutableEntry("foo", 1),
244 Maps.immutableEntry("bar", 2),
245 Maps.immutableEntry("baz", 3),
246 Maps.immutableEntry("qux", 4),
247 Maps.immutableEntry("zig", 5),
248 Maps.immutableEntry("zag", 6),
249 Maps.immutableEntry("bee", 7),
250 Maps.immutableEntry("bim", 8),
251 Maps.immutableEntry("bop", 9),
252 Maps.immutableEntry("dig", 10),
253 Maps.immutableEntry("dag", 11)).inOrder();
254 assertFalse(constrained.asMap().values() instanceof Serializable);
255 Iterator<Collection<Integer>> iterator =
256 constrained.asMap().values().iterator();
257 iterator.next();
258 iterator.next().add(12);
259 assertTrue(multimap.containsEntry("foo", 12));
260 }
261
262 public void testConstrainedTypePreservingList() {
263 ListMultimap<String, Integer> multimap
264 = MapConstraints.constrainedListMultimap(
265 LinkedListMultimap.<String, Integer>create(),
266 TEST_CONSTRAINT);
267 multimap.put("foo", 1);
268 Map.Entry<String, Collection<Integer>> entry
269 = multimap.asMap().entrySet().iterator().next();
270 assertTrue(entry.getValue() instanceof List);
271 assertFalse(multimap.entries() instanceof Set);
272 assertFalse(multimap.get("foo") instanceof RandomAccess);
273 }
274
275 public void testConstrainedTypePreservingRandomAccessList() {
276 ListMultimap<String, Integer> multimap
277 = MapConstraints.constrainedListMultimap(
278 ArrayListMultimap.<String, Integer>create(),
279 TEST_CONSTRAINT);
280 multimap.put("foo", 1);
281 Map.Entry<String, Collection<Integer>> entry
282 = multimap.asMap().entrySet().iterator().next();
283 assertTrue(entry.getValue() instanceof List);
284 assertFalse(multimap.entries() instanceof Set);
285 assertTrue(multimap.get("foo") instanceof RandomAccess);
286 }
287
288 public void testConstrainedTypePreservingSet() {
289 SetMultimap<String, Integer> multimap
290 = MapConstraints.constrainedSetMultimap(
291 LinkedHashMultimap.<String, Integer>create(),
292 TEST_CONSTRAINT);
293 multimap.put("foo", 1);
294 Map.Entry<String, Collection<Integer>> entry
295 = multimap.asMap().entrySet().iterator().next();
296 assertTrue(entry.getValue() instanceof Set);
297 }
298
299 public void testConstrainedTypePreservingSortedSet() {
300 Comparator<Integer> comparator = Collections.reverseOrder();
301 SortedSetMultimap<String, Integer> delegate
302 = TreeMultimap.create(Ordering.<String>natural(), comparator);
303 SortedSetMultimap<String, Integer> multimap
304 = MapConstraints.constrainedSortedSetMultimap(delegate,
305 TEST_CONSTRAINT);
306 multimap.put("foo", 1);
307 Map.Entry<String, Collection<Integer>> entry
308 = multimap.asMap().entrySet().iterator().next();
309 assertTrue(entry.getValue() instanceof SortedSet);
310 assertSame(comparator, multimap.valueComparator());
311 assertSame(comparator, multimap.get("foo").comparator());
312 }
313
314 @SuppressWarnings("unchecked")
315 public void testConstrainedMultimapIllegal() {
316 Multimap<String, Integer> multimap = LinkedListMultimap.create();
317 Multimap<String, Integer> constrained = MapConstraints.constrainedMultimap(
318 multimap, TEST_CONSTRAINT);
319 try {
320 constrained.put(TEST_KEY, 1);
321 fail("TestKeyException expected");
322 } catch (TestKeyException expected) {}
323 try {
324 constrained.put("foo", TEST_VALUE);
325 fail("TestValueException expected");
326 } catch (TestValueException expected) {}
327 try {
328 constrained.put(TEST_KEY, TEST_VALUE);
329 fail("TestKeyException expected");
330 } catch (TestKeyException expected) {}
331 try {
332 constrained.get(TEST_KEY).add(1);
333 fail("TestKeyException expected");
334 } catch (TestKeyException expected) {}
335 try {
336 constrained.get("foo").add(TEST_VALUE);
337 fail("TestValueException expected");
338 } catch (TestValueException expected) {}
339 try {
340 constrained.get(TEST_KEY).add(TEST_VALUE);
341 fail("TestKeyException expected");
342 } catch (TestKeyException expected) {}
343 try {
344 constrained.get(TEST_KEY).addAll(Arrays.asList(1));
345 fail("TestKeyException expected");
346 } catch (TestKeyException expected) {}
347 try {
348 constrained.get("foo").addAll(Arrays.asList(1, TEST_VALUE));
349 fail("TestValueException expected");
350 } catch (TestValueException expected) {}
351 try {
352 constrained.get(TEST_KEY).addAll(Arrays.asList(1, TEST_VALUE));
353 fail("TestKeyException expected");
354 } catch (TestKeyException expected) {}
355 try {
356 constrained.putAll(TEST_KEY, Arrays.asList(1));
357 fail("TestKeyException expected");
358 } catch (TestKeyException expected) {}
359 try {
360 constrained.putAll("foo", Arrays.asList(1, TEST_VALUE));
361 fail("TestValueException expected");
362 } catch (TestValueException expected) {}
363 try {
364 constrained.putAll(TEST_KEY, Arrays.asList(1, TEST_VALUE));
365 fail("TestKeyException expected");
366 } catch (TestKeyException expected) {}
367 try {
368 constrained.putAll(new ImmutableMultimap.Builder<String, Integer>()
369 .put(TEST_KEY, 2).put("foo", 1).build());
370 fail("TestKeyException expected");
371 } catch (TestKeyException expected) {}
372 try {
373 constrained.putAll(new ImmutableMultimap.Builder<String, Integer>()
374 .put("bar", TEST_VALUE).put("foo", 1).build());
375 fail("TestValueException expected");
376 } catch (TestValueException expected) {}
377 try {
378 constrained.putAll(new ImmutableMultimap.Builder<String, Integer>()
379 .put(TEST_KEY, TEST_VALUE).put("foo", 1).build());
380 fail("TestKeyException expected");
381 } catch (TestKeyException expected) {}
382 try {
383 constrained.entries().add(Maps.immutableEntry(TEST_KEY, 1));
384 fail("UnsupportedOperationException expected");
385 } catch (UnsupportedOperationException expected) {}
386 try {
387 constrained.entries().addAll(Arrays.asList(
388 Maps.immutableEntry("foo", 1),
389 Maps.immutableEntry(TEST_KEY, 2)));
390 fail("UnsupportedOperationException expected");
391 } catch (UnsupportedOperationException expected) {}
392 assertTrue(multimap.isEmpty());
393 assertTrue(constrained.isEmpty());
394 constrained.put("foo", 1);
395 try {
396 constrained.asMap().get("foo").add(TEST_VALUE);
397 fail("TestValueException expected");
398 } catch (TestValueException expected) {}
399 try {
400 constrained.asMap().values().iterator().next().add(TEST_VALUE);
401 fail("TestValueException expected");
402 } catch (TestValueException expected) {}
403 try {
404 ((Collection<Integer>) constrained.asMap().values().toArray()[0])
405 .add(TEST_VALUE);
406 fail("TestValueException expected");
407 } catch (TestValueException expected) {}
408 assertThat(ImmutableList.copyOf(multimap.entries())).isEqualTo(
409 ImmutableList.copyOf(constrained.entries()));
410 assertEquals(multimap.asMap(), constrained.asMap());
411 assertEquals(multimap.values(), constrained.values());
412 assertEquals(multimap.keys(), constrained.keys());
413 assertEquals(multimap.keySet(), constrained.keySet());
414 assertEquals(multimap.toString(), constrained.toString());
415 assertEquals(multimap.hashCode(), constrained.hashCode());
416 }
417
418 private static class QueueSupplier implements Supplier<Queue<Integer>> {
419 @Override
420 public Queue<Integer> get() {
421 return new LinkedList<Integer>();
422 }
423 }
424
425 public void testConstrainedMultimapQueue() {
426 Multimap<String, Integer> multimap = Multimaps.newMultimap(
427 new HashMap<String, Collection<Integer>>(), new QueueSupplier());
428 Multimap<String, Integer> constrained = MapConstraints.constrainedMultimap(
429 multimap, TEST_CONSTRAINT);
430 constrained.put("foo", 1);
431 assertTrue(constrained.get("foo").contains(1));
432 assertTrue(multimap.get("foo").contains(1));
433 try {
434 constrained.put(TEST_KEY, 1);
435 fail("TestKeyException expected");
436 } catch (TestKeyException expected) {}
437 try {
438 constrained.put("foo", TEST_VALUE);
439 fail("TestValueException expected");
440 } catch (TestValueException expected) {}
441 try {
442 constrained.get("foo").add(TEST_VALUE);
443 fail("TestKeyException expected");
444 } catch (TestValueException expected) {}
445 try {
446 constrained.get(TEST_KEY).add(1);
447 fail("TestValueException expected");
448 } catch (TestKeyException expected) {}
449 assertEquals(1, constrained.size());
450 assertEquals(1, multimap.size());
451 }
452
453 public void testMapEntrySetToArray() {
454 Map<String, Integer> map = Maps.newLinkedHashMap();
455 Map<String, Integer> constrained
456 = MapConstraints.constrainedMap(map, TEST_CONSTRAINT);
457 map.put("foo", 1);
458 @SuppressWarnings("unchecked")
459 Map.Entry<String, Integer> entry
460 = (Map.Entry) constrained.entrySet().toArray()[0];
461 try {
462 entry.setValue(TEST_VALUE);
463 fail("TestValueException expected");
464 } catch (TestValueException expected) {}
465 assertFalse(map.containsValue(TEST_VALUE));
466 }
467
468 public void testMapEntrySetContainsNefariousEntry() {
469 Map<String, Integer> map = Maps.newTreeMap();
470 Map<String, Integer> constrained
471 = MapConstraints.constrainedMap(map, TEST_CONSTRAINT);
472 map.put("foo", 1);
473 Map.Entry<String, Integer> nefariousEntry
474 = nefariousMapEntry(TEST_KEY, TEST_VALUE);
475 Set<Map.Entry<String, Integer>> entries = constrained.entrySet();
476 assertFalse(entries.contains(nefariousEntry));
477 assertFalse(map.containsValue(TEST_VALUE));
478 assertFalse(entries.containsAll(Collections.singleton(nefariousEntry)));
479 assertFalse(map.containsValue(TEST_VALUE));
480 }
481
482 public void testMultimapAsMapEntriesToArray() {
483 Multimap<String, Integer> multimap = LinkedListMultimap.create();
484 Multimap<String, Integer> constrained
485 = MapConstraints.constrainedMultimap(multimap, TEST_CONSTRAINT);
486 multimap.put("foo", 1);
487 @SuppressWarnings("unchecked")
488 Map.Entry<String, Collection<Integer>> entry
489 = (Map.Entry<String, Collection<Integer>>)
490 constrained.asMap().entrySet().toArray()[0];
491 try {
492 entry.setValue(Collections.<Integer>emptySet());
493 fail("UnsupportedOperationException expected");
494 } catch (UnsupportedOperationException expected) {}
495 try {
496 entry.getValue().add(TEST_VALUE);
497 fail("TestValueException expected");
498 } catch (TestValueException expected) {}
499 assertFalse(multimap.containsValue(TEST_VALUE));
500 }
501
502 public void testMultimapAsMapValuesToArray() {
503 Multimap<String, Integer> multimap = LinkedListMultimap.create();
504 Multimap<String, Integer> constrained
505 = MapConstraints.constrainedMultimap(multimap, TEST_CONSTRAINT);
506 multimap.put("foo", 1);
507 @SuppressWarnings("unchecked")
508 Collection<Integer> collection
509 = (Collection<Integer>) constrained.asMap().values().toArray()[0];
510 try {
511 collection.add(TEST_VALUE);
512 fail("TestValueException expected");
513 } catch (TestValueException expected) {}
514 assertFalse(multimap.containsValue(TEST_VALUE));
515 }
516
517 public void testMultimapEntriesContainsNefariousEntry() {
518 Multimap<String, Integer> multimap = LinkedListMultimap.create();
519 Multimap<String, Integer> constrained
520 = MapConstraints.constrainedMultimap(multimap, TEST_CONSTRAINT);
521 multimap.put("foo", 1);
522 Map.Entry<String, Integer> nefariousEntry
523 = nefariousMapEntry(TEST_KEY, TEST_VALUE);
524 Collection<Map.Entry<String, Integer>> entries = constrained.entries();
525 assertFalse(entries.contains(nefariousEntry));
526 assertFalse(multimap.containsValue(TEST_VALUE));
527 assertFalse(entries.containsAll(Collections.singleton(nefariousEntry)));
528 assertFalse(multimap.containsValue(TEST_VALUE));
529 }
530
531 public void testMultimapEntriesRemoveNefariousEntry() {
532 Multimap<String, Integer> multimap = LinkedListMultimap.create();
533 Multimap<String, Integer> constrained
534 = MapConstraints.constrainedMultimap(multimap, TEST_CONSTRAINT);
535 multimap.put("foo", 1);
536 Map.Entry<String, Integer> nefariousEntry
537 = nefariousMapEntry(TEST_KEY, TEST_VALUE);
538 Collection<Map.Entry<String, Integer>> entries = constrained.entries();
539 assertFalse(entries.remove(nefariousEntry));
540 assertFalse(multimap.containsValue(TEST_VALUE));
541 assertFalse(entries.removeAll(Collections.singleton(nefariousEntry)));
542 assertFalse(multimap.containsValue(TEST_VALUE));
543 }
544
545 public void testMultimapAsMapEntriesContainsNefariousEntry() {
546 Multimap<String, Integer> multimap = LinkedListMultimap.create();
547 Multimap<String, Integer> constrained
548 = MapConstraints.constrainedMultimap(multimap, TEST_CONSTRAINT);
549 multimap.put("foo", 1);
550 Map.Entry<String, ? extends Collection<Integer>> nefariousEntry
551 = nefariousMapEntry(TEST_KEY, Collections.singleton(TEST_VALUE));
552 Set<Map.Entry<String, Collection<Integer>>> entries
553 = constrained.asMap().entrySet();
554 assertFalse(entries.contains(nefariousEntry));
555 assertFalse(multimap.containsValue(TEST_VALUE));
556 assertFalse(entries.containsAll(Collections.singleton(nefariousEntry)));
557 assertFalse(multimap.containsValue(TEST_VALUE));
558 }
559
560 public void testMultimapAsMapEntriesRemoveNefariousEntry() {
561 Multimap<String, Integer> multimap = LinkedListMultimap.create();
562 Multimap<String, Integer> constrained
563 = MapConstraints.constrainedMultimap(multimap, TEST_CONSTRAINT);
564 multimap.put("foo", 1);
565 Map.Entry<String, ? extends Collection<Integer>> nefariousEntry
566 = nefariousMapEntry(TEST_KEY, Collections.singleton(TEST_VALUE));
567 Set<Map.Entry<String, Collection<Integer>>> entries
568 = constrained.asMap().entrySet();
569 assertFalse(entries.remove(nefariousEntry));
570 assertFalse(multimap.containsValue(TEST_VALUE));
571 assertFalse(entries.removeAll(Collections.singleton(nefariousEntry)));
572 assertFalse(multimap.containsValue(TEST_VALUE));
573 }
574
575 public void testNefariousMapPutAll() {
576 Map<String, Integer> map = Maps.newLinkedHashMap();
577 Map<String, Integer> constrained = MapConstraints.constrainedMap(
578 map, TEST_CONSTRAINT);
579 Map<String, Integer> onceIterable = onceIterableMap("foo", 1);
580 constrained.putAll(onceIterable);
581 assertEquals((Integer) 1, constrained.get("foo"));
582 }
583
584 public void testNefariousMultimapPutAllIterable() {
585 Multimap<String, Integer> multimap = LinkedListMultimap.create();
586 Multimap<String, Integer> constrained = MapConstraints.constrainedMultimap(
587 multimap, TEST_CONSTRAINT);
588 Collection<Integer> onceIterable
589 = ConstraintsTest.onceIterableCollection(1);
590 constrained.putAll("foo", onceIterable);
591 assertEquals(ImmutableList.of(1), constrained.get("foo"));
592 }
593
594 public void testNefariousMultimapPutAllMultimap() {
595 Multimap<String, Integer> multimap = LinkedListMultimap.create();
596 Multimap<String, Integer> constrained = MapConstraints.constrainedMultimap(
597 multimap, TEST_CONSTRAINT);
598 Multimap<String, Integer> onceIterable
599 = Multimaps.forMap(onceIterableMap("foo", 1));
600 constrained.putAll(onceIterable);
601 assertEquals(ImmutableList.of(1), constrained.get("foo"));
602 }
603
604 public void testNefariousMultimapGetAddAll() {
605 Multimap<String, Integer> multimap = LinkedListMultimap.create();
606 Multimap<String, Integer> constrained = MapConstraints.constrainedMultimap(
607 multimap, TEST_CONSTRAINT);
608 Collection<Integer> onceIterable
609 = ConstraintsTest.onceIterableCollection(1);
610 constrained.get("foo").addAll(onceIterable);
611 assertEquals(ImmutableList.of(1), constrained.get("foo"));
612 }
613
614
615
616
617
618
619
620
621
622
623 static <K, V> Map<K, V> onceIterableMap(K key, V value) {
624 final Map.Entry<K, V> entry = Maps.immutableEntry(key, value);
625 return new AbstractMap<K, V>() {
626 boolean iteratorCalled;
627 @Override public int size() {
628
629
630
631
632 return 1;
633 }
634 @Override public Set<Entry<K, V>> entrySet() {
635 return new ForwardingSet<Entry<K, V>>() {
636 @Override protected Set<Entry<K, V>> delegate() {
637 return Collections.singleton(entry);
638 }
639 @Override public Iterator<Entry<K, V>> iterator() {
640 assertFalse("Expected only one call to iterator()", iteratorCalled);
641 iteratorCalled = true;
642 return super.iterator();
643 }
644 };
645 }
646 @Override public Set<K> keySet() {
647 throw new UnsupportedOperationException();
648 }
649 @Override public Collection<V> values() {
650 throw new UnsupportedOperationException();
651 }
652 };
653 }
654 }
655