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.collect.testing.Helpers.orderEntriesByKey; 20import static org.truth0.Truth.ASSERT; 21 22import com.google.common.annotations.GwtCompatible; 23import com.google.common.collect.testing.Helpers; 24import com.google.common.collect.testing.SampleElements; 25import com.google.common.collect.testing.google.TestBiMapGenerator; 26import com.google.common.testing.EqualsTester; 27 28import junit.framework.TestCase; 29 30import java.util.Collections; 31import java.util.Iterator; 32import java.util.List; 33import java.util.Map; 34import java.util.Map.Entry; 35import java.util.Set; 36 37/** 38 * Tests for {@code EnumBiMap}. 39 * 40 * @author Mike Bostock 41 * @author Jared Levy 42 */ 43@GwtCompatible(emulated = true) 44public class EnumBiMapTest extends TestCase { 45 private enum Currency { DOLLAR, FRANC, PESO, POUND, YEN } 46 private enum Country { CANADA, CHILE, JAPAN, SWITZERLAND, UK } 47 48 public static final class EnumBiMapGenerator implements TestBiMapGenerator<Country, Currency> { 49 @SuppressWarnings("unchecked") 50 @Override 51 public BiMap<Country, Currency> create(Object... entries) { 52 BiMap<Country, Currency> result = EnumBiMap.create(Country.class, Currency.class); 53 for (Object object : entries) { 54 Entry<Country, Currency> entry = (Entry<Country, Currency>) object; 55 result.put(entry.getKey(), entry.getValue()); 56 } 57 return result; 58 } 59 60 @Override 61 public SampleElements<Entry<Country, Currency>> samples() { 62 return new SampleElements<Entry<Country, Currency>>( 63 Helpers.mapEntry(Country.CANADA, Currency.DOLLAR), 64 Helpers.mapEntry(Country.CHILE, Currency.PESO), 65 Helpers.mapEntry(Country.UK, Currency.POUND), 66 Helpers.mapEntry(Country.JAPAN, Currency.YEN), 67 Helpers.mapEntry(Country.SWITZERLAND, Currency.FRANC)); 68 } 69 70 @SuppressWarnings("unchecked") 71 @Override 72 public Entry<Country, Currency>[] createArray(int length) { 73 return new Entry[length]; 74 } 75 76 @Override 77 public Iterable<Entry<Country, Currency>> order(List<Entry<Country, Currency>> insertionOrder) { 78 return orderEntriesByKey(insertionOrder); 79 } 80 81 @Override 82 public Country[] createKeyArray(int length) { 83 return new Country[length]; 84 } 85 86 @Override 87 public Currency[] createValueArray(int length) { 88 return new Currency[length]; 89 } 90 } 91 92 public void testCreate() { 93 EnumBiMap<Currency, Country> bimap = 94 EnumBiMap.create(Currency.class, Country.class); 95 assertTrue(bimap.isEmpty()); 96 assertEquals("{}", bimap.toString()); 97 assertEquals(HashBiMap.create(), bimap); 98 bimap.put(Currency.DOLLAR, Country.CANADA); 99 assertEquals(Country.CANADA, bimap.get(Currency.DOLLAR)); 100 assertEquals(Currency.DOLLAR, bimap.inverse().get(Country.CANADA)); 101 } 102 103 public void testCreateFromMap() { 104 /* Test with non-empty Map. */ 105 Map<Currency, Country> map = ImmutableMap.of( 106 Currency.DOLLAR, Country.CANADA, 107 Currency.PESO, Country.CHILE, 108 Currency.FRANC, Country.SWITZERLAND); 109 EnumBiMap<Currency, Country> bimap = EnumBiMap.create(map); 110 assertEquals(Country.CANADA, bimap.get(Currency.DOLLAR)); 111 assertEquals(Currency.DOLLAR, bimap.inverse().get(Country.CANADA)); 112 113 /* Map must have at least one entry if not an EnumBiMap. */ 114 try { 115 EnumBiMap.create(Collections.<Currency, Country>emptyMap()); 116 fail("IllegalArgumentException expected"); 117 } catch (IllegalArgumentException expected) {} 118 try { 119 EnumBiMap.create( 120 EnumHashBiMap.<Currency, Country>create(Currency.class)); 121 fail("IllegalArgumentException expected"); 122 } catch (IllegalArgumentException expected) {} 123 124 /* Map can be empty if it's an EnumBiMap. */ 125 Map<Currency, Country> emptyBimap = 126 EnumBiMap.create(Currency.class, Country.class); 127 bimap = EnumBiMap.create(emptyBimap); 128 assertTrue(bimap.isEmpty()); 129 } 130 131 public void testEnumBiMapConstructor() { 132 /* Test that it copies existing entries. */ 133 EnumBiMap<Currency, Country> bimap1 = 134 EnumBiMap.create(Currency.class, Country.class); 135 bimap1.put(Currency.DOLLAR, Country.CANADA); 136 EnumBiMap<Currency, Country> bimap2 = 137 EnumBiMap.create(bimap1); 138 assertEquals(Country.CANADA, bimap2.get(Currency.DOLLAR)); 139 assertEquals(bimap1, bimap2); 140 bimap2.inverse().put(Country.SWITZERLAND, Currency.FRANC); 141 assertEquals(Country.SWITZERLAND, bimap2.get(Currency.FRANC)); 142 assertNull(bimap1.get(Currency.FRANC)); 143 assertFalse(bimap2.equals(bimap1)); 144 145 /* Test that it can be empty. */ 146 EnumBiMap<Currency, Country> emptyBimap = 147 EnumBiMap.create(Currency.class, Country.class); 148 EnumBiMap<Currency, Country> bimap3 = 149 EnumBiMap.create(emptyBimap); 150 assertEquals(bimap3, emptyBimap); 151 } 152 153 public void testKeyType() { 154 EnumBiMap<Currency, Country> bimap = 155 EnumBiMap.create(Currency.class, Country.class); 156 assertEquals(Currency.class, bimap.keyType()); 157 } 158 159 public void testValueType() { 160 EnumBiMap<Currency, Country> bimap = 161 EnumBiMap.create(Currency.class, Country.class); 162 assertEquals(Country.class, bimap.valueType()); 163 } 164 165 public void testIterationOrder() { 166 // The enum orderings are alphabetical, leading to the bimap and its inverse 167 // having inconsistent iteration orderings. 168 Map<Currency, Country> map = ImmutableMap.of( 169 Currency.DOLLAR, Country.CANADA, 170 Currency.PESO, Country.CHILE, 171 Currency.FRANC, Country.SWITZERLAND); 172 EnumBiMap<Currency, Country> bimap = EnumBiMap.create(map); 173 174 // forward map ordered by currency 175 ASSERT.that(bimap.keySet()) 176 .has().exactly(Currency.DOLLAR, Currency.FRANC, Currency.PESO).inOrder(); 177 // forward map ordered by currency (even for country values) 178 ASSERT.that(bimap.values()) 179 .has().exactly(Country.CANADA, Country.SWITZERLAND, Country.CHILE).inOrder(); 180 // backward map ordered by country 181 ASSERT.that(bimap.inverse().keySet()) 182 .has().exactly(Country.CANADA, Country.CHILE, Country.SWITZERLAND).inOrder(); 183 // backward map ordered by country (even for currency values) 184 ASSERT.that(bimap.inverse().values()) 185 .has().exactly(Currency.DOLLAR, Currency.PESO, Currency.FRANC).inOrder(); 186 } 187 188 public void testKeySetIteratorRemove() { 189 // The enum orderings are alphabetical, leading to the bimap and its inverse 190 // having inconsistent iteration orderings. 191 Map<Currency, Country> map = ImmutableMap.of( 192 Currency.DOLLAR, Country.CANADA, 193 Currency.PESO, Country.CHILE, 194 Currency.FRANC, Country.SWITZERLAND); 195 EnumBiMap<Currency, Country> bimap = EnumBiMap.create(map); 196 197 Iterator<Currency> iter = bimap.keySet().iterator(); 198 assertEquals(Currency.DOLLAR, iter.next()); 199 iter.remove(); 200 201 // forward map ordered by currency 202 ASSERT.that(bimap.keySet()) 203 .has().exactly(Currency.FRANC, Currency.PESO).inOrder(); 204 // forward map ordered by currency (even for country values) 205 ASSERT.that(bimap.values()) 206 .has().exactly(Country.SWITZERLAND, Country.CHILE).inOrder(); 207 // backward map ordered by country 208 ASSERT.that(bimap.inverse().keySet()) 209 .has().exactly(Country.CHILE, Country.SWITZERLAND).inOrder(); 210 // backward map ordered by country (even for currency values) 211 ASSERT.that(bimap.inverse().values()) 212 .has().exactly(Currency.PESO, Currency.FRANC).inOrder(); 213 } 214 215 public void testValuesIteratorRemove() { 216 // The enum orderings are alphabetical, leading to the bimap and its inverse 217 // having inconsistent iteration orderings. 218 Map<Currency, Country> map = ImmutableMap.of( 219 Currency.DOLLAR, Country.CANADA, 220 Currency.PESO, Country.CHILE, 221 Currency.FRANC, Country.SWITZERLAND); 222 EnumBiMap<Currency, Country> bimap = EnumBiMap.create(map); 223 224 Iterator<Currency> iter = bimap.keySet().iterator(); 225 assertEquals(Currency.DOLLAR, iter.next()); 226 assertEquals(Currency.FRANC, iter.next()); 227 iter.remove(); 228 229 // forward map ordered by currency 230 ASSERT.that(bimap.keySet()) 231 .has().exactly(Currency.DOLLAR, Currency.PESO).inOrder(); 232 // forward map ordered by currency (even for country values) 233 ASSERT.that(bimap.values()) 234 .has().exactly(Country.CANADA, Country.CHILE).inOrder(); 235 // backward map ordered by country 236 ASSERT.that(bimap.inverse().keySet()) 237 .has().exactly(Country.CANADA, Country.CHILE).inOrder(); 238 // backward map ordered by country (even for currency values) 239 ASSERT.that(bimap.inverse().values()) 240 .has().exactly(Currency.DOLLAR, Currency.PESO).inOrder(); 241 } 242 243 public void testEntrySet() { 244 // Bug 3168290 245 Map<Currency, Country> map = ImmutableMap.of( 246 Currency.DOLLAR, Country.CANADA, 247 Currency.PESO, Country.CHILE, 248 Currency.FRANC, Country.SWITZERLAND); 249 EnumBiMap<Currency, Country> bimap = EnumBiMap.create(map); 250 Set<Object> uniqueEntries = Sets.newIdentityHashSet(); 251 uniqueEntries.addAll(bimap.entrySet()); 252 assertEquals(3, uniqueEntries.size()); 253 } 254 255 public void testEquals() { 256 new EqualsTester() 257 .addEqualityGroup( 258 EnumBiMap.create(ImmutableMap.of(Currency.DOLLAR, Country.CANADA)), 259 EnumBiMap.create(ImmutableMap.of(Currency.DOLLAR, Country.CANADA))) 260 .addEqualityGroup(EnumBiMap.create(ImmutableMap.of(Currency.DOLLAR, Country.CHILE))) 261 .addEqualityGroup(EnumBiMap.create(ImmutableMap.of(Currency.FRANC, Country.CANADA))) 262 .testEquals(); 263 } 264 265 /* Remaining behavior tested by AbstractBiMapTest. */ 266} 267 268