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
17package com.google.common.collect;
18
19import static com.google.common.testing.SerializableTester.reserialize;
20
21import com.google.common.annotations.GwtCompatible;
22import com.google.common.annotations.GwtIncompatible;
23import com.google.common.base.Joiner;
24import com.google.common.collect.ImmutableMap.Builder;
25import com.google.common.collect.testing.AnEnum;
26import com.google.common.collect.testing.CollectionTestSuiteBuilder;
27import com.google.common.collect.testing.ListTestSuiteBuilder;
28import com.google.common.collect.testing.MapInterfaceTest;
29import com.google.common.collect.testing.MapTestSuiteBuilder;
30import com.google.common.collect.testing.MinimalSet;
31import com.google.common.collect.testing.SampleElements.Colliders;
32import com.google.common.collect.testing.SampleElements.Unhashables;
33import com.google.common.collect.testing.UnhashableObject;
34import com.google.common.collect.testing.features.CollectionFeature;
35import com.google.common.collect.testing.features.CollectionSize;
36import com.google.common.collect.testing.features.MapFeature;
37import com.google.common.collect.testing.google.MapGenerators.ImmutableMapCopyOfEnumMapGenerator;
38import com.google.common.collect.testing.google.MapGenerators.ImmutableMapCopyOfGenerator;
39import com.google.common.collect.testing.google.MapGenerators.ImmutableMapEntryListGenerator;
40import com.google.common.collect.testing.google.MapGenerators.ImmutableMapGenerator;
41import com.google.common.collect.testing.google.MapGenerators.ImmutableMapKeyListGenerator;
42import com.google.common.collect.testing.google.MapGenerators.ImmutableMapUnhashableValuesGenerator;
43import com.google.common.collect.testing.google.MapGenerators.ImmutableMapValueListGenerator;
44import com.google.common.testing.EqualsTester;
45import com.google.common.testing.NullPointerTester;
46import com.google.common.testing.SerializableTester;
47
48import junit.framework.Test;
49import junit.framework.TestCase;
50import junit.framework.TestSuite;
51
52import java.io.Serializable;
53import java.util.Collection;
54import java.util.Collections;
55import java.util.EnumMap;
56import java.util.LinkedHashMap;
57import java.util.Map;
58import 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)
67public 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