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 com.google.common.collect.Synchronized.SynchronizedBiMap; 20 import com.google.common.collect.Synchronized.SynchronizedSet; 21 22 import junit.framework.TestSuite; 23 24 import java.util.Set; 25 26 /** 27 * Tests for {@code Synchronized#biMap}. 28 * 29 * @author Mike Bostock 30 */ 31 public class SynchronizedBiMapTest extends SynchronizedMapTest { 32 suite()33 public static TestSuite suite() { 34 TestSuite suite = new TestSuite(SynchronizedBiMapTest.class); 35 suite.addTestSuite(AbstractBiMapTests.class); 36 return suite; 37 } 38 create()39 @Override protected <K, V> BiMap<K, V> create() { 40 TestBiMap<K, V> inner = 41 new TestBiMap<K, V>(HashBiMap.<K, V>create(), mutex); 42 BiMap<K, V> outer = Synchronized.biMap(inner, mutex); 43 return outer; 44 } 45 46 static class TestBiMap<K, V> extends TestMap<K, V> implements BiMap<K, V> { 47 private final BiMap<K, V> delegate; 48 TestBiMap(BiMap<K, V> delegate, Object mutex)49 public TestBiMap(BiMap<K, V> delegate, Object mutex) { 50 super(delegate, mutex); 51 this.delegate = delegate; 52 } 53 54 @Override forcePut(K key, V value)55 public V forcePut(K key, V value) { 56 assertTrue(Thread.holdsLock(mutex)); 57 return delegate.forcePut(key, value); 58 } 59 60 @Override inverse()61 public BiMap<V, K> inverse() { 62 assertTrue(Thread.holdsLock(mutex)); 63 return delegate.inverse(); 64 } 65 values()66 @Override public Set<V> values() { 67 assertTrue(Thread.holdsLock(mutex)); 68 return delegate.values(); 69 } 70 71 private static final long serialVersionUID = 0; 72 } 73 testForcePut()74 public void testForcePut() { 75 create().forcePut(null, null); 76 } 77 testInverse()78 public void testInverse() { 79 BiMap<String, Integer> bimap = create(); 80 BiMap<Integer, String> inverse = bimap.inverse(); 81 assertSame(bimap, inverse.inverse()); 82 assertTrue(inverse instanceof SynchronizedBiMap); 83 assertSame(mutex, ((SynchronizedBiMap<?, ?>) inverse).mutex); 84 } 85 testValues()86 @Override public void testValues() { 87 BiMap<String, Integer> map = create(); 88 Set<Integer> values = map.values(); 89 assertTrue(values instanceof SynchronizedSet); 90 assertSame(mutex, ((SynchronizedSet<?>) values).mutex); 91 } 92 93 public static class AbstractBiMapTests extends AbstractBiMapTest { 94 public final Object mutex = new Integer(1); // something Serializable 95 create()96 @Override protected BiMap<Integer, String> create() { 97 TestBiMap<Integer, String> inner = new TestBiMap<Integer, String>( 98 HashBiMap.<Integer, String>create(), mutex); 99 BiMap<Integer, String> outer = Synchronized.biMap(inner, mutex); 100 return outer; 101 } 102 103 /** 104 * If you serialize a synchronized bimap and its inverse together, the 105 * reserialized bimaps will have backing maps that stay in sync, as shown 106 * by the {@code testSerializationWithInverseEqual()} test. However, the 107 * inverse of one won't be the same as the other. 108 * 109 * To make them the same, the inverse synchronized bimap would need a custom 110 * serialized form, similar to what {@code AbstractBiMap.Inverse} does. 111 */ testSerializationWithInverseSame()112 @Override public void testSerializationWithInverseSame() {} 113 } 114 } 115