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 com.google.common.base.Preconditions.checkArgument; 20 21 import com.google.common.collect.Synchronized.SynchronizedBiMap; 22 import com.google.common.collect.Synchronized.SynchronizedSet; 23 import com.google.common.collect.testing.features.CollectionFeature; 24 import com.google.common.collect.testing.features.CollectionSize; 25 import com.google.common.collect.testing.features.MapFeature; 26 import com.google.common.collect.testing.google.BiMapInverseTester; 27 import com.google.common.collect.testing.google.BiMapTestSuiteBuilder; 28 import com.google.common.collect.testing.google.TestStringBiMapGenerator; 29 30 import junit.framework.TestSuite; 31 32 import java.util.Map.Entry; 33 import java.util.Set; 34 35 /** 36 * Tests for {@code Synchronized#biMap}. 37 * 38 * @author Mike Bostock 39 */ 40 public class SynchronizedBiMapTest extends SynchronizedMapTest { 41 42 public static TestSuite suite() { 43 TestSuite suite = new TestSuite(SynchronizedBiMapTest.class); 44 suite.addTest(BiMapTestSuiteBuilder.using(new SynchTestingBiMapGenerator()) 45 .named("Synchronized.biMap[TestBiMap]") 46 .withFeatures(CollectionSize.ANY, 47 CollectionFeature.SUPPORTS_ITERATOR_REMOVE, 48 MapFeature.ALLOWS_NULL_KEYS, 49 MapFeature.ALLOWS_NULL_VALUES, 50 MapFeature.ALLOWS_ANY_NULL_QUERIES, 51 MapFeature.GENERAL_PURPOSE, 52 MapFeature.REJECTS_DUPLICATES_AT_CREATION) 53 .createTestSuite()); 54 suite.addTest(BiMapTestSuiteBuilder.using(new SynchronizedHashBiMapGenerator()) 55 .named("synchronizedBiMap[HashBiMap]") 56 .withFeatures(CollectionSize.ANY, 57 CollectionFeature.SUPPORTS_ITERATOR_REMOVE, 58 MapFeature.ALLOWS_NULL_KEYS, 59 MapFeature.ALLOWS_NULL_VALUES, 60 MapFeature.ALLOWS_ANY_NULL_QUERIES, 61 MapFeature.GENERAL_PURPOSE, 62 MapFeature.REJECTS_DUPLICATES_AT_CREATION, 63 CollectionFeature.SERIALIZABLE) 64 .suppressing(BiMapInverseTester.getInverseSameAfterSerializingMethods()) 65 .createTestSuite()); 66 return suite; 67 } 68 69 @Override protected <K, V> BiMap<K, V> create() { 70 TestBiMap<K, V> inner = 71 new TestBiMap<K, V>(HashBiMap.<K, V>create(), mutex); 72 BiMap<K, V> outer = Synchronized.biMap(inner, mutex); 73 return outer; 74 } 75 76 public static final class SynchronizedHashBiMapGenerator extends TestStringBiMapGenerator { 77 @Override 78 protected BiMap<String, String> create(Entry<String, String>[] entries) { 79 Object mutex = new Object(); 80 BiMap<String, String> result = HashBiMap.create(); 81 for (Entry<String, String> entry : entries) { 82 checkArgument(!result.containsKey(entry.getKey())); 83 result.put(entry.getKey(), entry.getValue()); 84 } 85 return Maps.synchronizedBiMap(result); 86 } 87 } 88 89 public static final class SynchTestingBiMapGenerator extends TestStringBiMapGenerator { 90 @Override 91 protected BiMap<String, String> create(Entry<String, String>[] entries) { 92 Object mutex = new Object(); 93 BiMap<String, String> backing = 94 new TestBiMap<String, String>(HashBiMap.<String, String>create(), mutex); 95 BiMap<String, String> result = Synchronized.biMap(backing, mutex); 96 for (Entry<String, String> entry : entries) { 97 checkArgument(!result.containsKey(entry.getKey())); 98 result.put(entry.getKey(), entry.getValue()); 99 } 100 return result; 101 } 102 } 103 104 static class TestBiMap<K, V> extends TestMap<K, V> implements BiMap<K, V> { 105 private final BiMap<K, V> delegate; 106 107 public TestBiMap(BiMap<K, V> delegate, Object mutex) { 108 super(delegate, mutex); 109 this.delegate = delegate; 110 } 111 112 @Override 113 public V forcePut(K key, V value) { 114 assertTrue(Thread.holdsLock(mutex)); 115 return delegate.forcePut(key, value); 116 } 117 118 @Override 119 public BiMap<V, K> inverse() { 120 assertTrue(Thread.holdsLock(mutex)); 121 return delegate.inverse(); 122 } 123 124 @Override public Set<V> values() { 125 assertTrue(Thread.holdsLock(mutex)); 126 return delegate.values(); 127 } 128 129 private static final long serialVersionUID = 0; 130 } 131 132 public void testForcePut() { 133 create().forcePut(null, null); 134 } 135 136 public void testInverse() { 137 BiMap<String, Integer> bimap = create(); 138 BiMap<Integer, String> inverse = bimap.inverse(); 139 assertSame(bimap, inverse.inverse()); 140 assertTrue(inverse instanceof SynchronizedBiMap); 141 assertSame(mutex, ((SynchronizedBiMap<?, ?>) inverse).mutex); 142 } 143 144 @Override public void testValues() { 145 BiMap<String, Integer> map = create(); 146 Set<Integer> values = map.values(); 147 assertTrue(values instanceof SynchronizedSet); 148 assertSame(mutex, ((SynchronizedSet<?>) values).mutex); 149 } 150 } 151