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