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.truth.Truth.assertThat; 20 21 import com.google.common.annotations.GwtCompatible; 22 import com.google.common.annotations.GwtIncompatible; 23 import com.google.common.annotations.J2ktIncompatible; 24 import com.google.common.collect.testing.features.CollectionFeature; 25 import com.google.common.collect.testing.features.CollectionSize; 26 import com.google.common.collect.testing.features.MapFeature; 27 import com.google.common.collect.testing.google.BiMapTestSuiteBuilder; 28 import com.google.common.collect.testing.google.TestStringBiMapGenerator; 29 import java.util.Iterator; 30 import java.util.Map; 31 import java.util.Map.Entry; 32 import java.util.Set; 33 import junit.framework.Test; 34 import junit.framework.TestCase; 35 import junit.framework.TestSuite; 36 37 /** 38 * Tests for {@link HashBiMap}. 39 * 40 * @author Mike Bostock 41 */ 42 @GwtCompatible(emulated = true) 43 @ElementTypesAreNonnullByDefault 44 public class HashBiMapTest extends TestCase { 45 46 public static final class HashBiMapGenerator extends TestStringBiMapGenerator { 47 @Override create(Entry<String, String>[] entries)48 protected BiMap<String, String> create(Entry<String, String>[] entries) { 49 BiMap<String, String> result = HashBiMap.create(); 50 for (Entry<String, String> entry : entries) { 51 result.put(entry.getKey(), entry.getValue()); 52 } 53 return result; 54 } 55 } 56 57 @J2ktIncompatible 58 @GwtIncompatible // suite suite()59 public static Test suite() { 60 TestSuite suite = new TestSuite(); 61 suite.addTest( 62 BiMapTestSuiteBuilder.using(new HashBiMapGenerator()) 63 .named("HashBiMap") 64 .withFeatures( 65 CollectionSize.ANY, 66 CollectionFeature.SERIALIZABLE, 67 CollectionFeature.SUPPORTS_ITERATOR_REMOVE, 68 CollectionFeature.KNOWN_ORDER, 69 MapFeature.ALLOWS_NULL_KEYS, 70 MapFeature.ALLOWS_NULL_VALUES, 71 MapFeature.ALLOWS_ANY_NULL_QUERIES, 72 MapFeature.GENERAL_PURPOSE) 73 .createTestSuite()); 74 suite.addTestSuite(HashBiMapTest.class); 75 return suite; 76 } 77 testMapConstructor()78 public void testMapConstructor() { 79 /* Test with non-empty Map. */ 80 Map<String, String> map = 81 ImmutableMap.of( 82 "canada", "dollar", 83 "chile", "peso", 84 "switzerland", "franc"); 85 HashBiMap<String, String> bimap = HashBiMap.create(map); 86 assertEquals("dollar", bimap.get("canada")); 87 assertEquals("canada", bimap.inverse().get("dollar")); 88 } 89 90 private static final int N = 1000; 91 testBashIt()92 public void testBashIt() throws Exception { 93 BiMap<Integer, Integer> bimap = HashBiMap.create(N); 94 BiMap<Integer, Integer> inverse = bimap.inverse(); 95 96 for (int i = 0; i < N; i++) { 97 assertNull(bimap.put(2 * i, 2 * i + 1)); 98 } 99 for (int i = 0; i < N; i++) { 100 assertEquals(2 * i + 1, (int) bimap.get(2 * i)); 101 } 102 for (int i = 0; i < N; i++) { 103 assertEquals(2 * i, (int) inverse.get(2 * i + 1)); 104 } 105 for (int i = 0; i < N; i++) { 106 int oldValue = bimap.get(2 * i); 107 assertEquals(2 * i + 1, (int) bimap.put(2 * i, oldValue - 2)); 108 } 109 for (int i = 0; i < N; i++) { 110 assertEquals(2 * i - 1, (int) bimap.get(2 * i)); 111 } 112 for (int i = 0; i < N; i++) { 113 assertEquals(2 * i, (int) inverse.get(2 * i - 1)); 114 } 115 Set<Entry<Integer, Integer>> entries = bimap.entrySet(); 116 for (Entry<Integer, Integer> entry : entries) { 117 entry.setValue(entry.getValue() + 2 * N); 118 } 119 for (int i = 0; i < N; i++) { 120 assertEquals(2 * N + 2 * i - 1, (int) bimap.get(2 * i)); 121 } 122 } 123 testBiMapEntrySetIteratorRemove()124 public void testBiMapEntrySetIteratorRemove() { 125 BiMap<Integer, String> map = HashBiMap.create(); 126 map.put(1, "one"); 127 Set<Entry<Integer, String>> entries = map.entrySet(); 128 Iterator<Entry<Integer, String>> iterator = entries.iterator(); 129 Entry<Integer, String> entry = iterator.next(); 130 entry.setValue("two"); // changes the iterator's current entry value 131 assertEquals("two", map.get(1)); 132 assertEquals(Integer.valueOf(1), map.inverse().get("two")); 133 iterator.remove(); // removes the updated entry 134 assertTrue(map.isEmpty()); 135 } 136 testInsertionOrder()137 public void testInsertionOrder() { 138 BiMap<String, Integer> map = HashBiMap.create(); 139 map.put("foo", 1); 140 map.put("bar", 2); 141 map.put("quux", 3); 142 assertThat(map.entrySet()) 143 .containsExactly( 144 Maps.immutableEntry("foo", 1), 145 Maps.immutableEntry("bar", 2), 146 Maps.immutableEntry("quux", 3)) 147 .inOrder(); 148 } 149 testInsertionOrderAfterRemoveFirst()150 public void testInsertionOrderAfterRemoveFirst() { 151 BiMap<String, Integer> map = HashBiMap.create(); 152 map.put("foo", 1); 153 map.put("bar", 2); 154 map.put("quux", 3); 155 156 map.remove("foo"); 157 assertThat(map.entrySet()) 158 .containsExactly(Maps.immutableEntry("bar", 2), Maps.immutableEntry("quux", 3)) 159 .inOrder(); 160 } 161 testInsertionOrderAfterRemoveMiddle()162 public void testInsertionOrderAfterRemoveMiddle() { 163 BiMap<String, Integer> map = HashBiMap.create(); 164 map.put("foo", 1); 165 map.put("bar", 2); 166 map.put("quux", 3); 167 168 map.remove("bar"); 169 assertThat(map.entrySet()) 170 .containsExactly(Maps.immutableEntry("foo", 1), Maps.immutableEntry("quux", 3)) 171 .inOrder(); 172 } 173 testInsertionOrderAfterRemoveLast()174 public void testInsertionOrderAfterRemoveLast() { 175 BiMap<String, Integer> map = HashBiMap.create(); 176 map.put("foo", 1); 177 map.put("bar", 2); 178 map.put("quux", 3); 179 180 map.remove("quux"); 181 assertThat(map.entrySet()) 182 .containsExactly(Maps.immutableEntry("foo", 1), Maps.immutableEntry("bar", 2)) 183 .inOrder(); 184 } 185 testInsertionOrderAfterForcePut()186 public void testInsertionOrderAfterForcePut() { 187 BiMap<String, Integer> map = HashBiMap.create(); 188 map.put("foo", 1); 189 map.put("bar", 2); 190 map.put("quux", 3); 191 192 map.forcePut("quux", 1); 193 assertThat(map.entrySet()) 194 .containsExactly(Maps.immutableEntry("bar", 2), Maps.immutableEntry("quux", 1)) 195 .inOrder(); 196 } 197 testInsertionOrderAfterInverseForcePut()198 public void testInsertionOrderAfterInverseForcePut() { 199 BiMap<String, Integer> map = HashBiMap.create(); 200 map.put("foo", 1); 201 map.put("bar", 2); 202 map.put("quux", 3); 203 204 map.inverse().forcePut(1, "quux"); 205 assertThat(map.entrySet()) 206 .containsExactly(Maps.immutableEntry("bar", 2), Maps.immutableEntry("quux", 1)) 207 .inOrder(); 208 } 209 testInverseInsertionOrderAfterInverse()210 public void testInverseInsertionOrderAfterInverse() { 211 BiMap<String, Integer> map = HashBiMap.create(); 212 map.put("bar", 2); 213 map.put("quux", 1); 214 215 assertThat(map.inverse().entrySet()) 216 .containsExactly(Maps.immutableEntry(2, "bar"), Maps.immutableEntry(1, "quux")) 217 .inOrder(); 218 } 219 testInverseInsertionOrderAfterInverseForcePut()220 public void testInverseInsertionOrderAfterInverseForcePut() { 221 BiMap<String, Integer> map = HashBiMap.create(); 222 map.put("foo", 1); 223 map.put("bar", 2); 224 map.put("quux", 3); 225 226 map.inverse().forcePut(1, "quux"); 227 assertThat(map.inverse().entrySet()) 228 .containsExactly(Maps.immutableEntry(2, "bar"), Maps.immutableEntry(1, "quux")) 229 .inOrder(); 230 } 231 testInverseInsertionOrderAfterInverseForcePutPresentKey()232 public void testInverseInsertionOrderAfterInverseForcePutPresentKey() { 233 BiMap<String, Integer> map = HashBiMap.create(); 234 map.put("foo", 1); 235 map.put("bar", 2); 236 map.put("quux", 3); 237 map.put("nab", 4); 238 239 map.inverse().forcePut(4, "bar"); 240 assertThat(map.entrySet()) 241 .containsExactly( 242 Maps.immutableEntry("foo", 1), 243 Maps.immutableEntry("bar", 4), 244 Maps.immutableEntry("quux", 3)) 245 .inOrder(); 246 } 247 testInverseEntrySetValueNewKey()248 public void testInverseEntrySetValueNewKey() { 249 BiMap<Integer, String> map = HashBiMap.create(); 250 map.put(1, "a"); 251 map.put(2, "b"); 252 Iterator<Entry<String, Integer>> inverseEntryItr = map.inverse().entrySet().iterator(); 253 Entry<String, Integer> entry = inverseEntryItr.next(); 254 entry.setValue(3); 255 assertEquals(Maps.immutableEntry("b", 2), inverseEntryItr.next()); 256 assertFalse(inverseEntryItr.hasNext()); 257 assertThat(map.entrySet()) 258 .containsExactly(Maps.immutableEntry(2, "b"), Maps.immutableEntry(3, "a")) 259 .inOrder(); 260 } 261 } 262