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.truth.Truth.assertThat;
20
21 import com.google.common.annotations.GwtCompatible;
22 import com.google.common.annotations.GwtIncompatible;
23 import com.google.common.collect.ImmutableSetMultimap.Builder;
24 import com.google.common.collect.testing.features.CollectionFeature;
25 import com.google.common.collect.testing.features.CollectionSize;
26 import com.google.common.collect.testing.features.MapFeature;
27 import com.google.common.collect.testing.google.SetMultimapTestSuiteBuilder;
28 import com.google.common.collect.testing.google.TestStringSetMultimapGenerator;
29 import com.google.common.collect.testing.google.UnmodifiableCollectionTests;
30 import com.google.common.testing.EqualsTester;
31 import com.google.common.testing.SerializableTester;
32
33 import junit.framework.Test;
34 import junit.framework.TestCase;
35 import junit.framework.TestSuite;
36
37 import java.util.Arrays;
38 import java.util.Collection;
39 import java.util.Collections;
40 import java.util.Map.Entry;
41
42
43
44
45
46
47 @GwtCompatible(emulated = true)
48 public class ImmutableSetMultimapTest extends TestCase {
49 @GwtIncompatible("suite")
50 public static Test suite() {
51 TestSuite suite = new TestSuite();
52 suite.addTestSuite(ImmutableSetMultimapTest.class);
53 suite.addTest(SetMultimapTestSuiteBuilder.using(new TestStringSetMultimapGenerator() {
54 @Override
55 protected SetMultimap<String, String> create(Entry<String, String>[] entries) {
56 ImmutableSetMultimap.Builder<String, String> builder = ImmutableSetMultimap.builder();
57 for (Entry<String, String> entry : entries) {
58 builder.put(entry.getKey(), entry.getValue());
59 }
60 return builder.build();
61 }
62 })
63 .named("ImmutableSetMultimap")
64 .withFeatures(
65 MapFeature.ALLOWS_ANY_NULL_QUERIES,
66 CollectionFeature.KNOWN_ORDER,
67 CollectionFeature.SERIALIZABLE,
68 CollectionSize.ANY)
69 .createTestSuite());
70 return suite;
71 }
72
73 public void testBuilder_withImmutableEntry() {
74 ImmutableSetMultimap<String, Integer> multimap = new Builder<String, Integer>()
75 .put(Maps.immutableEntry("one", 1))
76 .build();
77 assertEquals(ImmutableSet.of(1), multimap.get("one"));
78 }
79
80 public void testBuilder_withImmutableEntryAndNullContents() {
81 Builder<String, Integer> builder = new Builder<String, Integer>();
82 try {
83 builder.put(Maps.immutableEntry("one", (Integer) null));
84 fail();
85 } catch (NullPointerException expected) {
86 }
87 try {
88 builder.put(Maps.immutableEntry((String) null, 1));
89 fail();
90 } catch (NullPointerException expected) {
91 }
92 }
93
94 private static class StringHolder {
95 String string;
96 }
97
98 public void testBuilder_withMutableEntry() {
99 ImmutableSetMultimap.Builder<String, Integer> builder =
100 new Builder<String, Integer>();
101 final StringHolder holder = new StringHolder();
102 holder.string = "one";
103 Entry<String, Integer> entry = new AbstractMapEntry<String, Integer>() {
104 @Override public String getKey() {
105 return holder.string;
106 }
107 @Override public Integer getValue() {
108 return 1;
109 }
110 };
111
112 builder.put(entry);
113 holder.string = "two";
114 assertEquals(ImmutableSet.of(1), builder.build().get("one"));
115 }
116
117 public void testBuilderPutAllIterable() {
118 ImmutableSetMultimap.Builder<String, Integer> builder
119 = ImmutableSetMultimap.builder();
120 builder.putAll("foo", Arrays.asList(1, 2, 3));
121 builder.putAll("bar", Arrays.asList(4, 5));
122 builder.putAll("foo", Arrays.asList(6, 7));
123 Multimap<String, Integer> multimap = builder.build();
124 assertEquals(ImmutableSet.of(1, 2, 3, 6, 7), multimap.get("foo"));
125 assertEquals(ImmutableSet.of(4, 5), multimap.get("bar"));
126 assertEquals(7, multimap.size());
127 }
128
129 public void testBuilderPutAllVarargs() {
130 ImmutableSetMultimap.Builder<String, Integer> builder
131 = ImmutableSetMultimap.builder();
132 builder.putAll("foo", 1, 2, 3);
133 builder.putAll("bar", 4, 5);
134 builder.putAll("foo", 6, 7);
135 Multimap<String, Integer> multimap = builder.build();
136 assertEquals(ImmutableSet.of(1, 2, 3, 6, 7), multimap.get("foo"));
137 assertEquals(ImmutableSet.of(4, 5), multimap.get("bar"));
138 assertEquals(7, multimap.size());
139 }
140
141 public void testBuilderPutAllMultimap() {
142 Multimap<String, Integer> toPut = LinkedListMultimap.create();
143 toPut.put("foo", 1);
144 toPut.put("bar", 4);
145 toPut.put("foo", 2);
146 toPut.put("foo", 3);
147 Multimap<String, Integer> moreToPut = LinkedListMultimap.create();
148 moreToPut.put("foo", 6);
149 moreToPut.put("bar", 5);
150 moreToPut.put("foo", 7);
151 ImmutableSetMultimap.Builder<String, Integer> builder
152 = ImmutableSetMultimap.builder();
153 builder.putAll(toPut);
154 builder.putAll(moreToPut);
155 Multimap<String, Integer> multimap = builder.build();
156 assertEquals(ImmutableSet.of(1, 2, 3, 6, 7), multimap.get("foo"));
157 assertEquals(ImmutableSet.of(4, 5), multimap.get("bar"));
158 assertEquals(7, multimap.size());
159 }
160
161 public void testBuilderPutAllWithDuplicates() {
162 ImmutableSetMultimap.Builder<String, Integer> builder
163 = ImmutableSetMultimap.builder();
164 builder.putAll("foo", 1, 2, 3);
165 builder.putAll("bar", 4, 5);
166 builder.putAll("foo", 1, 6, 7);
167 ImmutableSetMultimap<String, Integer> multimap = builder.build();
168 assertEquals(7, multimap.size());
169 }
170
171 public void testBuilderPutWithDuplicates() {
172 ImmutableSetMultimap.Builder<String, Integer> builder
173 = ImmutableSetMultimap.builder();
174 builder.putAll("foo", 1, 2, 3);
175 builder.putAll("bar", 4, 5);
176 builder.put("foo", 1);
177 ImmutableSetMultimap<String, Integer> multimap = builder.build();
178 assertEquals(5, multimap.size());
179 }
180
181 public void testBuilderPutAllMultimapWithDuplicates() {
182 Multimap<String, Integer> toPut = LinkedListMultimap.create();
183 toPut.put("foo", 1);
184 toPut.put("bar", 4);
185 toPut.put("foo", 2);
186 toPut.put("foo", 1);
187 toPut.put("bar", 5);
188 ImmutableSetMultimap.Builder<String, Integer> builder
189 = ImmutableSetMultimap.builder();
190 builder.putAll(toPut);
191 ImmutableSetMultimap<String, Integer> multimap = builder.build();
192 assertEquals(4, multimap.size());
193 }
194
195 public void testBuilderPutNullKey() {
196 Multimap<String, Integer> toPut = LinkedListMultimap.create();
197 toPut.put("foo", null);
198 ImmutableSetMultimap.Builder<String, Integer> builder
199 = ImmutableSetMultimap.builder();
200 try {
201 builder.put(null, 1);
202 fail();
203 } catch (NullPointerException expected) {}
204 try {
205 builder.putAll(null, Arrays.asList(1, 2, 3));
206 fail();
207 } catch (NullPointerException expected) {}
208 try {
209 builder.putAll(null, 1, 2, 3);
210 fail();
211 } catch (NullPointerException expected) {}
212 try {
213 builder.putAll(toPut);
214 fail();
215 } catch (NullPointerException expected) {}
216 }
217
218 public void testBuilderPutNullValue() {
219 Multimap<String, Integer> toPut = LinkedListMultimap.create();
220 toPut.put(null, 1);
221 ImmutableSetMultimap.Builder<String, Integer> builder
222 = ImmutableSetMultimap.builder();
223 try {
224 builder.put("foo", null);
225 fail();
226 } catch (NullPointerException expected) {}
227 try {
228 builder.putAll("foo", Arrays.asList(1, null, 3));
229 fail();
230 } catch (NullPointerException expected) {}
231 try {
232 builder.putAll("foo", 4, null, 6);
233 fail();
234 } catch (NullPointerException expected) {}
235 try {
236 builder.putAll(toPut);
237 fail();
238 } catch (NullPointerException expected) {}
239 }
240
241 public void testBuilderOrderKeysBy() {
242 ImmutableSetMultimap.Builder<String, Integer> builder
243 = ImmutableSetMultimap.builder();
244 builder.put("b", 3);
245 builder.put("d", 2);
246 builder.put("a", 5);
247 builder.orderKeysBy(Collections.reverseOrder());
248 builder.put("c", 4);
249 builder.put("a", 2);
250 builder.put("b", 6);
251 ImmutableSetMultimap<String, Integer> multimap = builder.build();
252 assertThat(multimap.keySet()).has().exactly("d", "c", "b", "a").inOrder();
253 assertThat(multimap.values()).has().exactly(2, 4, 3, 6, 5, 2).inOrder();
254 assertThat(multimap.get("a")).has().exactly(5, 2).inOrder();
255 assertThat(multimap.get("b")).has().exactly(3, 6).inOrder();
256 assertFalse(multimap.get("a") instanceof ImmutableSortedSet);
257 assertFalse(multimap.get("x") instanceof ImmutableSortedSet);
258 assertFalse(multimap.asMap().get("a") instanceof ImmutableSortedSet);
259 }
260
261 public void testBuilderOrderKeysByDuplicates() {
262 ImmutableSetMultimap.Builder<String, Integer> builder
263 = ImmutableSetMultimap.builder();
264 builder.put("bb", 3);
265 builder.put("d", 2);
266 builder.put("a", 5);
267 builder.orderKeysBy(new Ordering<String>() {
268 @Override
269 public int compare(String left, String right) {
270 return left.length() - right.length();
271 }
272 });
273 builder.put("cc", 4);
274 builder.put("a", 2);
275 builder.put("bb", 6);
276 ImmutableSetMultimap<String, Integer> multimap = builder.build();
277 assertThat(multimap.keySet()).has().exactly("d", "a", "bb", "cc").inOrder();
278 assertThat(multimap.values()).has().exactly(2, 5, 2, 3, 6, 4).inOrder();
279 assertThat(multimap.get("a")).has().exactly(5, 2).inOrder();
280 assertThat(multimap.get("bb")).has().exactly(3, 6).inOrder();
281 assertFalse(multimap.get("a") instanceof ImmutableSortedSet);
282 assertFalse(multimap.get("x") instanceof ImmutableSortedSet);
283 assertFalse(multimap.asMap().get("a") instanceof ImmutableSortedSet);
284 }
285
286 public void testBuilderOrderValuesBy() {
287 ImmutableSetMultimap.Builder<String, Integer> builder
288 = ImmutableSetMultimap.builder();
289 builder.put("b", 3);
290 builder.put("d", 2);
291 builder.put("a", 5);
292 builder.orderValuesBy(Collections.reverseOrder());
293 builder.put("c", 4);
294 builder.put("a", 2);
295 builder.put("b", 6);
296 ImmutableSetMultimap<String, Integer> multimap = builder.build();
297 assertThat(multimap.keySet()).has().exactly("b", "d", "a", "c").inOrder();
298 assertThat(multimap.values()).has().exactly(6, 3, 2, 5, 2, 4).inOrder();
299 assertThat(multimap.get("a")).has().exactly(5, 2).inOrder();
300 assertThat(multimap.get("b")).has().exactly(6, 3).inOrder();
301 assertTrue(multimap.get("a") instanceof ImmutableSortedSet);
302 assertEquals(Collections.reverseOrder(),
303 ((ImmutableSortedSet<Integer>) multimap.get("a")).comparator());
304 assertTrue(multimap.get("x") instanceof ImmutableSortedSet);
305 assertEquals(Collections.reverseOrder(),
306 ((ImmutableSortedSet<Integer>) multimap.get("x")).comparator());
307 assertTrue(multimap.asMap().get("a") instanceof ImmutableSortedSet);
308 assertEquals(Collections.reverseOrder(),
309 ((ImmutableSortedSet<Integer>) multimap.asMap().get("a")).comparator());
310 }
311
312 public void testBuilderOrderKeysAndValuesBy() {
313 ImmutableSetMultimap.Builder<String, Integer> builder
314 = ImmutableSetMultimap.builder();
315 builder.put("b", 3);
316 builder.put("d", 2);
317 builder.put("a", 5);
318 builder.orderKeysBy(Collections.reverseOrder());
319 builder.orderValuesBy(Collections.reverseOrder());
320 builder.put("c", 4);
321 builder.put("a", 2);
322 builder.put("b", 6);
323 ImmutableSetMultimap<String, Integer> multimap = builder.build();
324 assertThat(multimap.keySet()).has().exactly("d", "c", "b", "a").inOrder();
325 assertThat(multimap.values()).has().exactly(2, 4, 6, 3, 5, 2).inOrder();
326 assertThat(multimap.get("a")).has().exactly(5, 2).inOrder();
327 assertThat(multimap.get("b")).has().exactly(6, 3).inOrder();
328 assertTrue(multimap.get("a") instanceof ImmutableSortedSet);
329 assertEquals(Collections.reverseOrder(),
330 ((ImmutableSortedSet<Integer>) multimap.get("a")).comparator());
331 assertTrue(multimap.get("x") instanceof ImmutableSortedSet);
332 assertEquals(Collections.reverseOrder(),
333 ((ImmutableSortedSet<Integer>) multimap.get("x")).comparator());
334 assertTrue(multimap.asMap().get("a") instanceof ImmutableSortedSet);
335 assertEquals(Collections.reverseOrder(),
336 ((ImmutableSortedSet<Integer>) multimap.asMap().get("a")).comparator());
337 }
338
339 public void testCopyOf() {
340 HashMultimap<String, Integer> input = HashMultimap.create();
341 input.put("foo", 1);
342 input.put("bar", 2);
343 input.put("foo", 3);
344 Multimap<String, Integer> multimap = ImmutableSetMultimap.copyOf(input);
345 assertEquals(multimap, input);
346 assertEquals(input, multimap);
347 }
348
349 public void testCopyOfWithDuplicates() {
350 ArrayListMultimap<Object, Object> input = ArrayListMultimap.create();
351 input.put("foo", 1);
352 input.put("bar", 2);
353 input.put("foo", 3);
354 input.put("foo", 1);
355 ImmutableSetMultimap<Object, Object> copy
356 = ImmutableSetMultimap.copyOf(input);
357 assertEquals(3, copy.size());
358 }
359
360 public void testCopyOfEmpty() {
361 HashMultimap<String, Integer> input = HashMultimap.create();
362 Multimap<String, Integer> multimap = ImmutableSetMultimap.copyOf(input);
363 assertEquals(multimap, input);
364 assertEquals(input, multimap);
365 }
366
367 public void testCopyOfImmutableSetMultimap() {
368 Multimap<String, Integer> multimap = createMultimap();
369 assertSame(multimap, ImmutableSetMultimap.copyOf(multimap));
370 }
371
372 public void testCopyOfNullKey() {
373 HashMultimap<String, Integer> input = HashMultimap.create();
374 input.put(null, 1);
375 try {
376 ImmutableSetMultimap.copyOf(input);
377 fail();
378 } catch (NullPointerException expected) {}
379 }
380
381 public void testCopyOfNullValue() {
382 HashMultimap<String, Integer> input = HashMultimap.create();
383 input.putAll("foo", Arrays.asList(1, null, 3));
384 try {
385 ImmutableSetMultimap.copyOf(input);
386 fail();
387 } catch (NullPointerException expected) {}
388 }
389
390 public void testEmptyMultimapReads() {
391 Multimap<String, Integer> multimap = ImmutableSetMultimap.of();
392 assertFalse(multimap.containsKey("foo"));
393 assertFalse(multimap.containsValue(1));
394 assertFalse(multimap.containsEntry("foo", 1));
395 assertTrue(multimap.entries().isEmpty());
396 assertTrue(multimap.equals(HashMultimap.create()));
397 assertEquals(Collections.emptySet(), multimap.get("foo"));
398 assertEquals(0, multimap.hashCode());
399 assertTrue(multimap.isEmpty());
400 assertEquals(HashMultiset.create(), multimap.keys());
401 assertEquals(Collections.emptySet(), multimap.keySet());
402 assertEquals(0, multimap.size());
403 assertTrue(multimap.values().isEmpty());
404 assertEquals("{}", multimap.toString());
405 }
406
407 public void testEmptyMultimapWrites() {
408 Multimap<String, Integer> multimap = ImmutableSetMultimap.of();
409 UnmodifiableCollectionTests.assertMultimapIsUnmodifiable(
410 multimap, "foo", 1);
411 }
412
413 public void testMultimapReads() {
414 Multimap<String, Integer> multimap = createMultimap();
415 assertTrue(multimap.containsKey("foo"));
416 assertFalse(multimap.containsKey("cat"));
417 assertTrue(multimap.containsValue(1));
418 assertFalse(multimap.containsValue(5));
419 assertTrue(multimap.containsEntry("foo", 1));
420 assertFalse(multimap.containsEntry("cat", 1));
421 assertFalse(multimap.containsEntry("foo", 5));
422 assertFalse(multimap.entries().isEmpty());
423 assertEquals(3, multimap.size());
424 assertFalse(multimap.isEmpty());
425 assertEquals("{foo=[1, 3], bar=[2]}", multimap.toString());
426 }
427
428 public void testMultimapWrites() {
429 Multimap<String, Integer> multimap = createMultimap();
430 UnmodifiableCollectionTests.assertMultimapIsUnmodifiable(
431 multimap, "bar", 2);
432 }
433
434 public void testMultimapEquals() {
435 Multimap<String, Integer> multimap = createMultimap();
436 Multimap<String, Integer> hashMultimap = HashMultimap.create();
437 hashMultimap.putAll("foo", Arrays.asList(1, 3));
438 hashMultimap.put("bar", 2);
439
440 new EqualsTester()
441 .addEqualityGroup(
442 multimap,
443 createMultimap(),
444 hashMultimap,
445 ImmutableSetMultimap.<String, Integer>builder()
446 .put("bar", 2).put("foo", 1).put("foo", 3).build(),
447 ImmutableSetMultimap.<String, Integer>builder()
448 .put("bar", 2).put("foo", 3).put("foo", 1).build())
449 .addEqualityGroup(ImmutableSetMultimap.<String, Integer>builder()
450 .put("foo", 2).put("foo", 3).put("foo", 1).build())
451 .addEqualityGroup(ImmutableSetMultimap.<String, Integer>builder()
452 .put("bar", 2).put("foo", 3).build())
453 .testEquals();
454 }
455
456 public void testOf() {
457 assertMultimapEquals(
458 ImmutableSetMultimap.of("one", 1),
459 "one", 1);
460 assertMultimapEquals(
461 ImmutableSetMultimap.of("one", 1, "two", 2),
462 "one", 1, "two", 2);
463 assertMultimapEquals(
464 ImmutableSetMultimap.of("one", 1, "two", 2, "three", 3),
465 "one", 1, "two", 2, "three", 3);
466 assertMultimapEquals(
467 ImmutableSetMultimap.of("one", 1, "two", 2, "three", 3, "four", 4),
468 "one", 1, "two", 2, "three", 3, "four", 4);
469 assertMultimapEquals(
470 ImmutableSetMultimap.of(
471 "one", 1, "two", 2, "three", 3, "four", 4, "five", 5),
472 "one", 1, "two", 2, "three", 3, "four", 4, "five", 5);
473 }
474
475 public void testInverse() {
476 assertEquals(
477 ImmutableSetMultimap.<Integer, String>of(),
478 ImmutableSetMultimap.<String, Integer>of().inverse());
479 assertEquals(
480 ImmutableSetMultimap.of(1, "one"),
481 ImmutableSetMultimap.of("one", 1).inverse());
482 assertEquals(
483 ImmutableSetMultimap.of(1, "one", 2, "two"),
484 ImmutableSetMultimap.of("one", 1, "two", 2).inverse());
485 assertEquals(
486 ImmutableSetMultimap.of('o', "of", 'f', "of", 't', "to", 'o', "to"),
487 ImmutableSetMultimap.of("of", 'o', "of", 'f', "to", 't', "to", 'o').inverse());
488 }
489
490 public void testInverseMinimizesWork() {
491 ImmutableSetMultimap<String, Character> multimap =
492 ImmutableSetMultimap.of("of", 'o', "of", 'f', "to", 't', "to", 'o');
493 assertSame(multimap.inverse(), multimap.inverse());
494 assertSame(multimap, multimap.inverse().inverse());
495 }
496
497 private static <K, V> void assertMultimapEquals(Multimap<K, V> multimap,
498 Object... alternatingKeysAndValues) {
499 assertEquals(multimap.size(), alternatingKeysAndValues.length / 2);
500 int i = 0;
501 for (Entry<K, V> entry : multimap.entries()) {
502 assertEquals(alternatingKeysAndValues[i++], entry.getKey());
503 assertEquals(alternatingKeysAndValues[i++], entry.getValue());
504 }
505 }
506
507 @GwtIncompatible("SerializableTester")
508 public void testSerialization() {
509 Multimap<String, Integer> multimap = createMultimap();
510 SerializableTester.reserializeAndAssert(multimap);
511 assertEquals(multimap.size(),
512 SerializableTester.reserialize(multimap).size());
513 SerializableTester.reserializeAndAssert(multimap.get("foo"));
514 LenientSerializableTester.reserializeAndAssertLenient(multimap.keySet());
515 LenientSerializableTester.reserializeAndAssertLenient(multimap.keys());
516 SerializableTester.reserializeAndAssert(multimap.asMap());
517 Collection<Integer> valuesCopy
518 = SerializableTester.reserialize(multimap.values());
519 assertEquals(HashMultiset.create(multimap.values()),
520 HashMultiset.create(valuesCopy));
521 }
522
523 @GwtIncompatible("SerializableTester")
524 public void testEmptySerialization() {
525 Multimap<String, Integer> multimap = ImmutableSetMultimap.of();
526 assertSame(multimap, SerializableTester.reserialize(multimap));
527 }
528
529 @GwtIncompatible("SerializableTester")
530 public void testSortedSerialization() {
531 Multimap<String, Integer> multimap = new ImmutableSetMultimap.Builder<String, Integer>()
532 .orderKeysBy(Ordering.natural().reverse())
533 .orderValuesBy(Ordering.usingToString())
534 .put("a", 2)
535 .put("a", 10)
536 .put("b", 1)
537 .build();
538 multimap = SerializableTester.reserialize(multimap);
539 assertThat(multimap.keySet()).has().exactly("b", "a").inOrder();
540 assertThat(multimap.get("a")).has().exactly(10, 2).inOrder();
541 assertEquals(Ordering.usingToString(),
542 ((ImmutableSortedSet<Integer>) multimap.get("a")).comparator());
543 assertEquals(Ordering.usingToString(),
544 ((ImmutableSortedSet<Integer>) multimap.get("z")).comparator());
545 }
546
547 private ImmutableSetMultimap<String, Integer> createMultimap() {
548 return ImmutableSetMultimap.<String, Integer>builder()
549 .put("foo", 1).put("bar", 2).put("foo", 3).build();
550 }
551 }