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