• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2009 The Guava Authors
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.google.common.collect;
18 
19 import static com.google.common.collect.testing.Helpers.mapEntry;
20 import static com.google.common.collect.testing.features.CollectionFeature.KNOWN_ORDER;
21 import static com.google.common.collect.testing.features.CollectionFeature.SERIALIZABLE;
22 import static com.google.common.collect.testing.features.MapFeature.ALLOWS_ANY_NULL_QUERIES;
23 import static com.google.common.truth.Truth.assertThat;
24 
25 import com.google.common.annotations.GwtCompatible;
26 import com.google.common.annotations.GwtIncompatible;
27 import com.google.common.base.Equivalence;
28 import com.google.common.collect.ImmutableSetMultimap.Builder;
29 import com.google.common.collect.testing.features.CollectionSize;
30 import com.google.common.collect.testing.google.SetMultimapTestSuiteBuilder;
31 import com.google.common.collect.testing.google.TestStringSetMultimapGenerator;
32 import com.google.common.collect.testing.google.UnmodifiableCollectionTests;
33 import com.google.common.testing.CollectorTester;
34 import com.google.common.testing.EqualsTester;
35 import com.google.common.testing.SerializableTester;
36 import java.util.Arrays;
37 import java.util.Collection;
38 import java.util.Collections;
39 import java.util.Map.Entry;
40 import java.util.function.BiPredicate;
41 import java.util.stream.Collector;
42 import junit.framework.Test;
43 import junit.framework.TestCase;
44 import junit.framework.TestSuite;
45 
46 /**
47  * Tests for {@link ImmutableSetMultimap}.
48  *
49  * @author Mike Ward
50  */
51 @GwtCompatible(emulated = true)
52 public class ImmutableSetMultimapTest extends TestCase {
53   private static final class ImmutableSetMultimapGenerator extends TestStringSetMultimapGenerator {
54     @Override
create(Entry<String, String>[] entries)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 
64   private static final class ImmutableSetMultimapCopyOfEntriesGenerator
65       extends TestStringSetMultimapGenerator {
66     @Override
create(Entry<String, String>[] entries)67     protected SetMultimap<String, String> create(Entry<String, String>[] entries) {
68       return ImmutableSetMultimap.copyOf(Arrays.asList(entries));
69     }
70   }
71 
72   @GwtIncompatible // suite
suite()73   public static Test suite() {
74     TestSuite suite = new TestSuite();
75     suite.addTestSuite(ImmutableSetMultimapTest.class);
76     suite.addTest(
77         SetMultimapTestSuiteBuilder.using(new ImmutableSetMultimapGenerator())
78             .named("ImmutableSetMultimap")
79             .withFeatures(ALLOWS_ANY_NULL_QUERIES, KNOWN_ORDER, SERIALIZABLE, CollectionSize.ANY)
80             .createTestSuite());
81     suite.addTest(
82         SetMultimapTestSuiteBuilder.using(new ImmutableSetMultimapCopyOfEntriesGenerator())
83             .named("ImmutableSetMultimap.copyOf[Iterable<Entry>]")
84             .withFeatures(ALLOWS_ANY_NULL_QUERIES, KNOWN_ORDER, SERIALIZABLE, CollectionSize.ANY)
85             .createTestSuite());
86     return suite;
87   }
88 
testBuilder_withImmutableEntry()89   public void testBuilder_withImmutableEntry() {
90     ImmutableSetMultimap<String, Integer> multimap =
91         new Builder<String, Integer>().put(Maps.immutableEntry("one", 1)).build();
92     assertEquals(ImmutableSet.of(1), multimap.get("one"));
93   }
94 
testBuilder_withImmutableEntryAndNullContents()95   public void testBuilder_withImmutableEntryAndNullContents() {
96     Builder<String, Integer> builder = new Builder<>();
97     try {
98       builder.put(Maps.immutableEntry("one", (Integer) null));
99       fail();
100     } catch (NullPointerException expected) {
101     }
102     try {
103       builder.put(Maps.immutableEntry((String) null, 1));
104       fail();
105     } catch (NullPointerException expected) {
106     }
107   }
108 
109   private static class StringHolder {
110     String string;
111   }
112 
testBuilder_withMutableEntry()113   public void testBuilder_withMutableEntry() {
114     ImmutableSetMultimap.Builder<String, Integer> builder = new Builder<>();
115     final StringHolder holder = new StringHolder();
116     holder.string = "one";
117     Entry<String, Integer> entry =
118         new AbstractMapEntry<String, Integer>() {
119           @Override
120           public String getKey() {
121             return holder.string;
122           }
123 
124           @Override
125           public Integer getValue() {
126             return 1;
127           }
128         };
129 
130     builder.put(entry);
131     holder.string = "two";
132     assertEquals(ImmutableSet.of(1), builder.build().get("one"));
133   }
134 
testBuilderPutAllIterable()135   public void testBuilderPutAllIterable() {
136     ImmutableSetMultimap.Builder<String, Integer> builder = ImmutableSetMultimap.builder();
137     builder.putAll("foo", Arrays.asList(1, 2, 3));
138     builder.putAll("bar", Arrays.asList(4, 5));
139     builder.putAll("foo", Arrays.asList(6, 7));
140     Multimap<String, Integer> multimap = builder.build();
141     assertEquals(ImmutableSet.of(1, 2, 3, 6, 7), multimap.get("foo"));
142     assertEquals(ImmutableSet.of(4, 5), multimap.get("bar"));
143     assertEquals(7, multimap.size());
144   }
145 
testBuilderPutAllVarargs()146   public void testBuilderPutAllVarargs() {
147     ImmutableSetMultimap.Builder<String, Integer> builder = ImmutableSetMultimap.builder();
148     builder.putAll("foo", 1, 2, 3);
149     builder.putAll("bar", 4, 5);
150     builder.putAll("foo", 6, 7);
151     Multimap<String, Integer> multimap = builder.build();
152     assertEquals(ImmutableSet.of(1, 2, 3, 6, 7), multimap.get("foo"));
153     assertEquals(ImmutableSet.of(4, 5), multimap.get("bar"));
154     assertEquals(7, multimap.size());
155   }
156 
testBuilderPutAllMultimap()157   public void testBuilderPutAllMultimap() {
158     Multimap<String, Integer> toPut = LinkedListMultimap.create();
159     toPut.put("foo", 1);
160     toPut.put("bar", 4);
161     toPut.put("foo", 2);
162     toPut.put("foo", 3);
163     Multimap<String, Integer> moreToPut = LinkedListMultimap.create();
164     moreToPut.put("foo", 6);
165     moreToPut.put("bar", 5);
166     moreToPut.put("foo", 7);
167     ImmutableSetMultimap.Builder<String, Integer> builder = ImmutableSetMultimap.builder();
168     builder.putAll(toPut);
169     builder.putAll(moreToPut);
170     Multimap<String, Integer> multimap = builder.build();
171     assertEquals(ImmutableSet.of(1, 2, 3, 6, 7), multimap.get("foo"));
172     assertEquals(ImmutableSet.of(4, 5), multimap.get("bar"));
173     assertEquals(7, multimap.size());
174   }
175 
testBuilderPutAllWithDuplicates()176   public void testBuilderPutAllWithDuplicates() {
177     ImmutableSetMultimap.Builder<String, Integer> builder = ImmutableSetMultimap.builder();
178     builder.putAll("foo", 1, 2, 3);
179     builder.putAll("bar", 4, 5);
180     builder.putAll("foo", 1, 6, 7);
181     ImmutableSetMultimap<String, Integer> multimap = builder.build();
182     assertEquals(7, multimap.size());
183   }
184 
testBuilderPutWithDuplicates()185   public void testBuilderPutWithDuplicates() {
186     ImmutableSetMultimap.Builder<String, Integer> builder = ImmutableSetMultimap.builder();
187     builder.putAll("foo", 1, 2, 3);
188     builder.putAll("bar", 4, 5);
189     builder.put("foo", 1);
190     ImmutableSetMultimap<String, Integer> multimap = builder.build();
191     assertEquals(5, multimap.size());
192   }
193 
testBuilderPutAllMultimapWithDuplicates()194   public void testBuilderPutAllMultimapWithDuplicates() {
195     Multimap<String, Integer> toPut = LinkedListMultimap.create();
196     toPut.put("foo", 1);
197     toPut.put("bar", 4);
198     toPut.put("foo", 2);
199     toPut.put("foo", 1);
200     toPut.put("bar", 5);
201     ImmutableSetMultimap.Builder<String, Integer> builder = ImmutableSetMultimap.builder();
202     builder.putAll(toPut);
203     ImmutableSetMultimap<String, Integer> multimap = builder.build();
204     assertEquals(4, multimap.size());
205   }
206 
testBuilderPutNullKey()207   public void testBuilderPutNullKey() {
208     Multimap<String, Integer> toPut = LinkedListMultimap.create();
209     toPut.put("foo", null);
210     ImmutableSetMultimap.Builder<String, Integer> builder = ImmutableSetMultimap.builder();
211     try {
212       builder.put(null, 1);
213       fail();
214     } catch (NullPointerException expected) {
215     }
216     try {
217       builder.putAll(null, Arrays.asList(1, 2, 3));
218       fail();
219     } catch (NullPointerException expected) {
220     }
221     try {
222       builder.putAll(null, 1, 2, 3);
223       fail();
224     } catch (NullPointerException expected) {
225     }
226     try {
227       builder.putAll(toPut);
228       fail();
229     } catch (NullPointerException expected) {
230     }
231   }
232 
testBuilderPutNullValue()233   public void testBuilderPutNullValue() {
234     Multimap<String, Integer> toPut = LinkedListMultimap.create();
235     toPut.put(null, 1);
236     ImmutableSetMultimap.Builder<String, Integer> builder = ImmutableSetMultimap.builder();
237     try {
238       builder.put("foo", null);
239       fail();
240     } catch (NullPointerException expected) {
241     }
242     try {
243       builder.putAll("foo", Arrays.asList(1, null, 3));
244       fail();
245     } catch (NullPointerException expected) {
246     }
247     try {
248       builder.putAll("foo", 4, null, 6);
249       fail();
250     } catch (NullPointerException expected) {
251     }
252     try {
253       builder.putAll(toPut);
254       fail();
255     } catch (NullPointerException expected) {
256     }
257   }
258 
testBuilderOrderKeysBy()259   public void testBuilderOrderKeysBy() {
260     ImmutableSetMultimap.Builder<String, Integer> builder = ImmutableSetMultimap.builder();
261     builder.put("b", 3);
262     builder.put("d", 2);
263     builder.put("a", 5);
264     builder.orderKeysBy(Collections.reverseOrder());
265     builder.put("c", 4);
266     builder.put("a", 2);
267     builder.put("b", 6);
268     ImmutableSetMultimap<String, Integer> multimap = builder.build();
269     assertThat(multimap.keySet()).containsExactly("d", "c", "b", "a").inOrder();
270     assertThat(multimap.values()).containsExactly(2, 4, 3, 6, 5, 2).inOrder();
271     assertThat(multimap.get("a")).containsExactly(5, 2).inOrder();
272     assertThat(multimap.get("b")).containsExactly(3, 6).inOrder();
273     assertFalse(multimap.get("a") instanceof ImmutableSortedSet);
274     assertFalse(multimap.get("x") instanceof ImmutableSortedSet);
275     assertFalse(multimap.asMap().get("a") instanceof ImmutableSortedSet);
276   }
277 
testBuilderOrderKeysByDuplicates()278   public void testBuilderOrderKeysByDuplicates() {
279     ImmutableSetMultimap.Builder<String, Integer> builder = ImmutableSetMultimap.builder();
280     builder.put("bb", 3);
281     builder.put("d", 2);
282     builder.put("a", 5);
283     builder.orderKeysBy(
284         new Ordering<String>() {
285           @Override
286           public int compare(String left, String right) {
287             return left.length() - right.length();
288           }
289         });
290     builder.put("cc", 4);
291     builder.put("a", 2);
292     builder.put("bb", 6);
293     ImmutableSetMultimap<String, Integer> multimap = builder.build();
294     assertThat(multimap.keySet()).containsExactly("d", "a", "bb", "cc").inOrder();
295     assertThat(multimap.values()).containsExactly(2, 5, 2, 3, 6, 4).inOrder();
296     assertThat(multimap.get("a")).containsExactly(5, 2).inOrder();
297     assertThat(multimap.get("bb")).containsExactly(3, 6).inOrder();
298     assertFalse(multimap.get("a") instanceof ImmutableSortedSet);
299     assertFalse(multimap.get("x") instanceof ImmutableSortedSet);
300     assertFalse(multimap.asMap().get("a") instanceof ImmutableSortedSet);
301   }
302 
testBuilderOrderValuesBy()303   public void testBuilderOrderValuesBy() {
304     ImmutableSetMultimap.Builder<String, Integer> builder = ImmutableSetMultimap.builder();
305     builder.put("b", 3);
306     builder.put("d", 2);
307     builder.put("a", 5);
308     builder.orderValuesBy(Collections.reverseOrder());
309     builder.put("c", 4);
310     builder.put("a", 2);
311     builder.put("b", 6);
312     ImmutableSetMultimap<String, Integer> multimap = builder.build();
313     assertThat(multimap.keySet()).containsExactly("b", "d", "a", "c").inOrder();
314     assertThat(multimap.values()).containsExactly(6, 3, 2, 5, 2, 4).inOrder();
315     assertThat(multimap.get("a")).containsExactly(5, 2).inOrder();
316     assertThat(multimap.get("b")).containsExactly(6, 3).inOrder();
317     assertTrue(multimap.get("a") instanceof ImmutableSortedSet);
318     assertEquals(
319         Collections.reverseOrder(), ((ImmutableSortedSet<Integer>) multimap.get("a")).comparator());
320     assertTrue(multimap.get("x") instanceof ImmutableSortedSet);
321     assertEquals(
322         Collections.reverseOrder(), ((ImmutableSortedSet<Integer>) multimap.get("x")).comparator());
323     assertTrue(multimap.asMap().get("a") instanceof ImmutableSortedSet);
324     assertEquals(
325         Collections.reverseOrder(),
326         ((ImmutableSortedSet<Integer>) multimap.asMap().get("a")).comparator());
327   }
328 
testBuilderOrderKeysAndValuesBy()329   public void testBuilderOrderKeysAndValuesBy() {
330     ImmutableSetMultimap.Builder<String, Integer> builder = ImmutableSetMultimap.builder();
331     builder.put("b", 3);
332     builder.put("d", 2);
333     builder.put("a", 5);
334     builder.orderKeysBy(Collections.reverseOrder());
335     builder.orderValuesBy(Collections.reverseOrder());
336     builder.put("c", 4);
337     builder.put("a", 2);
338     builder.put("b", 6);
339     ImmutableSetMultimap<String, Integer> multimap = builder.build();
340     assertThat(multimap.keySet()).containsExactly("d", "c", "b", "a").inOrder();
341     assertThat(multimap.values()).containsExactly(2, 4, 6, 3, 5, 2).inOrder();
342     assertThat(multimap.get("a")).containsExactly(5, 2).inOrder();
343     assertThat(multimap.get("b")).containsExactly(6, 3).inOrder();
344     assertTrue(multimap.get("a") instanceof ImmutableSortedSet);
345     assertEquals(
346         Collections.reverseOrder(), ((ImmutableSortedSet<Integer>) multimap.get("a")).comparator());
347     assertTrue(multimap.get("x") instanceof ImmutableSortedSet);
348     assertEquals(
349         Collections.reverseOrder(), ((ImmutableSortedSet<Integer>) multimap.get("x")).comparator());
350     assertTrue(multimap.asMap().get("a") instanceof ImmutableSortedSet);
351     assertEquals(
352         Collections.reverseOrder(),
353         ((ImmutableSortedSet<Integer>) multimap.asMap().get("a")).comparator());
354   }
355 
testCopyOf()356   public void testCopyOf() {
357     HashMultimap<String, Integer> input = HashMultimap.create();
358     input.put("foo", 1);
359     input.put("bar", 2);
360     input.put("foo", 3);
361     Multimap<String, Integer> multimap = ImmutableSetMultimap.copyOf(input);
362     assertEquals(multimap, input);
363     assertEquals(input, multimap);
364   }
365 
testCopyOfWithDuplicates()366   public void testCopyOfWithDuplicates() {
367     ArrayListMultimap<Object, Object> input = ArrayListMultimap.create();
368     input.put("foo", 1);
369     input.put("bar", 2);
370     input.put("foo", 3);
371     input.put("foo", 1);
372     ImmutableSetMultimap<Object, Object> copy = ImmutableSetMultimap.copyOf(input);
373     assertEquals(3, copy.size());
374   }
375 
testCopyOfEmpty()376   public void testCopyOfEmpty() {
377     HashMultimap<String, Integer> input = HashMultimap.create();
378     Multimap<String, Integer> multimap = ImmutableSetMultimap.copyOf(input);
379     assertEquals(multimap, input);
380     assertEquals(input, multimap);
381   }
382 
testCopyOfImmutableSetMultimap()383   public void testCopyOfImmutableSetMultimap() {
384     Multimap<String, Integer> multimap = createMultimap();
385     assertSame(multimap, ImmutableSetMultimap.copyOf(multimap));
386   }
387 
testCopyOfNullKey()388   public void testCopyOfNullKey() {
389     HashMultimap<String, Integer> input = HashMultimap.create();
390     input.put(null, 1);
391     try {
392       ImmutableSetMultimap.copyOf(input);
393       fail();
394     } catch (NullPointerException expected) {
395     }
396   }
397 
testCopyOfNullValue()398   public void testCopyOfNullValue() {
399     HashMultimap<String, Integer> input = HashMultimap.create();
400     input.putAll("foo", Arrays.asList(1, null, 3));
401     try {
402       ImmutableSetMultimap.copyOf(input);
403       fail();
404     } catch (NullPointerException expected) {
405     }
406   }
407 
testToImmutableSetMultimap()408   public void testToImmutableSetMultimap() {
409     Collector<Entry<String, Integer>, ?, ImmutableSetMultimap<String, Integer>> collector =
410         ImmutableSetMultimap.toImmutableSetMultimap(Entry::getKey, Entry::getValue);
411     BiPredicate<ImmutableSetMultimap<?, ?>, ImmutableSetMultimap<?, ?>> equivalence =
412         Equivalence.equals()
413             .onResultOf(
414                 (ImmutableSetMultimap<?, ?> mm) ->
415                     ImmutableListMultimap.copyOf(mm).asMap().entrySet().asList())
416             .and(Equivalence.equals());
417     CollectorTester.of(collector, equivalence)
418         .expectCollects(ImmutableSetMultimap.of())
419         .expectCollects(
420             ImmutableSetMultimap.of("a", 1, "b", 2, "a", 3, "c", 4),
421             mapEntry("a", 1),
422             mapEntry("b", 2),
423             mapEntry("a", 3),
424             mapEntry("c", 4));
425   }
426 
testFlatteningToImmutableSetMultimap()427   public void testFlatteningToImmutableSetMultimap() {
428     Collector<String, ?, ImmutableSetMultimap<Character, Character>> collector =
429         ImmutableSetMultimap.flatteningToImmutableSetMultimap(
430             str -> str.charAt(0), str -> str.substring(1).chars().mapToObj(c -> (char) c));
431     BiPredicate<Multimap<?, ?>, Multimap<?, ?>> equivalence =
432         Equivalence.equals()
433             .onResultOf((Multimap<?, ?> mm) -> ImmutableList.copyOf(mm.asMap().entrySet()))
434             .and(Equivalence.equals());
435     ImmutableSetMultimap<Character, Character> empty = ImmutableSetMultimap.of();
436     ImmutableSetMultimap<Character, Character> filled =
437         ImmutableSetMultimap.<Character, Character>builder()
438             .putAll('b', Arrays.asList('a', 'n', 'a', 'n', 'a'))
439             .putAll('a', Arrays.asList('p', 'p', 'l', 'e'))
440             .putAll('c', Arrays.asList('a', 'r', 'r', 'o', 't'))
441             .putAll('a', Arrays.asList('s', 'p', 'a', 'r', 'a', 'g', 'u', 's'))
442             .putAll('c', Arrays.asList('h', 'e', 'r', 'r', 'y'))
443             .build();
444     CollectorTester.of(collector, equivalence)
445         .expectCollects(empty)
446         .expectCollects(filled, "banana", "apple", "carrot", "asparagus", "cherry");
447   }
448 
testEmptyMultimapReads()449   public void testEmptyMultimapReads() {
450     Multimap<String, Integer> multimap = ImmutableSetMultimap.of();
451     assertFalse(multimap.containsKey("foo"));
452     assertFalse(multimap.containsValue(1));
453     assertFalse(multimap.containsEntry("foo", 1));
454     assertTrue(multimap.entries().isEmpty());
455     assertTrue(multimap.equals(HashMultimap.create()));
456     assertEquals(Collections.emptySet(), multimap.get("foo"));
457     assertEquals(0, multimap.hashCode());
458     assertTrue(multimap.isEmpty());
459     assertEquals(HashMultiset.create(), multimap.keys());
460     assertEquals(Collections.emptySet(), multimap.keySet());
461     assertEquals(0, multimap.size());
462     assertTrue(multimap.values().isEmpty());
463     assertEquals("{}", multimap.toString());
464   }
465 
testEmptyMultimapWrites()466   public void testEmptyMultimapWrites() {
467     Multimap<String, Integer> multimap = ImmutableSetMultimap.of();
468     UnmodifiableCollectionTests.assertMultimapIsUnmodifiable(multimap, "foo", 1);
469   }
470 
testMultimapReads()471   public void testMultimapReads() {
472     Multimap<String, Integer> multimap = createMultimap();
473     assertTrue(multimap.containsKey("foo"));
474     assertFalse(multimap.containsKey("cat"));
475     assertTrue(multimap.containsValue(1));
476     assertFalse(multimap.containsValue(5));
477     assertTrue(multimap.containsEntry("foo", 1));
478     assertFalse(multimap.containsEntry("cat", 1));
479     assertFalse(multimap.containsEntry("foo", 5));
480     assertFalse(multimap.entries().isEmpty());
481     assertEquals(3, multimap.size());
482     assertFalse(multimap.isEmpty());
483     assertEquals("{foo=[1, 3], bar=[2]}", multimap.toString());
484   }
485 
testMultimapWrites()486   public void testMultimapWrites() {
487     Multimap<String, Integer> multimap = createMultimap();
488     UnmodifiableCollectionTests.assertMultimapIsUnmodifiable(multimap, "bar", 2);
489   }
490 
testMultimapEquals()491   public void testMultimapEquals() {
492     Multimap<String, Integer> multimap = createMultimap();
493     Multimap<String, Integer> hashMultimap = HashMultimap.create();
494     hashMultimap.putAll("foo", Arrays.asList(1, 3));
495     hashMultimap.put("bar", 2);
496 
497     new EqualsTester()
498         .addEqualityGroup(
499             multimap,
500             createMultimap(),
501             hashMultimap,
502             ImmutableSetMultimap.<String, Integer>builder()
503                 .put("bar", 2)
504                 .put("foo", 1)
505                 .put("foo", 3)
506                 .build(),
507             ImmutableSetMultimap.<String, Integer>builder()
508                 .put("bar", 2)
509                 .put("foo", 3)
510                 .put("foo", 1)
511                 .build())
512         .addEqualityGroup(
513             ImmutableSetMultimap.<String, Integer>builder()
514                 .put("foo", 2)
515                 .put("foo", 3)
516                 .put("foo", 1)
517                 .build())
518         .addEqualityGroup(
519             ImmutableSetMultimap.<String, Integer>builder().put("bar", 2).put("foo", 3).build())
520         .testEquals();
521   }
522 
testOf()523   public void testOf() {
524     assertMultimapEquals(ImmutableSetMultimap.of("one", 1), "one", 1);
525     assertMultimapEquals(ImmutableSetMultimap.of("one", 1, "two", 2), "one", 1, "two", 2);
526     assertMultimapEquals(
527         ImmutableSetMultimap.of("one", 1, "two", 2, "three", 3), "one", 1, "two", 2, "three", 3);
528     assertMultimapEquals(
529         ImmutableSetMultimap.of("one", 1, "two", 2, "three", 3, "four", 4),
530         "one",
531         1,
532         "two",
533         2,
534         "three",
535         3,
536         "four",
537         4);
538     assertMultimapEquals(
539         ImmutableSetMultimap.of("one", 1, "two", 2, "three", 3, "four", 4, "five", 5),
540         "one",
541         1,
542         "two",
543         2,
544         "three",
545         3,
546         "four",
547         4,
548         "five",
549         5);
550   }
551 
testInverse()552   public void testInverse() {
553     assertEquals(
554         ImmutableSetMultimap.<Integer, String>of(),
555         ImmutableSetMultimap.<String, Integer>of().inverse());
556     assertEquals(ImmutableSetMultimap.of(1, "one"), ImmutableSetMultimap.of("one", 1).inverse());
557     assertEquals(
558         ImmutableSetMultimap.of(1, "one", 2, "two"),
559         ImmutableSetMultimap.of("one", 1, "two", 2).inverse());
560     assertEquals(
561         ImmutableSetMultimap.of('o', "of", 'f', "of", 't', "to", 'o', "to"),
562         ImmutableSetMultimap.of("of", 'o', "of", 'f', "to", 't', "to", 'o').inverse());
563   }
564 
testInverseMinimizesWork()565   public void testInverseMinimizesWork() {
566     ImmutableSetMultimap<String, Character> multimap =
567         ImmutableSetMultimap.of("of", 'o', "of", 'f', "to", 't', "to", 'o');
568     assertSame(multimap.inverse(), multimap.inverse());
569     assertSame(multimap, multimap.inverse().inverse());
570   }
571 
assertMultimapEquals( Multimap<K, V> multimap, Object... alternatingKeysAndValues)572   private static <K, V> void assertMultimapEquals(
573       Multimap<K, V> multimap, Object... alternatingKeysAndValues) {
574     assertEquals(multimap.size(), alternatingKeysAndValues.length / 2);
575     int i = 0;
576     for (Entry<K, V> entry : multimap.entries()) {
577       assertEquals(alternatingKeysAndValues[i++], entry.getKey());
578       assertEquals(alternatingKeysAndValues[i++], entry.getValue());
579     }
580   }
581 
582   @GwtIncompatible // SerializableTester
testSerialization()583   public void testSerialization() {
584     Multimap<String, Integer> multimap = createMultimap();
585     SerializableTester.reserializeAndAssert(multimap);
586     assertEquals(multimap.size(), SerializableTester.reserialize(multimap).size());
587     SerializableTester.reserializeAndAssert(multimap.get("foo"));
588     LenientSerializableTester.reserializeAndAssertLenient(multimap.keySet());
589     LenientSerializableTester.reserializeAndAssertLenient(multimap.keys());
590     SerializableTester.reserializeAndAssert(multimap.asMap());
591     Collection<Integer> valuesCopy = SerializableTester.reserialize(multimap.values());
592     assertEquals(HashMultiset.create(multimap.values()), HashMultiset.create(valuesCopy));
593   }
594 
595   @GwtIncompatible // SerializableTester
testEmptySerialization()596   public void testEmptySerialization() {
597     Multimap<String, Integer> multimap = ImmutableSetMultimap.of();
598     assertSame(multimap, SerializableTester.reserialize(multimap));
599   }
600 
601   @GwtIncompatible // SerializableTester
testSortedSerialization()602   public void testSortedSerialization() {
603     Multimap<String, Integer> multimap =
604         new ImmutableSetMultimap.Builder<String, Integer>()
605             .orderKeysBy(Ordering.natural().reverse())
606             .orderValuesBy(Ordering.usingToString())
607             .put("a", 2)
608             .put("a", 10)
609             .put("b", 1)
610             .build();
611     multimap = SerializableTester.reserialize(multimap);
612     assertThat(multimap.keySet()).containsExactly("b", "a").inOrder();
613     assertThat(multimap.get("a")).containsExactly(10, 2).inOrder();
614     assertEquals(
615         Ordering.usingToString(), ((ImmutableSortedSet<Integer>) multimap.get("a")).comparator());
616     assertEquals(
617         Ordering.usingToString(), ((ImmutableSortedSet<Integer>) multimap.get("z")).comparator());
618   }
619 
createMultimap()620   private ImmutableSetMultimap<String, Integer> createMultimap() {
621     return ImmutableSetMultimap.<String, Integer>builder()
622         .put("foo", 1)
623         .put("bar", 2)
624         .put("foo", 3)
625         .build();
626   }
627 }
628