• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2007 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 java.util.Arrays.asList;
20 
21 import com.google.common.annotations.GwtCompatible;
22 import com.google.common.annotations.GwtIncompatible;
23 import com.google.common.testing.SerializableTester;
24 
25 import junit.framework.TestCase;
26 
27 import java.io.Serializable;
28 import java.util.Collections;
29 import java.util.Iterator;
30 import java.util.Map;
31 import java.util.Map.Entry;
32 import java.util.Set;
33 
34 /**
35  * Common tests for any {@code BiMap}.
36  *
37  * @author Kevin Bourrillion
38  */
39 @GwtCompatible(emulated = true)
40 public abstract class AbstractBiMapTest extends TestCase {
41 
create()42   protected abstract BiMap<Integer, String> create();
43 
44   protected BiMap<Integer, String> bimap;
45   protected Set<Entry<Integer, String>> entrySet;
46 
47   // public for GWT
setUp()48   @Override public void setUp() throws Exception {
49     super.setUp();
50     bimap = create();
51     entrySet = bimap.entrySet();
52   }
53 
testClear()54   public void testClear() {
55     bimap.clear();
56     assertTrue(bimap.isEmpty());
57     putOneTwoThree();
58     bimap.clear();
59     assertTrue(bimap.isEmpty());
60   }
61 
testContainsKey()62   public void testContainsKey() {
63     assertFalse(bimap.containsKey(null));
64     assertFalse(bimap.containsKey(1));
65     assertFalse(bimap.containsKey("one"));
66 
67     bimap.put(1, "one");
68     assertTrue(bimap.containsKey(1));
69 
70     bimap.put(null, null);
71     assertTrue(bimap.containsKey(null));
72   }
73 
testContainsValue()74   public void testContainsValue() {
75     assertFalse(bimap.containsValue(null));
76     assertFalse(bimap.containsValue(1));
77     assertFalse(bimap.containsValue("one"));
78 
79     bimap.put(1, "one");
80     assertTrue(bimap.containsValue("one"));
81 
82     bimap.put(null, null);
83     assertTrue(bimap.containsValue(null));
84   }
85 
testEquals()86   public void testEquals() {
87     BiMap<Integer, String> biMap = create();
88     assertEquals(biMap, biMap);
89     assertEquals(create(), biMap);
90     biMap.put(1, null);
91     assertFalse(create().equals(biMap));
92   }
93 
testGet()94   public void testGet() {
95     assertNull(bimap.get(1));
96     assertNull(bimap.get(null));
97     assertNull(bimap.get("bad"));
98 
99     bimap.put(1, "one");
100     bimap.put(0, null);
101     bimap.put(null, "nothing");
102     assertEquals("one", bimap.get(1));
103     assertNull(bimap.get(0));
104     assertEquals("nothing", bimap.get(null));
105     assertNull(bimap.get("bad"));
106 
107     bimap.forcePut(null, null);
108     assertNull(bimap.get(null));
109     bimap.remove(null);
110     assertNull(bimap.get(null));
111   }
112 
testInverseSimple()113   public void testInverseSimple() {
114     BiMap<String, Integer> inverse = bimap.inverse();
115     bimap.put(1, "one");
116     bimap.put(2, "two");
117     assertEquals(ImmutableMap.of("one", 1, "two", 2), inverse);
118     // see InverseBiMapTest
119 
120     assertSame(bimap, inverse.inverse());
121   }
122 
testInversePut()123   public void testInversePut() {
124     BiMap<String, Integer> inverse = bimap.inverse();
125     bimap.put(1, "one");
126     bimap.inverse().put("two", 2);
127     assertEquals(ImmutableMap.of("one", 1, "two", 2), inverse);
128     assertEquals(ImmutableMap.of(1, "one", 2, "two"), bimap);
129   }
130 
testIsEmpty()131   public void testIsEmpty() {
132     assertTrue(bimap.isEmpty());
133     bimap.put(1, "one");
134     assertFalse(bimap.isEmpty());
135     bimap.remove(1);
136     assertTrue(bimap.isEmpty());
137   }
138 
testPut()139   public void testPut() {
140     bimap.put(1, "one");
141     assertEquals(ImmutableMap.of(1, "one"), bimap);
142 
143     bimap.put(2, "two");
144     assertEquals(ImmutableMap.of(1, "one", 2, "two"), bimap);
145 
146     bimap.put(2, "two");
147     assertEquals(ImmutableMap.of(1, "one", 2, "two"), bimap);
148 
149     bimap.put(1, "ONE");
150     assertEquals(ImmutableMap.of(1, "ONE", 2, "two"), bimap);
151 
152     try {
153       bimap.put(3, "two");
154       fail();
155     } catch (IllegalArgumentException e) {
156     }
157     assertEquals(ImmutableMap.of(1, "ONE", 2, "two"), bimap);
158 
159     bimap.put(-1, null);
160     bimap.put(null, "null");
161     Map<Integer, String> expected = Maps.newHashMap();
162     expected.put(1, "ONE");
163     expected.put(2, "two");
164     expected.put(-1, null);
165     expected.put(null, "null");
166 
167     assertEquals(expected, bimap);
168 
169     bimap.remove(-1);
170     bimap.put(null, null);
171 
172     expected.remove(-1);
173     expected.put(null, null);
174 
175     assertEquals(expected, bimap);
176   }
177 
testPutNull()178   public void testPutNull() {
179     bimap.put(-1, null);
180     assertTrue(bimap.containsValue(null));
181     bimap.put(1, "one");
182     assertTrue(bimap.containsValue(null));
183   }
184 
testPutAll()185   public void testPutAll() {
186     bimap.put(1, "one");
187     Map<Integer, String> newEntries = ImmutableMap.of(2, "two", 3, "three");
188     bimap.putAll(newEntries);
189     assertEquals(ImmutableMap.of(1, "one", 2, "two", 3, "three"), bimap);
190   }
191 
testForcePut()192   public void testForcePut() {
193     assertNull(bimap.forcePut(1, "one"));
194     assertEquals(ImmutableMap.of(1, "one"), bimap);
195     assertEquals("one", bimap.forcePut(1, "one"));
196     assertEquals(ImmutableMap.of(1, "one"), bimap);
197     assertEquals("one", bimap.forcePut(1, "ONE"));
198     assertEquals(ImmutableMap.of(1, "ONE"), bimap);
199     assertNull(bimap.forcePut(-1, "ONE")); // key 1 disappears without a trace
200     assertEquals(ImmutableMap.of(-1, "ONE"), bimap);
201     assertNull(bimap.forcePut(2, "two"));
202     assertEquals(ImmutableMap.of(-1, "ONE", 2, "two"), bimap);
203     assertEquals("two", bimap.forcePut(2, "ONE"));
204     assertEquals(ImmutableMap.of(2, "ONE"), bimap);
205   }
206 
testRemove()207   public void testRemove() {
208     Map<Integer, String> map = Maps.newHashMap();
209     map.put(0, null);
210     map.put(1, "one");
211     map.put(null, "null");
212 
213     bimap.putAll(map);
214     assertNull(bimap.remove(0));
215 
216     map.remove(0);
217     assertEquals(map, bimap);
218 
219     assertEquals("null", bimap.remove(null));
220     assertEquals(Collections.singletonMap(1, "one"), bimap);
221 
222     assertNull(bimap.remove(15));
223 
224     assertEquals("one", bimap.remove(1));
225     assertTrue(bimap.isEmpty());
226   }
227 
testSize()228   public void testSize() {
229     assertEquals(0, bimap.size());
230     bimap.put(1, "one");
231     assertEquals(1, bimap.size());
232     bimap.put(1, "ONE");
233     assertEquals(1, bimap.size());
234     bimap.put(2, "two");
235     assertEquals(2, bimap.size());
236     bimap.forcePut(1, "two");
237     assertEquals(1, bimap.size());
238   }
239 
testToString()240   public void testToString() {
241     bimap.put(1, "one");
242     bimap.put(2, "two");
243 
244     String string = bimap.toString();
245     String expected = string.startsWith("{1")
246         ? "{1=one, 2=two}"
247         : "{2=two, 1=one}";
248     assertEquals(expected, bimap.toString());
249   }
250 
251   // Entry Set
252 
testEntrySetAdd()253   public void testEntrySetAdd() {
254     try {
255       entrySet.add(Maps.immutableEntry(1, "one"));
256       fail();
257     } catch (UnsupportedOperationException expected) {
258     }
259   }
260 
testEntrySetAddAll()261   public void testEntrySetAddAll() {
262     try {
263       entrySet.addAll(Collections.singleton(Maps.immutableEntry(1, "one")));
264       fail();
265     } catch (UnsupportedOperationException expected) {
266     }
267   }
268 
testEntrySetClear()269   public void testEntrySetClear() {
270     entrySet.clear();
271     assertTrue(entrySet.isEmpty());
272     assertTrue(bimap.isEmpty());
273     putOneTwoThree();
274     entrySet.clear();
275     assertTrue(entrySet.isEmpty());
276     assertTrue(bimap.isEmpty());
277   }
278 
testEntrySetContains()279   public void testEntrySetContains() {
280     assertFalse(entrySet.contains(Maps.immutableEntry(1, "one")));
281     bimap.put(1, "one");
282     assertTrue(entrySet.contains(Maps.immutableEntry(1, "one")));
283     assertFalse(entrySet.contains(Maps.immutableEntry(1, "")));
284     assertFalse(entrySet.contains(Maps.immutableEntry(0, "one")));
285     assertFalse(entrySet.contains(Maps.immutableEntry(1, null)));
286     assertFalse(entrySet.contains(Maps.immutableEntry(null, "one")));
287     assertFalse(entrySet.contains(Maps.immutableEntry(null, null)));
288 
289     bimap.put(null, null);
290     assertTrue(entrySet.contains(Maps.immutableEntry(1, "one")));
291     assertTrue(entrySet.contains(Maps.immutableEntry(null, null)));
292     assertFalse(entrySet.contains(Maps.immutableEntry(1, "")));
293     assertFalse(entrySet.contains(Maps.immutableEntry(0, "one")));
294     assertFalse(entrySet.contains(Maps.immutableEntry(1, null)));
295     assertFalse(entrySet.contains(Maps.immutableEntry(null, "one")));
296 
297     bimap.put(null, "null");
298     bimap.put(0, null);
299     assertTrue(entrySet.contains(Maps.immutableEntry(1, "one")));
300     assertTrue(entrySet.contains(Maps.immutableEntry(null, "null")));
301     assertTrue(entrySet.contains(Maps.immutableEntry(0, null)));
302     assertFalse(entrySet.contains(Maps.immutableEntry(1, "")));
303     assertFalse(entrySet.contains(Maps.immutableEntry(0, "one")));
304     assertFalse(entrySet.contains(Maps.immutableEntry(1, null)));
305     assertFalse(entrySet.contains(Maps.immutableEntry(null, "one")));
306     assertFalse(entrySet.contains(Maps.immutableEntry(null, null)));
307   }
308 
testEntrySetIsEmpty()309   public void testEntrySetIsEmpty() {
310     assertTrue(entrySet.isEmpty());
311     bimap.put(1, "one");
312     assertFalse(entrySet.isEmpty());
313     bimap.remove(1);
314     assertTrue(entrySet.isEmpty());
315   }
316 
testEntrySetRemove()317   public void testEntrySetRemove() {
318     putOneTwoThree();
319     assertTrue(bimap.containsKey(1));
320     assertTrue(bimap.containsValue("one"));
321     assertTrue(entrySet.remove(Maps.immutableEntry(1, "one")));
322     assertFalse(bimap.containsKey(1));
323     assertFalse(bimap.containsValue("one"));
324     assertEquals(2, bimap.size());
325     assertEquals(2, bimap.inverse().size());
326     assertFalse(entrySet.remove(Maps.immutableEntry(2, "three")));
327     assertFalse(entrySet.remove(3));
328     assertEquals(2, bimap.size());
329     assertEquals(2, bimap.inverse().size());
330   }
331 
testEntrySetRemoveAll()332   public void testEntrySetRemoveAll() {
333     putOneTwoThree();
334     assertTrue(bimap.containsKey(1));
335     assertTrue(bimap.containsValue("one"));
336     assertTrue(entrySet.removeAll(
337         Collections.singleton(Maps.immutableEntry(1, "one"))));
338     assertFalse(bimap.containsKey(1));
339     assertFalse(bimap.containsValue("one"));
340     assertEquals(2, bimap.size());
341     assertEquals(2, bimap.inverse().size());
342   }
343 
testEntrySetValue()344   public void testEntrySetValue() {
345     bimap.put(1, "one");
346     Entry<Integer, String> entry = bimap.entrySet().iterator().next();
347     bimap.put(2, "two");
348     assertEquals("one", entry.getValue());
349     bimap.put(1, "one");
350     assertEquals("one", entry.getValue());
351     assertEquals("one", bimap.get(1));
352     assertEquals(Integer.valueOf(1), bimap.inverse().get("one"));
353     bimap.put(1, "uno");
354     assertEquals("uno", entry.getValue());
355     assertEquals("uno", bimap.get(1));
356     assertEquals(Integer.valueOf(1), bimap.inverse().get("uno"));
357     assertEquals(2, bimap.size());
358     assertEquals(2, bimap.inverse().size());
359     try {
360       entry.setValue("two");
361       fail();
362     } catch (IllegalArgumentException expected) {}
363     assertEquals("uno", entry.getValue());
364     assertEquals("uno", bimap.get(1));
365     assertEquals(Integer.valueOf(1), bimap.inverse().get("uno"));
366     assertEquals(2, bimap.size());
367     assertEquals(2, bimap.inverse().size());
368   }
369 
testEntrySetValueRemovedEntry()370   public void testEntrySetValueRemovedEntry() {
371     bimap.put(1, "a");
372     Entry<Integer, String> entry = bimap.entrySet().iterator().next();
373     bimap.clear();
374     try {
375       entry.setValue("b");
376       fail();
377     } catch (IllegalStateException expected) {}
378     assertEquals(0, bimap.size());
379     assertEquals(0, bimap.inverse().size());
380   }
381 
testEntrySetValueRemovedEntryNullOldValue()382   public void testEntrySetValueRemovedEntryNullOldValue() {
383     bimap.put(1, null);
384     Entry<Integer, String> entry = bimap.entrySet().iterator().next();
385     bimap.clear();
386     try {
387       entry.setValue("b");
388       fail();
389     } catch (IllegalStateException expected) {}
390     assertEquals(0, bimap.size());
391     assertEquals(0, bimap.inverse().size());
392   }
393 
testEntrySetValueRemovedEntryAddedEqualEntry()394   public void testEntrySetValueRemovedEntryAddedEqualEntry() {
395     bimap.put(1, "a");
396     Entry<Integer, String> entry = bimap.entrySet().iterator().next();
397     bimap.clear();
398     bimap.put(1, "a");
399     try {
400       entry.setValue("b");
401       fail();
402     } catch (IllegalStateException expected) {}
403     assertEquals(1, bimap.size());
404     assertEquals("a", bimap.get(1));
405     assertEquals(1, bimap.inverse().size());
406     assertEquals((Integer) 1, bimap.inverse().get("a"));
407   }
408 
testKeySetIteratorRemove()409   public void testKeySetIteratorRemove() {
410     putOneTwoThree();
411     Iterator<Integer> iterator = bimap.keySet().iterator();
412     iterator.next();
413     iterator.remove();
414     assertEquals(2, bimap.size());
415     assertEquals(2, bimap.inverse().size());
416   }
417 
testKeySetRemoveAll()418   public void testKeySetRemoveAll() {
419     putOneTwoThree();
420     Set<Integer> keySet = bimap.keySet();
421     assertTrue(keySet.removeAll(asList(1, 3)));
422     assertEquals(1, bimap.size());
423     assertTrue(keySet.contains(2));
424   }
425 
testKeySetRetainAll()426   public void testKeySetRetainAll() {
427     putOneTwoThree();
428     Set<Integer> keySet = bimap.keySet();
429     assertTrue(keySet.retainAll(Collections.singleton(2)));
430     assertEquals(1, bimap.size());
431     assertTrue(keySet.contains(2));
432   }
433 
testEntriesIteratorRemove()434   public void testEntriesIteratorRemove() {
435     putOneTwoThree();
436     Iterator<Entry<Integer, String>> iterator = bimap.entrySet().iterator();
437     iterator.next();
438     iterator.remove();
439     assertEquals(2, bimap.size());
440     assertEquals(2, bimap.inverse().size());
441   }
442 
testEntriesRetainAll()443   public void testEntriesRetainAll() {
444     putOneTwoThree();
445     Set<Map.Entry<Integer, String>> entries = bimap.entrySet();
446     Map.Entry<Integer, String> entry = Maps.immutableEntry(2, "two");
447     assertTrue(entries.retainAll(Collections.singleton(entry)));
448     assertEquals(1, bimap.size());
449     assertTrue(bimap.containsKey(2));
450   }
451 
testValuesIteratorRemove()452   public void testValuesIteratorRemove() {
453     putOneTwoThree();
454     Iterator<String> iterator = bimap.values().iterator();
455     iterator.next();
456     iterator.remove();
457     assertEquals(2, bimap.size());
458     assertEquals(2, bimap.inverse().size());
459   }
460 
testValuesToArray()461   public void testValuesToArray() {
462     bimap.put(1, "one");
463     String[] array = new String[3];
464     array[1] = "garbage";
465     assertSame(array, bimap.values().toArray(array));
466     assertEquals("one", array[0]);
467     assertNull(array[1]);
468   }
469 
testValuesToString()470   public void testValuesToString() {
471     bimap.put(1, "one");
472     assertEquals("[one]", bimap.values().toString());
473   }
474 
475   @GwtIncompatible("SerializableTester")
testSerialization()476   public void testSerialization() {
477     bimap.put(1, "one");
478     bimap.put(2, "two");
479     bimap.put(3, "three");
480     bimap.put(null, null);
481 
482     BiMap<Integer, String> copy =
483         SerializableTester.reserializeAndAssert(bimap);
484     assertEquals(bimap.inverse(), copy.inverse());
485   }
486 
putOneTwoThree()487   void putOneTwoThree() {
488     bimap.put(1, "one");
489     bimap.put(2, "two");
490     bimap.put(3, "three");
491   }
492 
493   @GwtIncompatible("used only by @GwtIncompatible code")
494   private static class BiMapPair implements Serializable {
495     final BiMap<Integer, String> forward;
496     final BiMap<String, Integer> backward;
497 
BiMapPair(BiMap<Integer, String> original)498     BiMapPair(BiMap<Integer, String> original) {
499       this.forward = original;
500       this.backward = original.inverse();
501     }
502 
503     private static final long serialVersionUID = 0;
504   }
505 
506   @GwtIncompatible("SerializableTester")
testSerializationWithInverseEqual()507   public void testSerializationWithInverseEqual() {
508     bimap.put(1, "one");
509     bimap.put(2, "two");
510     bimap.put(3, "three");
511     bimap.put(null, null);
512 
513     BiMapPair pair = new BiMapPair(bimap);
514     BiMapPair copy = SerializableTester.reserialize(pair);
515     assertEquals(pair.forward, copy.forward);
516     assertEquals(pair.backward, copy.backward);
517 
518     copy.forward.put(4, "four");
519     copy.backward.put("five", 5);
520     assertEquals(copy.backward, copy.forward.inverse());
521     assertEquals(copy.forward, copy.backward.inverse());
522 
523     assertTrue(copy.forward.containsKey(4));
524     assertTrue(copy.forward.containsKey(5));
525     assertTrue(copy.backward.containsValue(4));
526     assertTrue(copy.backward.containsValue(5));
527     assertTrue(copy.forward.containsValue("four"));
528     assertTrue(copy.forward.containsValue("five"));
529     assertTrue(copy.backward.containsKey("four"));
530     assertTrue(copy.backward.containsKey("five"));
531   }
532 
533   /**
534    * The sameness checks ensure that a bimap and its inverse remain consistent,
535    * even after the deserialized instances are updated. Also, the relationship
536    * {@code a == b.inverse()} should continue to hold after both bimaps are
537    * serialized and deserialized together.
538    */
539   @GwtIncompatible("SerializableTester")
testSerializationWithInverseSame()540   public void testSerializationWithInverseSame() {
541     bimap.put(1, "one");
542     bimap.put(2, "two");
543     bimap.put(3, "three");
544     bimap.put(null, null);
545 
546     BiMapPair pair = new BiMapPair(bimap);
547     BiMapPair copy = SerializableTester.reserialize(pair);
548     assertSame(copy.backward, copy.forward.inverse());
549     assertSame(copy.forward, copy.backward.inverse());
550   }
551 }
552