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