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 com.google.common.annotations.GwtCompatible;
20import com.google.common.annotations.GwtIncompatible;
21import com.google.common.collect.testing.SampleElements;
22import com.google.common.collect.testing.features.CollectionFeature;
23import com.google.common.collect.testing.features.CollectionSize;
24import com.google.common.collect.testing.features.MapFeature;
25import com.google.common.collect.testing.google.BiMapTestSuiteBuilder;
26import com.google.common.collect.testing.google.TestBiMapGenerator;
27import com.google.common.testing.NullPointerTester;
28import com.google.common.testing.SerializableTester;
29
30import junit.framework.Test;
31import junit.framework.TestCase;
32import junit.framework.TestSuite;
33
34import java.util.Collections;
35import java.util.List;
36import java.util.Map;
37import java.util.Map.Entry;
38import java.util.Set;
39
40/**
41 * Tests for {@code EnumHashBiMap}.
42 *
43 * @author Mike Bostock
44 */
45@GwtCompatible(emulated = true)
46public class EnumHashBiMapTest extends TestCase {
47  private enum Currency { DOLLAR, FRANC, PESO, POUND, YEN }
48  private enum Country { CANADA, CHILE, JAPAN, SWITZERLAND, UK }
49
50  public static final class EnumHashBiMapGenerator implements TestBiMapGenerator<Country, String> {
51    @SuppressWarnings("unchecked")
52    @Override
53    public BiMap<Country, String> create(Object... entries) {
54      BiMap<Country, String> result = EnumHashBiMap.create(Country.class);
55      for (Object o : entries) {
56        Entry<Country, String> entry = (Entry<Country, String>) o;
57        result.put(entry.getKey(), entry.getValue());
58      }
59      return result;
60    }
61
62    @Override
63    public SampleElements<Entry<Country, String>> samples() {
64      return new SampleElements<Entry<Country, String>>(
65          Maps.immutableEntry(Country.CANADA, "DOLLAR"),
66          Maps.immutableEntry(Country.CHILE, "PESO"),
67          Maps.immutableEntry(Country.UK, "POUND"),
68          Maps.immutableEntry(Country.JAPAN, "YEN"),
69          Maps.immutableEntry(Country.SWITZERLAND, "FRANC"));
70    }
71
72    @SuppressWarnings("unchecked")
73    @Override
74    public Entry<Country, String>[] createArray(int length) {
75      return new Entry[length];
76    }
77
78    @Override
79    public Iterable<Entry<Country, String>> order(List<Entry<Country, String>> insertionOrder) {
80      return insertionOrder;
81    }
82
83    @Override
84    public Country[] createKeyArray(int length) {
85      return new Country[length];
86    }
87
88    @Override
89    public String[] createValueArray(int length) {
90      return new String[length];
91    }
92  }
93
94  @GwtIncompatible("suite")
95  public static Test suite() {
96    TestSuite suite = new TestSuite();
97    suite.addTest(BiMapTestSuiteBuilder.using(new EnumHashBiMapGenerator())
98        .named("EnumHashBiMap")
99        .withFeatures(CollectionSize.ANY,
100            CollectionFeature.SERIALIZABLE,
101            CollectionFeature.SUPPORTS_ITERATOR_REMOVE,
102            MapFeature.ALLOWS_NULL_VALUES,
103            MapFeature.GENERAL_PURPOSE,
104            CollectionFeature.KNOWN_ORDER)
105        .createTestSuite());
106    suite.addTestSuite(EnumHashBiMapTest.class);
107    return suite;
108  }
109
110  public void testCreate() {
111    EnumHashBiMap<Currency, String> bimap =
112        EnumHashBiMap.create(Currency.class);
113    assertTrue(bimap.isEmpty());
114    assertEquals("{}", bimap.toString());
115    assertEquals(HashBiMap.create(), bimap);
116    bimap.put(Currency.DOLLAR, "dollar");
117    assertEquals("dollar", bimap.get(Currency.DOLLAR));
118    assertEquals(Currency.DOLLAR, bimap.inverse().get("dollar"));
119  }
120
121  public void testCreateFromMap() {
122    /* Test with non-empty Map. */
123    Map<Currency, String> map = ImmutableMap.of(
124        Currency.DOLLAR, "dollar",
125        Currency.PESO, "peso",
126        Currency.FRANC, "franc");
127    EnumHashBiMap<Currency, String> bimap
128        = EnumHashBiMap.create(map);
129    assertEquals("dollar", bimap.get(Currency.DOLLAR));
130    assertEquals(Currency.DOLLAR, bimap.inverse().get("dollar"));
131
132    /* Map must have at least one entry if not an EnumHashBiMap. */
133    try {
134      EnumHashBiMap.create(
135          Collections.<Currency, String>emptyMap());
136      fail("IllegalArgumentException expected");
137    } catch (IllegalArgumentException expected) {}
138
139    /* Map can be empty if it's an EnumHashBiMap. */
140    Map<Currency, String> emptyBimap = EnumHashBiMap.create(Currency.class);
141    bimap = EnumHashBiMap.create(emptyBimap);
142    assertTrue(bimap.isEmpty());
143
144    /* Map can be empty if it's an EnumBiMap. */
145    Map<Currency, Country> emptyBimap2 =
146        EnumBiMap.create(Currency.class, Country.class);
147    EnumHashBiMap<Currency, Country> bimap2
148        = EnumHashBiMap.create(emptyBimap2);
149    assertTrue(bimap2.isEmpty());
150  }
151
152  public void testEnumHashBiMapConstructor() {
153    /* Test that it copies existing entries. */
154    EnumHashBiMap<Currency, String> bimap1 =
155        EnumHashBiMap.create(Currency.class);
156    bimap1.put(Currency.DOLLAR, "dollar");
157    EnumHashBiMap<Currency, String> bimap2 =
158        EnumHashBiMap.create(bimap1);
159    assertEquals("dollar", bimap2.get(Currency.DOLLAR));
160    assertEquals(bimap1, bimap2);
161    bimap2.inverse().put("franc", Currency.FRANC);
162    assertEquals("franc", bimap2.get(Currency.FRANC));
163    assertNull(bimap1.get(Currency.FRANC));
164    assertFalse(bimap2.equals(bimap1));
165
166    /* Test that it can be empty. */
167    EnumHashBiMap<Currency, String> emptyBimap =
168        EnumHashBiMap.create(Currency.class);
169    EnumHashBiMap<Currency, String> bimap3 =
170        EnumHashBiMap.create(emptyBimap);
171    assertEquals(bimap3, emptyBimap);
172  }
173
174  public void testEnumBiMapConstructor() {
175    /* Test that it copies existing entries. */
176    EnumBiMap<Currency, Country> bimap1 =
177        EnumBiMap.create(Currency.class, Country.class);
178    bimap1.put(Currency.DOLLAR, Country.SWITZERLAND);
179    EnumHashBiMap<Currency, Object> bimap2 = // use supertype
180        EnumHashBiMap.<Currency, Object>create(bimap1);
181    assertEquals(Country.SWITZERLAND, bimap2.get(Currency.DOLLAR));
182    assertEquals(bimap1, bimap2);
183    bimap2.inverse().put("franc", Currency.FRANC);
184    assertEquals("franc", bimap2.get(Currency.FRANC));
185    assertNull(bimap1.get(Currency.FRANC));
186    assertFalse(bimap2.equals(bimap1));
187
188    /* Test that it can be empty. */
189    EnumBiMap<Currency, Country> emptyBimap =
190        EnumBiMap.create(Currency.class, Country.class);
191    EnumHashBiMap<Currency, Country> bimap3 = // use exact type
192        EnumHashBiMap.create(emptyBimap);
193    assertEquals(bimap3, emptyBimap);
194  }
195
196  public void testKeyType() {
197    EnumHashBiMap<Currency, String> bimap =
198        EnumHashBiMap.create(Currency.class);
199    assertEquals(Currency.class, bimap.keyType());
200  }
201
202  public void testEntrySet() {
203    // Bug 3168290
204    Map<Currency, String> map = ImmutableMap.of(
205        Currency.DOLLAR, "dollar",
206        Currency.PESO, "peso",
207        Currency.FRANC, "franc");
208    EnumHashBiMap<Currency, String> bimap
209        = EnumHashBiMap.create(map);
210
211    Set<Object> uniqueEntries = Sets.newIdentityHashSet();
212    uniqueEntries.addAll(bimap.entrySet());
213    assertEquals(3, uniqueEntries.size());
214  }
215
216  @GwtIncompatible("serialize")
217  public void testSerializable() {
218    SerializableTester.reserializeAndAssert(EnumHashBiMap.create(Currency.class));
219  }
220
221  @GwtIncompatible("reflection")
222  public void testNulls() {
223    new NullPointerTester().testAllPublicStaticMethods(EnumHashBiMap.class);
224    new NullPointerTester().testAllPublicInstanceMethods(EnumHashBiMap.create(Currency.class));
225  }
226}
227