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