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