1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package com.google.common.collect;
18
19 import static com.google.common.truth.Truth.assertThat;
20
21 import com.google.common.annotations.GwtCompatible;
22 import com.google.common.annotations.GwtIncompatible;
23 import com.google.common.base.Joiner;
24 import com.google.common.collect.ImmutableBiMap.Builder;
25 import com.google.common.collect.testing.MapInterfaceTest;
26 import com.google.common.collect.testing.features.CollectionFeature;
27 import com.google.common.collect.testing.features.CollectionSize;
28 import com.google.common.collect.testing.features.MapFeature;
29 import com.google.common.collect.testing.google.BiMapGenerators.ImmutableBiMapCopyOfGenerator;
30 import com.google.common.collect.testing.google.BiMapGenerators.ImmutableBiMapGenerator;
31 import com.google.common.collect.testing.google.BiMapInverseTester;
32 import com.google.common.collect.testing.google.BiMapTestSuiteBuilder;
33 import com.google.common.testing.SerializableTester;
34
35 import junit.framework.Test;
36 import junit.framework.TestCase;
37 import junit.framework.TestSuite;
38
39 import java.util.Collections;
40 import java.util.LinkedHashMap;
41 import java.util.Map;
42 import java.util.Map.Entry;
43 import java.util.Set;
44
45
46
47
48
49
50 @GwtCompatible(emulated = true)
51 public class ImmutableBiMapTest extends TestCase {
52
53
54
55 @GwtIncompatible("suite")
56 public static Test suite() {
57 TestSuite suite = new TestSuite();
58
59 suite.addTestSuite(MapTests.class);
60 suite.addTestSuite(InverseMapTests.class);
61 suite.addTestSuite(CreationTests.class);
62 suite.addTestSuite(BiMapSpecificTests.class);
63
64 suite.addTest(BiMapTestSuiteBuilder.using(new ImmutableBiMapGenerator())
65 .named("ImmutableBiMap")
66 .withFeatures(CollectionSize.ANY,
67 CollectionFeature.SERIALIZABLE,
68 CollectionFeature.KNOWN_ORDER,
69 MapFeature.REJECTS_DUPLICATES_AT_CREATION,
70 MapFeature.ALLOWS_ANY_NULL_QUERIES)
71 .suppressing(BiMapInverseTester.getInverseSameAfterSerializingMethods())
72 .createTestSuite());
73 suite.addTest(BiMapTestSuiteBuilder.using(new ImmutableBiMapCopyOfGenerator())
74 .named("ImmutableBiMap.copyOf")
75 .withFeatures(CollectionSize.ANY,
76 CollectionFeature.SERIALIZABLE,
77 CollectionFeature.KNOWN_ORDER,
78 MapFeature.ALLOWS_ANY_NULL_QUERIES)
79 .suppressing(BiMapInverseTester.getInverseSameAfterSerializingMethods())
80 .createTestSuite());
81
82 return suite;
83 }
84
85 public static abstract class AbstractMapTests<K, V>
86 extends MapInterfaceTest<K, V> {
87 public AbstractMapTests() {
88 super(false, false, false, false, false);
89 }
90
91 @Override protected Map<K, V> makeEmptyMap() {
92 throw new UnsupportedOperationException();
93 }
94
95 private static final Joiner joiner = Joiner.on(", ");
96
97 @Override protected void assertMoreInvariants(Map<K, V> map) {
98
99 BiMap<K, V> bimap = (BiMap<K, V>) map;
100
101 for (Entry<K, V> entry : map.entrySet()) {
102 assertEquals(entry.getKey() + "=" + entry.getValue(),
103 entry.toString());
104 assertEquals(entry.getKey(), bimap.inverse().get(entry.getValue()));
105 }
106
107 assertEquals("{" + joiner.join(map.entrySet()) + "}",
108 map.toString());
109 assertEquals("[" + joiner.join(map.entrySet()) + "]",
110 map.entrySet().toString());
111 assertEquals("[" + joiner.join(map.keySet()) + "]",
112 map.keySet().toString());
113 assertEquals("[" + joiner.join(map.values()) + "]",
114 map.values().toString());
115
116 assertEquals(Sets.newHashSet(map.entrySet()), map.entrySet());
117 assertEquals(Sets.newHashSet(map.keySet()), map.keySet());
118 }
119 }
120
121 public static class MapTests extends AbstractMapTests<String, Integer> {
122 @Override protected Map<String, Integer> makeEmptyMap() {
123 return ImmutableBiMap.of();
124 }
125
126 @Override protected Map<String, Integer> makePopulatedMap() {
127 return ImmutableBiMap.of("one", 1, "two", 2, "three", 3);
128 }
129
130 @Override protected String getKeyNotInPopulatedMap() {
131 return "minus one";
132 }
133
134 @Override protected Integer getValueNotInPopulatedMap() {
135 return -1;
136 }
137 }
138
139 public static class InverseMapTests
140 extends AbstractMapTests<String, Integer> {
141 @Override protected Map<String, Integer> makeEmptyMap() {
142 return ImmutableBiMap.of();
143 }
144
145 @Override protected Map<String, Integer> makePopulatedMap() {
146 return ImmutableBiMap.of(1, "one", 2, "two", 3, "three").inverse();
147 }
148
149 @Override protected String getKeyNotInPopulatedMap() {
150 return "minus one";
151 }
152
153 @Override protected Integer getValueNotInPopulatedMap() {
154 return -1;
155 }
156 }
157
158 public static class CreationTests extends TestCase {
159 public void testEmptyBuilder() {
160 ImmutableBiMap<String, Integer> map
161 = new Builder<String, Integer>().build();
162 assertEquals(Collections.<String, Integer>emptyMap(), map);
163 assertEquals(Collections.<Integer, String>emptyMap(), map.inverse());
164 assertSame(ImmutableBiMap.of(), map);
165 }
166
167 public void testSingletonBuilder() {
168 ImmutableBiMap<String, Integer> map = new Builder<String, Integer>()
169 .put("one", 1)
170 .build();
171 assertMapEquals(map, "one", 1);
172 assertMapEquals(map.inverse(), 1, "one");
173 }
174
175 public void testBuilder() {
176 ImmutableBiMap<String, Integer> map
177 = ImmutableBiMap.<String, Integer>builder()
178 .put("one", 1)
179 .put("two", 2)
180 .put("three", 3)
181 .put("four", 4)
182 .put("five", 5)
183 .build();
184 assertMapEquals(map,
185 "one", 1, "two", 2, "three", 3, "four", 4, "five", 5);
186 assertMapEquals(map.inverse(),
187 1, "one", 2, "two", 3, "three", 4, "four", 5, "five");
188 }
189
190 public void testBuilderPutAllWithEmptyMap() {
191 ImmutableBiMap<String, Integer> map = new Builder<String, Integer>()
192 .putAll(Collections.<String, Integer>emptyMap())
193 .build();
194 assertEquals(Collections.<String, Integer>emptyMap(), map);
195 }
196
197 public void testBuilderPutAll() {
198 Map<String, Integer> toPut = new LinkedHashMap<String, Integer>();
199 toPut.put("one", 1);
200 toPut.put("two", 2);
201 toPut.put("three", 3);
202 Map<String, Integer> moreToPut = new LinkedHashMap<String, Integer>();
203 moreToPut.put("four", 4);
204 moreToPut.put("five", 5);
205
206 ImmutableBiMap<String, Integer> map = new Builder<String, Integer>()
207 .putAll(toPut)
208 .putAll(moreToPut)
209 .build();
210 assertMapEquals(map,
211 "one", 1, "two", 2, "three", 3, "four", 4, "five", 5);
212 assertMapEquals(map.inverse(),
213 1, "one", 2, "two", 3, "three", 4, "four", 5, "five");
214 }
215
216 public void testBuilderReuse() {
217 Builder<String, Integer> builder = new Builder<String, Integer>();
218 ImmutableBiMap<String, Integer> mapOne = builder
219 .put("one", 1)
220 .put("two", 2)
221 .build();
222 ImmutableBiMap<String, Integer> mapTwo = builder
223 .put("three", 3)
224 .put("four", 4)
225 .build();
226
227 assertMapEquals(mapOne, "one", 1, "two", 2);
228 assertMapEquals(mapOne.inverse(), 1, "one", 2, "two");
229 assertMapEquals(mapTwo, "one", 1, "two", 2, "three", 3, "four", 4);
230 assertMapEquals(mapTwo.inverse(),
231 1, "one", 2, "two", 3, "three", 4, "four");
232 }
233
234 public void testBuilderPutNullKey() {
235 Builder<String, Integer> builder = new Builder<String, Integer>();
236 try {
237 builder.put(null, 1);
238 fail();
239 } catch (NullPointerException expected) {
240 }
241 }
242
243 public void testBuilderPutNullValue() {
244 Builder<String, Integer> builder = new Builder<String, Integer>();
245 try {
246 builder.put("one", null);
247 fail();
248 } catch (NullPointerException expected) {
249 }
250 }
251
252 public void testBuilderPutNullKeyViaPutAll() {
253 Builder<String, Integer> builder = new Builder<String, Integer>();
254 try {
255 builder.putAll(Collections.<String, Integer>singletonMap(null, 1));
256 fail();
257 } catch (NullPointerException expected) {
258 }
259 }
260
261 public void testBuilderPutNullValueViaPutAll() {
262 Builder<String, Integer> builder = new Builder<String, Integer>();
263 try {
264 builder.putAll(Collections.<String, Integer>singletonMap("one", null));
265 fail();
266 } catch (NullPointerException expected) {
267 }
268 }
269
270 public void testPuttingTheSameKeyTwiceThrowsOnBuild() {
271 Builder<String, Integer> builder = new Builder<String, Integer>()
272 .put("one", 1)
273 .put("one", 1);
274
275 try {
276 builder.build();
277 fail();
278 } catch (IllegalArgumentException expected) {
279 assertTrue(expected.getMessage().contains("one"));
280 }
281 }
282
283 public void testOf() {
284 assertMapEquals(
285 ImmutableBiMap.of("one", 1),
286 "one", 1);
287 assertMapEquals(
288 ImmutableBiMap.of("one", 1).inverse(),
289 1, "one");
290 assertMapEquals(
291 ImmutableBiMap.of("one", 1, "two", 2),
292 "one", 1, "two", 2);
293 assertMapEquals(
294 ImmutableBiMap.of("one", 1, "two", 2).inverse(),
295 1, "one", 2, "two");
296 assertMapEquals(
297 ImmutableBiMap.of("one", 1, "two", 2, "three", 3),
298 "one", 1, "two", 2, "three", 3);
299 assertMapEquals(
300 ImmutableBiMap.of("one", 1, "two", 2, "three", 3).inverse(),
301 1, "one", 2, "two", 3, "three");
302 assertMapEquals(
303 ImmutableBiMap.of("one", 1, "two", 2, "three", 3, "four", 4),
304 "one", 1, "two", 2, "three", 3, "four", 4);
305 assertMapEquals(
306 ImmutableBiMap.of(
307 "one", 1, "two", 2, "three", 3, "four", 4).inverse(),
308 1, "one", 2, "two", 3, "three", 4, "four");
309 assertMapEquals(
310 ImmutableBiMap.of(
311 "one", 1, "two", 2, "three", 3, "four", 4, "five", 5),
312 "one", 1, "two", 2, "three", 3, "four", 4, "five", 5);
313 assertMapEquals(
314 ImmutableBiMap.of(
315 "one", 1, "two", 2, "three", 3, "four", 4, "five", 5).inverse(),
316 1, "one", 2, "two", 3, "three", 4, "four", 5, "five");
317 }
318
319 public void testOfNullKey() {
320 try {
321 ImmutableBiMap.of(null, 1);
322 fail();
323 } catch (NullPointerException expected) {
324 }
325
326 try {
327 ImmutableBiMap.of("one", 1, null, 2);
328 fail();
329 } catch (NullPointerException expected) {
330 }
331 }
332
333 public void testOfNullValue() {
334 try {
335 ImmutableBiMap.of("one", null);
336 fail();
337 } catch (NullPointerException expected) {
338 }
339
340 try {
341 ImmutableBiMap.of("one", 1, "two", null);
342 fail();
343 } catch (NullPointerException expected) {
344 }
345 }
346
347 public void testOfWithDuplicateKey() {
348 try {
349 ImmutableBiMap.of("one", 1, "one", 1);
350 fail();
351 } catch (IllegalArgumentException expected) {
352 assertTrue(expected.getMessage().contains("one"));
353 }
354 }
355
356 public void testCopyOfEmptyMap() {
357 ImmutableBiMap<String, Integer> copy
358 = ImmutableBiMap.copyOf(Collections.<String, Integer>emptyMap());
359 assertEquals(Collections.<String, Integer>emptyMap(), copy);
360 assertSame(copy, ImmutableBiMap.copyOf(copy));
361 assertSame(ImmutableBiMap.of(), copy);
362 }
363
364 public void testCopyOfSingletonMap() {
365 ImmutableBiMap<String, Integer> copy
366 = ImmutableBiMap.copyOf(Collections.singletonMap("one", 1));
367 assertMapEquals(copy, "one", 1);
368 assertSame(copy, ImmutableBiMap.copyOf(copy));
369 }
370
371 public void testCopyOf() {
372 Map<String, Integer> original = new LinkedHashMap<String, Integer>();
373 original.put("one", 1);
374 original.put("two", 2);
375 original.put("three", 3);
376
377 ImmutableBiMap<String, Integer> copy = ImmutableBiMap.copyOf(original);
378 assertMapEquals(copy, "one", 1, "two", 2, "three", 3);
379 assertSame(copy, ImmutableBiMap.copyOf(copy));
380 }
381
382 public void testEmpty() {
383 ImmutableBiMap<String, Integer> bimap = ImmutableBiMap.of();
384 assertEquals(Collections.<String, Integer>emptyMap(), bimap);
385 assertEquals(Collections.<String, Integer>emptyMap(), bimap.inverse());
386 }
387
388 public void testFromHashMap() {
389 Map<String, Integer> hashMap = Maps.newLinkedHashMap();
390 hashMap.put("one", 1);
391 hashMap.put("two", 2);
392 ImmutableBiMap<String, Integer> bimap = ImmutableBiMap.copyOf(
393 ImmutableMap.of("one", 1, "two", 2));
394 assertMapEquals(bimap, "one", 1, "two", 2);
395 assertMapEquals(bimap.inverse(), 1, "one", 2, "two");
396 }
397
398 public void testFromImmutableMap() {
399 ImmutableBiMap<String, Integer> bimap = ImmutableBiMap.copyOf(
400 new ImmutableMap.Builder<String, Integer>()
401 .put("one", 1)
402 .put("two", 2)
403 .put("three", 3)
404 .put("four", 4)
405 .put("five", 5)
406 .build());
407 assertMapEquals(bimap,
408 "one", 1, "two", 2, "three", 3, "four", 4, "five", 5);
409 assertMapEquals(bimap.inverse(),
410 1, "one", 2, "two", 3, "three", 4, "four", 5, "five");
411 }
412
413 public void testDuplicateValues() {
414 ImmutableMap<String, Integer> map
415 = new ImmutableMap.Builder<String, Integer>()
416 .put("one", 1)
417 .put("two", 2)
418 .put("uno", 1)
419 .put("dos", 2)
420 .build();
421
422 try {
423 ImmutableBiMap.copyOf(map);
424 fail();
425 } catch (IllegalArgumentException expected) {
426 assertTrue(expected.getMessage().contains("1"));
427 }
428 }
429 }
430
431 public static class BiMapSpecificTests extends TestCase {
432
433 @SuppressWarnings("deprecation")
434 public void testForcePut() {
435 ImmutableBiMap<String, Integer> bimap = ImmutableBiMap.copyOf(
436 ImmutableMap.of("one", 1, "two", 2));
437 try {
438 bimap.forcePut("three", 3);
439 fail();
440 } catch (UnsupportedOperationException expected) {}
441 }
442
443 public void testKeySet() {
444 ImmutableBiMap<String, Integer> bimap = ImmutableBiMap.copyOf(
445 ImmutableMap.of("one", 1, "two", 2, "three", 3, "four", 4));
446 Set<String> keys = bimap.keySet();
447 assertEquals(Sets.newHashSet("one", "two", "three", "four"), keys);
448 assertThat(keys).has().exactly("one", "two", "three", "four").inOrder();
449 }
450
451 public void testValues() {
452 ImmutableBiMap<String, Integer> bimap = ImmutableBiMap.copyOf(
453 ImmutableMap.of("one", 1, "two", 2, "three", 3, "four", 4));
454 Set<Integer> values = bimap.values();
455 assertEquals(Sets.newHashSet(1, 2, 3, 4), values);
456 assertThat(values).has().exactly(1, 2, 3, 4).inOrder();
457 }
458
459 public void testDoubleInverse() {
460 ImmutableBiMap<String, Integer> bimap = ImmutableBiMap.copyOf(
461 ImmutableMap.of("one", 1, "two", 2));
462 assertSame(bimap, bimap.inverse().inverse());
463 }
464
465 @GwtIncompatible("SerializableTester")
466 public void testEmptySerialization() {
467 ImmutableBiMap<String, Integer> bimap = ImmutableBiMap.of();
468 assertSame(bimap, SerializableTester.reserializeAndAssert(bimap));
469 }
470
471 @GwtIncompatible("SerializableTester")
472 public void testSerialization() {
473 ImmutableBiMap<String, Integer> bimap = ImmutableBiMap.copyOf(
474 ImmutableMap.of("one", 1, "two", 2));
475 ImmutableBiMap<String, Integer> copy =
476 SerializableTester.reserializeAndAssert(bimap);
477 assertEquals(Integer.valueOf(1), copy.get("one"));
478 assertEquals("one", copy.inverse().get(1));
479 assertSame(copy, copy.inverse().inverse());
480 }
481
482 @GwtIncompatible("SerializableTester")
483 public void testInverseSerialization() {
484 ImmutableBiMap<String, Integer> bimap = ImmutableBiMap.copyOf(
485 ImmutableMap.of(1, "one", 2, "two")).inverse();
486 ImmutableBiMap<String, Integer> copy =
487 SerializableTester.reserializeAndAssert(bimap);
488 assertEquals(Integer.valueOf(1), copy.get("one"));
489 assertEquals("one", copy.inverse().get(1));
490 assertSame(copy, copy.inverse().inverse());
491 }
492 }
493
494 private static <K, V> void assertMapEquals(Map<K, V> map,
495 Object... alternatingKeysAndValues) {
496 int i = 0;
497 for (Entry<K, V> entry : map.entrySet()) {
498 assertEquals(alternatingKeysAndValues[i++], entry.getKey());
499 assertEquals(alternatingKeysAndValues[i++], entry.getValue());
500 }
501 }
502 }