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