Home | History | Annotate | Download | only in collect
      1 /*
      2  * Copyright (C) 2008 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.testing.SerializableTester.reserialize;
     20 
     21 import com.google.common.annotations.GwtCompatible;
     22 import com.google.common.annotations.GwtIncompatible;
     23 import com.google.common.base.Joiner;
     24 import com.google.common.collect.ImmutableMap.Builder;
     25 import com.google.common.collect.testing.AnEnum;
     26 import com.google.common.collect.testing.CollectionTestSuiteBuilder;
     27 import com.google.common.collect.testing.ListTestSuiteBuilder;
     28 import com.google.common.collect.testing.MapInterfaceTest;
     29 import com.google.common.collect.testing.MapTestSuiteBuilder;
     30 import com.google.common.collect.testing.MinimalSet;
     31 import com.google.common.collect.testing.SampleElements.Colliders;
     32 import com.google.common.collect.testing.SampleElements.Unhashables;
     33 import com.google.common.collect.testing.UnhashableObject;
     34 import com.google.common.collect.testing.features.CollectionFeature;
     35 import com.google.common.collect.testing.features.CollectionSize;
     36 import com.google.common.collect.testing.features.MapFeature;
     37 import com.google.common.collect.testing.google.MapGenerators.ImmutableMapCopyOfEnumMapGenerator;
     38 import com.google.common.collect.testing.google.MapGenerators.ImmutableMapCopyOfGenerator;
     39 import com.google.common.collect.testing.google.MapGenerators.ImmutableMapEntryListGenerator;
     40 import com.google.common.collect.testing.google.MapGenerators.ImmutableMapGenerator;
     41 import com.google.common.collect.testing.google.MapGenerators.ImmutableMapKeyListGenerator;
     42 import com.google.common.collect.testing.google.MapGenerators.ImmutableMapUnhashableValuesGenerator;
     43 import com.google.common.collect.testing.google.MapGenerators.ImmutableMapValueListGenerator;
     44 import com.google.common.testing.EqualsTester;
     45 import com.google.common.testing.NullPointerTester;
     46 import com.google.common.testing.SerializableTester;
     47 
     48 import junit.framework.Test;
     49 import junit.framework.TestCase;
     50 import junit.framework.TestSuite;
     51 
     52 import java.io.Serializable;
     53 import java.util.Collection;
     54 import java.util.Collections;
     55 import java.util.EnumMap;
     56 import java.util.LinkedHashMap;
     57 import java.util.Map;
     58 import java.util.Map.Entry;
     59 
     60 /**
     61  * Tests for {@link ImmutableMap}.
     62  *
     63  * @author Kevin Bourrillion
     64  * @author Jesse Wilson
     65  */
     66 @GwtCompatible(emulated = true)
     67 public class ImmutableMapTest extends TestCase {
     68 
     69   @GwtIncompatible("suite")
     70   public static Test suite() {
     71     TestSuite suite = new TestSuite();
     72     suite.addTestSuite(ImmutableMapTest.class);
     73 
     74     suite.addTest(MapTestSuiteBuilder.using(new ImmutableMapGenerator())
     75         .withFeatures(
     76             CollectionSize.ANY,
     77             CollectionFeature.SERIALIZABLE_INCLUDING_VIEWS,
     78             CollectionFeature.KNOWN_ORDER,
     79             MapFeature.REJECTS_DUPLICATES_AT_CREATION,
     80             CollectionFeature.ALLOWS_NULL_QUERIES)
     81         .named("ImmutableMap")
     82         .createTestSuite());
     83 
     84     suite.addTest(MapTestSuiteBuilder.using(new ImmutableMapCopyOfGenerator())
     85         .withFeatures(
     86             CollectionSize.ANY,
     87             CollectionFeature.SERIALIZABLE_INCLUDING_VIEWS,
     88             CollectionFeature.KNOWN_ORDER,
     89             CollectionFeature.ALLOWS_NULL_QUERIES)
     90         .named("ImmutableMap.copyOf")
     91         .createTestSuite());
     92 
     93     suite.addTest(MapTestSuiteBuilder.using(new ImmutableMapCopyOfEnumMapGenerator())
     94         .withFeatures(
     95             CollectionSize.ANY,
     96             CollectionFeature.SERIALIZABLE_INCLUDING_VIEWS,
     97             CollectionFeature.KNOWN_ORDER,
     98             CollectionFeature.ALLOWS_NULL_QUERIES)
     99         .named("ImmutableMap.copyOf[EnumMap]")
    100         .createTestSuite());
    101 
    102     suite.addTest(CollectionTestSuiteBuilder.using(
    103             new ImmutableMapUnhashableValuesGenerator())
    104         .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
    105             CollectionFeature.ALLOWS_NULL_QUERIES)
    106         .named("ImmutableMap.values, unhashable")
    107         .createTestSuite());
    108 
    109     suite.addTest(ListTestSuiteBuilder.using(
    110         new ImmutableMapKeyListGenerator())
    111         .named("ImmutableMap.keySet.asList")
    112         .withFeatures(CollectionSize.ANY,
    113             CollectionFeature.SERIALIZABLE,
    114             CollectionFeature.REJECTS_DUPLICATES_AT_CREATION,
    115             CollectionFeature.ALLOWS_NULL_QUERIES)
    116         .createTestSuite());
    117 
    118     suite.addTest(ListTestSuiteBuilder.using(
    119         new ImmutableMapEntryListGenerator())
    120         .named("ImmutableMap.entrySet.asList")
    121         .withFeatures(CollectionSize.ANY,
    122             CollectionFeature.SERIALIZABLE,
    123             CollectionFeature.REJECTS_DUPLICATES_AT_CREATION,
    124             CollectionFeature.ALLOWS_NULL_QUERIES)
    125         .createTestSuite());
    126 
    127     suite.addTest(ListTestSuiteBuilder.using(
    128         new ImmutableMapValueListGenerator())
    129         .named("ImmutableMap.values.asList")
    130         .withFeatures(CollectionSize.ANY,
    131             CollectionFeature.SERIALIZABLE,
    132             CollectionFeature.ALLOWS_NULL_QUERIES)
    133         .createTestSuite());
    134 
    135     return suite;
    136   }
    137 
    138   public abstract static class AbstractMapTests<K, V>
    139       extends MapInterfaceTest<K, V> {
    140     public AbstractMapTests() {
    141       super(false, false, false, false, false);
    142     }
    143 
    144     @Override protected Map<K, V> makeEmptyMap() {
    145       throw new UnsupportedOperationException();
    146     }
    147 
    148     private static final Joiner joiner = Joiner.on(", ");
    149 
    150     @Override protected void assertMoreInvariants(Map<K, V> map) {
    151       // TODO: can these be moved to MapInterfaceTest?
    152       for (Entry<K, V> entry : map.entrySet()) {
    153         assertEquals(entry.getKey() + "=" + entry.getValue(),
    154             entry.toString());
    155       }
    156 
    157       assertEquals("{" + joiner.join(map.entrySet()) + "}",
    158           map.toString());
    159       assertEquals("[" + joiner.join(map.entrySet()) + "]",
    160           map.entrySet().toString());
    161       assertEquals("[" + joiner.join(map.keySet()) + "]",
    162           map.keySet().toString());
    163       assertEquals("[" + joiner.join(map.values()) + "]",
    164           map.values().toString());
    165 
    166       assertEquals(MinimalSet.from(map.entrySet()), map.entrySet());
    167       assertEquals(Sets.newHashSet(map.keySet()), map.keySet());
    168     }
    169   }
    170 
    171   public static class MapTests extends AbstractMapTests<String, Integer> {
    172     @Override protected Map<String, Integer> makeEmptyMap() {
    173       return ImmutableMap.of();
    174     }
    175 
    176     @Override protected Map<String, Integer> makePopulatedMap() {
    177       return ImmutableMap.of("one", 1, "two", 2, "three", 3);
    178     }
    179 
    180     @Override protected String getKeyNotInPopulatedMap() {
    181       return "minus one";
    182     }
    183 
    184     @Override protected Integer getValueNotInPopulatedMap() {
    185       return -1;
    186     }
    187   }
    188 
    189   public static class SingletonMapTests
    190       extends AbstractMapTests<String, Integer> {
    191     @Override protected Map<String, Integer> makePopulatedMap() {
    192       return ImmutableMap.of("one", 1);
    193     }
    194 
    195     @Override protected String getKeyNotInPopulatedMap() {
    196       return "minus one";
    197     }
    198 
    199     @Override protected Integer getValueNotInPopulatedMap() {
    200       return -1;
    201     }
    202   }
    203 
    204   @GwtIncompatible("SerializableTester")
    205   public static class ReserializedMapTests
    206       extends AbstractMapTests<String, Integer> {
    207     @Override protected Map<String, Integer> makePopulatedMap() {
    208       return SerializableTester.reserialize(
    209           ImmutableMap.of("one", 1, "two", 2, "three", 3));
    210     }
    211 
    212     @Override protected String getKeyNotInPopulatedMap() {
    213       return "minus one";
    214     }
    215 
    216     @Override protected Integer getValueNotInPopulatedMap() {
    217       return -1;
    218     }
    219   }
    220 
    221   public static class MapTestsWithBadHashes
    222       extends AbstractMapTests<Object, Integer> {
    223 
    224     @Override protected Map<Object, Integer> makeEmptyMap() {
    225       throw new UnsupportedOperationException();
    226     }
    227 
    228     @Override protected Map<Object, Integer> makePopulatedMap() {
    229       Colliders colliders = new Colliders();
    230       return ImmutableMap.of(
    231           colliders.e0, 0,
    232           colliders.e1, 1,
    233           colliders.e2, 2,
    234           colliders.e3, 3);
    235     }
    236 
    237     @Override protected Object getKeyNotInPopulatedMap() {
    238       return new Colliders().e4;
    239     }
    240 
    241     @Override protected Integer getValueNotInPopulatedMap() {
    242       return 4;
    243     }
    244   }
    245 
    246   @GwtIncompatible("GWT's ImmutableMap emulation is backed by java.util.HashMap.")
    247   public static class MapTestsWithUnhashableValues
    248       extends AbstractMapTests<Integer, UnhashableObject> {
    249     @Override protected Map<Integer, UnhashableObject> makeEmptyMap() {
    250       return ImmutableMap.of();
    251     }
    252 
    253     @Override protected Map<Integer, UnhashableObject> makePopulatedMap() {
    254       Unhashables unhashables = new Unhashables();
    255       return ImmutableMap.of(
    256           0, unhashables.e0, 1, unhashables.e1, 2, unhashables.e2);
    257     }
    258 
    259     @Override protected Integer getKeyNotInPopulatedMap() {
    260       return 3;
    261     }
    262 
    263     @Override protected UnhashableObject getValueNotInPopulatedMap() {
    264       return new Unhashables().e3;
    265     }
    266   }
    267 
    268   @GwtIncompatible("GWT's ImmutableMap emulation is backed by java.util.HashMap.")
    269   public static class MapTestsWithSingletonUnhashableValue
    270       extends MapTestsWithUnhashableValues {
    271     @Override protected Map<Integer, UnhashableObject> makePopulatedMap() {
    272       Unhashables unhashables = new Unhashables();
    273       return ImmutableMap.of(0, unhashables.e0);
    274     }
    275   }
    276 
    277   public static class CreationTests extends TestCase {
    278     public void testEmptyBuilder() {
    279       ImmutableMap<String, Integer> map
    280           = new Builder<String, Integer>().build();
    281       assertEquals(Collections.<String, Integer>emptyMap(), map);
    282     }
    283 
    284     public void testSingletonBuilder() {
    285       ImmutableMap<String, Integer> map = new Builder<String, Integer>()
    286           .put("one", 1)
    287           .build();
    288       assertMapEquals(map, "one", 1);
    289     }
    290 
    291     public void testBuilder() {
    292       ImmutableMap<String, Integer> map = new Builder<String, Integer>()
    293           .put("one", 1)
    294           .put("two", 2)
    295           .put("three", 3)
    296           .put("four", 4)
    297           .put("five", 5)
    298           .build();
    299       assertMapEquals(map,
    300           "one", 1, "two", 2, "three", 3, "four", 4, "five", 5);
    301     }
    302 
    303     public void testBuilder_withImmutableEntry() {
    304       ImmutableMap<String, Integer> map = new Builder<String, Integer>()
    305           .put(Maps.immutableEntry("one", 1))
    306           .build();
    307       assertMapEquals(map, "one", 1);
    308     }
    309 
    310     public void testBuilder_withImmutableEntryAndNullContents() {
    311       Builder<String, Integer> builder = new Builder<String, Integer>();
    312       try {
    313         builder.put(Maps.immutableEntry("one", (Integer) null));
    314         fail();
    315       } catch (NullPointerException expected) {
    316       }
    317       try {
    318         builder.put(Maps.immutableEntry((String) null, 1));
    319         fail();
    320       } catch (NullPointerException expected) {
    321       }
    322     }
    323 
    324     private static class StringHolder {
    325       String string;
    326     }
    327 
    328     public void testBuilder_withMutableEntry() {
    329       ImmutableMap.Builder<String, Integer> builder =
    330           new Builder<String, Integer>();
    331       final StringHolder holder = new StringHolder();
    332       holder.string = "one";
    333       Entry<String, Integer> entry = new AbstractMapEntry<String, Integer>() {
    334         @Override public String getKey() {
    335           return holder.string;
    336         }
    337         @Override public Integer getValue() {
    338           return 1;
    339         }
    340       };
    341 
    342       builder.put(entry);
    343       holder.string = "two";
    344       assertMapEquals(builder.build(), "one", 1);
    345     }
    346 
    347     public void testBuilderPutAllWithEmptyMap() {
    348       ImmutableMap<String, Integer> map = new Builder<String, Integer>()
    349           .putAll(Collections.<String, Integer>emptyMap())
    350           .build();
    351       assertEquals(Collections.<String, Integer>emptyMap(), map);
    352     }
    353 
    354     public void testBuilderPutAll() {
    355       Map<String, Integer> toPut = new LinkedHashMap<String, Integer>();
    356       toPut.put("one", 1);
    357       toPut.put("two", 2);
    358       toPut.put("three", 3);
    359       Map<String, Integer> moreToPut = new LinkedHashMap<String, Integer>();
    360       moreToPut.put("four", 4);
    361       moreToPut.put("five", 5);
    362 
    363       ImmutableMap<String, Integer> map = new Builder<String, Integer>()
    364           .putAll(toPut)
    365           .putAll(moreToPut)
    366           .build();
    367       assertMapEquals(map,
    368           "one", 1, "two", 2, "three", 3, "four", 4, "five", 5);
    369     }
    370 
    371     public void testBuilderReuse() {
    372       Builder<String, Integer> builder = new Builder<String, Integer>();
    373       ImmutableMap<String, Integer> mapOne = builder
    374           .put("one", 1)
    375           .put("two", 2)
    376           .build();
    377       ImmutableMap<String, Integer> mapTwo = builder
    378           .put("three", 3)
    379           .put("four", 4)
    380           .build();
    381 
    382       assertMapEquals(mapOne, "one", 1, "two", 2);
    383       assertMapEquals(mapTwo, "one", 1, "two", 2, "three", 3, "four", 4);
    384     }
    385 
    386     public void testBuilderPutNullKeyFailsAtomically() {
    387       Builder<String, Integer> builder = new Builder<String, Integer>();
    388       try {
    389         builder.put(null, 1);
    390         fail();
    391       } catch (NullPointerException expected) {}
    392       builder.put("foo", 2);
    393       assertMapEquals(builder.build(), "foo", 2);
    394     }
    395 
    396     public void testBuilderPutImmutableEntryWithNullKeyFailsAtomically() {
    397       Builder<String, Integer> builder = new Builder<String, Integer>();
    398       try {
    399         builder.put(Maps.immutableEntry((String) null, 1));
    400         fail();
    401       } catch (NullPointerException expected) {}
    402       builder.put("foo", 2);
    403       assertMapEquals(builder.build(), "foo", 2);
    404     }
    405 
    406     // for GWT compatibility
    407     static class SimpleEntry<K, V> extends AbstractMapEntry<K, V> {
    408       public K key;
    409       public V value;
    410 
    411       SimpleEntry(K key, V value) {
    412         this.key = key;
    413         this.value = value;
    414       }
    415 
    416       @Override
    417       public K getKey() {
    418         return key;
    419       }
    420 
    421       @Override
    422       public V getValue() {
    423         return value;
    424       }
    425     }
    426 
    427     public void testBuilderPutMutableEntryWithNullKeyFailsAtomically() {
    428       Builder<String, Integer> builder = new Builder<String, Integer>();
    429       try {
    430         builder.put(new SimpleEntry<String, Integer>(null, 1));
    431         fail();
    432       } catch (NullPointerException expected) {}
    433       builder.put("foo", 2);
    434       assertMapEquals(builder.build(), "foo", 2);
    435     }
    436 
    437     public void testBuilderPutNullKey() {
    438       Builder<String, Integer> builder = new Builder<String, Integer>();
    439       try {
    440         builder.put(null, 1);
    441         fail();
    442       } catch (NullPointerException expected) {
    443       }
    444     }
    445 
    446     public void testBuilderPutNullValue() {
    447       Builder<String, Integer> builder = new Builder<String, Integer>();
    448       try {
    449         builder.put("one", null);
    450         fail();
    451       } catch (NullPointerException expected) {
    452       }
    453     }
    454 
    455     public void testBuilderPutNullKeyViaPutAll() {
    456       Builder<String, Integer> builder = new Builder<String, Integer>();
    457       try {
    458         builder.putAll(Collections.<String, Integer>singletonMap(null, 1));
    459         fail();
    460       } catch (NullPointerException expected) {
    461       }
    462     }
    463 
    464     public void testBuilderPutNullValueViaPutAll() {
    465       Builder<String, Integer> builder = new Builder<String, Integer>();
    466       try {
    467         builder.putAll(Collections.<String, Integer>singletonMap("one", null));
    468         fail();
    469       } catch (NullPointerException expected) {
    470       }
    471     }
    472 
    473     public void testPuttingTheSameKeyTwiceThrowsOnBuild() {
    474       Builder<String, Integer> builder = new Builder<String, Integer>()
    475           .put("one", 1)
    476           .put("one", 1); // throwing on this line would be even better
    477 
    478       try {
    479         builder.build();
    480         fail();
    481       } catch (IllegalArgumentException expected) {
    482       }
    483     }
    484 
    485     public void testOf() {
    486       assertMapEquals(
    487           ImmutableMap.of("one", 1),
    488           "one", 1);
    489       assertMapEquals(
    490           ImmutableMap.of("one", 1, "two", 2),
    491           "one", 1, "two", 2);
    492       assertMapEquals(
    493           ImmutableMap.of("one", 1, "two", 2, "three", 3),
    494           "one", 1, "two", 2, "three", 3);
    495       assertMapEquals(
    496           ImmutableMap.of("one", 1, "two", 2, "three", 3, "four", 4),
    497           "one", 1, "two", 2, "three", 3, "four", 4);
    498       assertMapEquals(
    499           ImmutableMap.of("one", 1, "two", 2, "three", 3, "four", 4, "five", 5),
    500           "one", 1, "two", 2, "three", 3, "four", 4, "five", 5);
    501     }
    502 
    503     public void testOfNullKey() {
    504       try {
    505         ImmutableMap.of(null, 1);
    506         fail();
    507       } catch (NullPointerException expected) {
    508       }
    509 
    510       try {
    511         ImmutableMap.of("one", 1, null, 2);
    512         fail();
    513       } catch (NullPointerException expected) {
    514       }
    515     }
    516 
    517     public void testOfNullValue() {
    518       try {
    519         ImmutableMap.of("one", null);
    520         fail();
    521       } catch (NullPointerException expected) {
    522       }
    523 
    524       try {
    525         ImmutableMap.of("one", 1, "two", null);
    526         fail();
    527       } catch (NullPointerException expected) {
    528       }
    529     }
    530 
    531     public void testOfWithDuplicateKey() {
    532       try {
    533         ImmutableMap.of("one", 1, "one", 1);
    534         fail();
    535       } catch (IllegalArgumentException expected) {
    536       }
    537     }
    538 
    539     public void testCopyOfEmptyMap() {
    540       ImmutableMap<String, Integer> copy
    541           = ImmutableMap.copyOf(Collections.<String, Integer>emptyMap());
    542       assertEquals(Collections.<String, Integer>emptyMap(), copy);
    543       assertSame(copy, ImmutableMap.copyOf(copy));
    544     }
    545 
    546     public void testCopyOfSingletonMap() {
    547       ImmutableMap<String, Integer> copy
    548           = ImmutableMap.copyOf(Collections.singletonMap("one", 1));
    549       assertMapEquals(copy, "one", 1);
    550       assertSame(copy, ImmutableMap.copyOf(copy));
    551     }
    552 
    553     public void testCopyOf() {
    554       Map<String, Integer> original = new LinkedHashMap<String, Integer>();
    555       original.put("one", 1);
    556       original.put("two", 2);
    557       original.put("three", 3);
    558 
    559       ImmutableMap<String, Integer> copy = ImmutableMap.copyOf(original);
    560       assertMapEquals(copy, "one", 1, "two", 2, "three", 3);
    561       assertSame(copy, ImmutableMap.copyOf(copy));
    562     }
    563   }
    564 
    565   public void testNullGet() {
    566     ImmutableMap<String, Integer> map = ImmutableMap.of("one", 1);
    567     assertNull(map.get(null));
    568   }
    569 
    570   public void testAsMultimap() {
    571     ImmutableMap<String, Integer> map = ImmutableMap.of(
    572         "one", 1, "won", 1, "two", 2, "too", 2, "three", 3);
    573     ImmutableSetMultimap<String, Integer> expected = ImmutableSetMultimap.of(
    574         "one", 1, "won", 1, "two", 2, "too", 2, "three", 3);
    575     assertEquals(expected, map.asMultimap());
    576   }
    577 
    578   public void testAsMultimapWhenEmpty() {
    579     ImmutableMap<String, Integer> map = ImmutableMap.of();
    580     ImmutableSetMultimap<String, Integer> expected = ImmutableSetMultimap.of();
    581     assertEquals(expected, map.asMultimap());
    582   }
    583 
    584   public void testAsMultimapCaches() {
    585     ImmutableMap<String, Integer> map = ImmutableMap.of("one", 1);
    586     ImmutableSetMultimap<String, Integer> multimap1 = map.asMultimap();
    587     ImmutableSetMultimap<String, Integer> multimap2 = map.asMultimap();
    588     assertEquals(1, multimap1.asMap().size());
    589     assertSame(multimap1, multimap2);
    590   }
    591 
    592   @GwtIncompatible("NullPointerTester")
    593   public void testNullPointers() {
    594     NullPointerTester tester = new NullPointerTester();
    595     tester.testAllPublicStaticMethods(ImmutableMap.class);
    596     tester.testAllPublicInstanceMethods(
    597         new ImmutableMap.Builder<Object, Object>());
    598     tester.testAllPublicInstanceMethods(ImmutableMap.of());
    599     tester.testAllPublicInstanceMethods(ImmutableMap.of("one", 1));
    600     tester.testAllPublicInstanceMethods(
    601         ImmutableMap.of("one", 1, "two", 2, "three", 3));
    602   }
    603 
    604   private static <K, V> void assertMapEquals(Map<K, V> map,
    605       Object... alternatingKeysAndValues) {
    606     assertEquals(map.size(), alternatingKeysAndValues.length / 2);
    607     int i = 0;
    608     for (Entry<K, V> entry : map.entrySet()) {
    609       assertEquals(alternatingKeysAndValues[i++], entry.getKey());
    610       assertEquals(alternatingKeysAndValues[i++], entry.getValue());
    611     }
    612   }
    613 
    614   private static class IntHolder implements Serializable {
    615     public int value;
    616 
    617     public IntHolder(int value) {
    618       this.value = value;
    619     }
    620 
    621     @Override public boolean equals(Object o) {
    622       return (o instanceof IntHolder) && ((IntHolder) o).value == value;
    623     }
    624 
    625     @Override public int hashCode() {
    626       return value;
    627     }
    628 
    629     private static final long serialVersionUID = 5;
    630   }
    631 
    632   public void testMutableValues() {
    633     IntHolder holderA = new IntHolder(1);
    634     IntHolder holderB = new IntHolder(2);
    635     Map<String, IntHolder> map = ImmutableMap.of("a", holderA, "b", holderB);
    636     holderA.value = 3;
    637     assertTrue(map.entrySet().contains(
    638         Maps.immutableEntry("a", new IntHolder(3))));
    639     Map<String, Integer> intMap = ImmutableMap.of("a", 3, "b", 2);
    640     assertEquals(intMap.hashCode(), map.entrySet().hashCode());
    641     assertEquals(intMap.hashCode(), map.hashCode());
    642   }
    643 
    644   public void testCopyOfEnumMap() {
    645     EnumMap<AnEnum, String> map = new EnumMap<AnEnum, String>(AnEnum.class);
    646     map.put(AnEnum.B, "foo");
    647     map.put(AnEnum.C, "bar");
    648     assertTrue(ImmutableMap.copyOf(map) instanceof ImmutableEnumMap);
    649   }
    650 
    651   @GwtIncompatible("SerializableTester")
    652   public void testViewSerialization() {
    653     Map<String, Integer> map = ImmutableMap.of("one", 1, "two", 2, "three", 3);
    654     LenientSerializableTester.reserializeAndAssertLenient(map.entrySet());
    655     LenientSerializableTester.reserializeAndAssertLenient(map.keySet());
    656 
    657     Collection<Integer> reserializedValues = reserialize(map.values());
    658     assertEquals(Lists.newArrayList(map.values()),
    659         Lists.newArrayList(reserializedValues));
    660     assertTrue(reserializedValues instanceof ImmutableCollection);
    661   }
    662 
    663   public void testEquals() {
    664     new EqualsTester()
    665         .addEqualityGroup(ImmutableList.of(), ImmutableList.of())
    666         .addEqualityGroup(ImmutableList.of(1), ImmutableList.of(1))
    667         .addEqualityGroup(ImmutableList.of(1, 2), ImmutableList.of(1, 2))
    668         .addEqualityGroup(ImmutableList.of(1, 2, 3))
    669         .addEqualityGroup(ImmutableList.of(1, 2, 3, 4))
    670         .addEqualityGroup(ImmutableList.of(1, 2, 3, 4, 5))
    671         .addEqualityGroup(ImmutableList.of(1, 2, 3, 4, 5, 6))
    672         .addEqualityGroup(ImmutableList.of(1, 2, 3, 4, 5, 6, 7))
    673         .addEqualityGroup(ImmutableList.of(1, 2, 3, 4, 5, 6, 7, 8))
    674         .addEqualityGroup(ImmutableList.of(1, 2, 3, 4, 5, 6, 7, 8, 9))
    675         .addEqualityGroup(ImmutableList.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10))
    676         .addEqualityGroup(ImmutableList.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11))
    677         .addEqualityGroup(ImmutableList.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12))
    678         .addEqualityGroup(ImmutableList.of(100, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12))
    679         .addEqualityGroup(ImmutableList.of(1, 200, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12))
    680         .addEqualityGroup(ImmutableList.of(1, 2, 300, 4, 5, 6, 7, 8, 9, 10, 11, 12))
    681         .addEqualityGroup(ImmutableList.of(1, 2, 3, 400, 5, 6, 7, 8, 9, 10, 11, 12))
    682         .addEqualityGroup(ImmutableList.of(1, 2, 3, 4, 500, 6, 7, 8, 9, 10, 11, 12))
    683         .addEqualityGroup(ImmutableList.of(1, 2, 3, 4, 5, 600, 7, 8, 9, 10, 11, 12))
    684         .addEqualityGroup(ImmutableList.of(1, 2, 3, 4, 5, 6, 700, 8, 9, 10, 11, 12))
    685         .addEqualityGroup(ImmutableList.of(1, 2, 3, 4, 5, 6, 7, 800, 9, 10, 11, 12))
    686         .addEqualityGroup(ImmutableList.of(1, 2, 3, 4, 5, 6, 7, 8, 900, 10, 11, 12))
    687         .addEqualityGroup(ImmutableList.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 1000, 11, 12))
    688         .addEqualityGroup(ImmutableList.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1100, 12))
    689         .addEqualityGroup(ImmutableList.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 1200))
    690         .testEquals();
    691 
    692   }
    693 }
    694