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