Home | History | Annotate | Download | only in collect
      1 /*
      2  * Copyright (C) 2009 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 org.junit.contrib.truth.Truth.ASSERT;
     20 
     21 import com.google.common.annotations.GwtCompatible;
     22 import com.google.common.annotations.GwtIncompatible;
     23 import com.google.common.collect.ImmutableSetMultimap.Builder;
     24 import com.google.common.collect.testing.google.UnmodifiableCollectionTests;
     25 import com.google.common.testing.EqualsTester;
     26 import com.google.common.testing.SerializableTester;
     27 
     28 import junit.framework.TestCase;
     29 
     30 import java.util.Arrays;
     31 import java.util.Collection;
     32 import java.util.Collections;
     33 import java.util.Map.Entry;
     34 
     35 /**
     36  * Tests for {@link ImmutableSetMultimap}.
     37  *
     38  * @author Mike Ward
     39  */
     40 @GwtCompatible(emulated = true)
     41 public class ImmutableSetMultimapTest extends TestCase {
     42 
     43   public void testBuilder_withImmutableEntry() {
     44     ImmutableSetMultimap<String, Integer> multimap = new Builder<String, Integer>()
     45         .put(Maps.immutableEntry("one", 1))
     46         .build();
     47     assertEquals(ImmutableSet.of(1), multimap.get("one"));
     48   }
     49 
     50   public void testBuilder_withImmutableEntryAndNullContents() {
     51     Builder<String, Integer> builder = new Builder<String, Integer>();
     52     try {
     53       builder.put(Maps.immutableEntry("one", (Integer) null));
     54       fail();
     55     } catch (NullPointerException expected) {
     56     }
     57     try {
     58       builder.put(Maps.immutableEntry((String) null, 1));
     59       fail();
     60     } catch (NullPointerException expected) {
     61     }
     62   }
     63 
     64   private static class StringHolder {
     65     String string;
     66   }
     67 
     68   public void testBuilder_withMutableEntry() {
     69     ImmutableSetMultimap.Builder<String, Integer> builder =
     70         new Builder<String, Integer>();
     71     final StringHolder holder = new StringHolder();
     72     holder.string = "one";
     73     Entry<String, Integer> entry = new AbstractMapEntry<String, Integer>() {
     74       @Override public String getKey() {
     75         return holder.string;
     76       }
     77       @Override public Integer getValue() {
     78         return 1;
     79       }
     80     };
     81 
     82     builder.put(entry);
     83     holder.string = "two";
     84     assertEquals(ImmutableSet.of(1), builder.build().get("one"));
     85   }
     86 
     87   public void testBuilderPutAllIterable() {
     88     ImmutableSetMultimap.Builder<String, Integer> builder
     89         = ImmutableSetMultimap.builder();
     90     builder.putAll("foo", Arrays.asList(1, 2, 3));
     91     builder.putAll("bar", Arrays.asList(4, 5));
     92     builder.putAll("foo", Arrays.asList(6, 7));
     93     Multimap<String, Integer> multimap = builder.build();
     94     assertEquals(ImmutableSet.of(1, 2, 3, 6, 7), multimap.get("foo"));
     95     assertEquals(ImmutableSet.of(4, 5), multimap.get("bar"));
     96     assertEquals(7, multimap.size());
     97   }
     98 
     99   public void testBuilderPutAllVarargs() {
    100     ImmutableSetMultimap.Builder<String, Integer> builder
    101         = ImmutableSetMultimap.builder();
    102     builder.putAll("foo", 1, 2, 3);
    103     builder.putAll("bar", 4, 5);
    104     builder.putAll("foo", 6, 7);
    105     Multimap<String, Integer> multimap = builder.build();
    106     assertEquals(ImmutableSet.of(1, 2, 3, 6, 7), multimap.get("foo"));
    107     assertEquals(ImmutableSet.of(4, 5), multimap.get("bar"));
    108     assertEquals(7, multimap.size());
    109   }
    110 
    111   public void testBuilderPutAllMultimap() {
    112     Multimap<String, Integer> toPut = LinkedListMultimap.create();
    113     toPut.put("foo", 1);
    114     toPut.put("bar", 4);
    115     toPut.put("foo", 2);
    116     toPut.put("foo", 3);
    117     Multimap<String, Integer> moreToPut = LinkedListMultimap.create();
    118     moreToPut.put("foo", 6);
    119     moreToPut.put("bar", 5);
    120     moreToPut.put("foo", 7);
    121     ImmutableSetMultimap.Builder<String, Integer> builder
    122         = ImmutableSetMultimap.builder();
    123     builder.putAll(toPut);
    124     builder.putAll(moreToPut);
    125     Multimap<String, Integer> multimap = builder.build();
    126     assertEquals(ImmutableSet.of(1, 2, 3, 6, 7), multimap.get("foo"));
    127     assertEquals(ImmutableSet.of(4, 5), multimap.get("bar"));
    128     assertEquals(7, multimap.size());
    129   }
    130 
    131   public void testBuilderPutAllWithDuplicates() {
    132     ImmutableSetMultimap.Builder<String, Integer> builder
    133         = ImmutableSetMultimap.builder();
    134     builder.putAll("foo", 1, 2, 3);
    135     builder.putAll("bar", 4, 5);
    136     builder.putAll("foo", 1, 6, 7);
    137     ImmutableSetMultimap<String, Integer> multimap = builder.build();
    138     assertEquals(7, multimap.size());
    139   }
    140 
    141   public void testBuilderPutWithDuplicates() {
    142     ImmutableSetMultimap.Builder<String, Integer> builder
    143         = ImmutableSetMultimap.builder();
    144     builder.putAll("foo", 1, 2, 3);
    145     builder.putAll("bar", 4, 5);
    146     builder.put("foo", 1);
    147     ImmutableSetMultimap<String, Integer> multimap = builder.build();
    148     assertEquals(5, multimap.size());
    149   }
    150 
    151   public void testBuilderPutAllMultimapWithDuplicates() {
    152     Multimap<String, Integer> toPut = LinkedListMultimap.create();
    153     toPut.put("foo", 1);
    154     toPut.put("bar", 4);
    155     toPut.put("foo", 2);
    156     toPut.put("foo", 1);
    157     toPut.put("bar", 5);
    158     ImmutableSetMultimap.Builder<String, Integer> builder
    159         = ImmutableSetMultimap.builder();
    160     builder.putAll(toPut);
    161     ImmutableSetMultimap<String, Integer> multimap = builder.build();
    162     assertEquals(4, multimap.size());
    163   }
    164 
    165   public void testBuilderPutNullKey() {
    166     Multimap<String, Integer> toPut = LinkedListMultimap.create();
    167     toPut.put("foo", null);
    168     ImmutableSetMultimap.Builder<String, Integer> builder
    169         = ImmutableSetMultimap.builder();
    170     try {
    171       builder.put(null, 1);
    172       fail();
    173     } catch (NullPointerException expected) {}
    174     try {
    175       builder.putAll(null, Arrays.asList(1, 2, 3));
    176       fail();
    177     } catch (NullPointerException expected) {}
    178     try {
    179       builder.putAll(null, 1, 2, 3);
    180       fail();
    181     } catch (NullPointerException expected) {}
    182     try {
    183       builder.putAll(toPut);
    184       fail();
    185     } catch (NullPointerException expected) {}
    186   }
    187 
    188   public void testBuilderPutNullValue() {
    189     Multimap<String, Integer> toPut = LinkedListMultimap.create();
    190     toPut.put(null, 1);
    191     ImmutableSetMultimap.Builder<String, Integer> builder
    192         = ImmutableSetMultimap.builder();
    193     try {
    194       builder.put("foo", null);
    195       fail();
    196     } catch (NullPointerException expected) {}
    197     try {
    198       builder.putAll("foo", Arrays.asList(1, null, 3));
    199       fail();
    200     } catch (NullPointerException expected) {}
    201     try {
    202       builder.putAll("foo", 4, null, 6);
    203       fail();
    204     } catch (NullPointerException expected) {}
    205     try {
    206       builder.putAll(toPut);
    207       fail();
    208     } catch (NullPointerException expected) {}
    209   }
    210 
    211   public void testBuilderOrderKeysBy() {
    212     ImmutableSetMultimap.Builder<String, Integer> builder
    213         = ImmutableSetMultimap.builder();
    214     builder.put("b", 3);
    215     builder.put("d", 2);
    216     builder.put("a", 5);
    217     builder.orderKeysBy(Collections.reverseOrder());
    218     builder.put("c", 4);
    219     builder.put("a", 2);
    220     builder.put("b", 6);
    221     ImmutableSetMultimap<String, Integer> multimap = builder.build();
    222     ASSERT.that(multimap.keySet()).hasContentsInOrder("d", "c", "b", "a");
    223     ASSERT.that(multimap.values()).hasContentsInOrder(2, 4, 3, 6, 5, 2);
    224     ASSERT.that(multimap.get("a")).hasContentsInOrder(5, 2);
    225     ASSERT.that(multimap.get("b")).hasContentsInOrder(3, 6);
    226     assertFalse(multimap.get("a") instanceof ImmutableSortedSet);
    227     assertFalse(multimap.get("x") instanceof ImmutableSortedSet);
    228     assertFalse(multimap.asMap().get("a") instanceof ImmutableSortedSet);
    229   }
    230 
    231   public void testBuilderOrderValuesBy() {
    232     ImmutableSetMultimap.Builder<String, Integer> builder
    233         = ImmutableSetMultimap.builder();
    234     builder.put("b", 3);
    235     builder.put("d", 2);
    236     builder.put("a", 5);
    237     builder.orderValuesBy(Collections.reverseOrder());
    238     builder.put("c", 4);
    239     builder.put("a", 2);
    240     builder.put("b", 6);
    241     ImmutableSetMultimap<String, Integer> multimap = builder.build();
    242     ASSERT.that(multimap.keySet()).hasContentsInOrder("b", "d", "a", "c");
    243     ASSERT.that(multimap.values()).hasContentsInOrder(6, 3, 2, 5, 2, 4);
    244     ASSERT.that(multimap.get("a")).hasContentsInOrder(5, 2);
    245     ASSERT.that(multimap.get("b")).hasContentsInOrder(6, 3);
    246     assertTrue(multimap.get("a") instanceof ImmutableSortedSet);
    247     assertEquals(Collections.reverseOrder(),
    248         ((ImmutableSortedSet<Integer>) multimap.get("a")).comparator());
    249     assertTrue(multimap.get("x") instanceof ImmutableSortedSet);
    250     assertEquals(Collections.reverseOrder(),
    251         ((ImmutableSortedSet<Integer>) multimap.get("x")).comparator());
    252     assertTrue(multimap.asMap().get("a") instanceof ImmutableSortedSet);
    253     assertEquals(Collections.reverseOrder(),
    254         ((ImmutableSortedSet<Integer>) multimap.asMap().get("a")).comparator());
    255   }
    256 
    257   public void testBuilderOrderKeysAndValuesBy() {
    258     ImmutableSetMultimap.Builder<String, Integer> builder
    259         = ImmutableSetMultimap.builder();
    260     builder.put("b", 3);
    261     builder.put("d", 2);
    262     builder.put("a", 5);
    263     builder.orderKeysBy(Collections.reverseOrder());
    264     builder.orderValuesBy(Collections.reverseOrder());
    265     builder.put("c", 4);
    266     builder.put("a", 2);
    267     builder.put("b", 6);
    268     ImmutableSetMultimap<String, Integer> multimap = builder.build();
    269     ASSERT.that(multimap.keySet()).hasContentsInOrder("d", "c", "b", "a");
    270     ASSERT.that(multimap.values()).hasContentsInOrder(2, 4, 6, 3, 5, 2);
    271     ASSERT.that(multimap.get("a")).hasContentsInOrder(5, 2);
    272     ASSERT.that(multimap.get("b")).hasContentsInOrder(6, 3);
    273     assertTrue(multimap.get("a") instanceof ImmutableSortedSet);
    274     assertEquals(Collections.reverseOrder(),
    275         ((ImmutableSortedSet<Integer>) multimap.get("a")).comparator());
    276     assertTrue(multimap.get("x") instanceof ImmutableSortedSet);
    277     assertEquals(Collections.reverseOrder(),
    278         ((ImmutableSortedSet<Integer>) multimap.get("x")).comparator());
    279     assertTrue(multimap.asMap().get("a") instanceof ImmutableSortedSet);
    280     assertEquals(Collections.reverseOrder(),
    281         ((ImmutableSortedSet<Integer>) multimap.asMap().get("a")).comparator());
    282   }
    283 
    284   public void testCopyOf() {
    285     HashMultimap<String, Integer> input = HashMultimap.create();
    286     input.put("foo", 1);
    287     input.put("bar", 2);
    288     input.put("foo", 3);
    289     Multimap<String, Integer> multimap = ImmutableSetMultimap.copyOf(input);
    290     assertEquals(multimap, input);
    291     assertEquals(input, multimap);
    292   }
    293 
    294   public void testCopyOfWithDuplicates() {
    295     ArrayListMultimap<Object, Object> input = ArrayListMultimap.create();
    296     input.put("foo", 1);
    297     input.put("bar", 2);
    298     input.put("foo", 3);
    299     input.put("foo", 1);
    300     ImmutableSetMultimap<Object, Object> copy
    301         = ImmutableSetMultimap.copyOf(input);
    302     assertEquals(3, copy.size());
    303   }
    304 
    305   public void testCopyOfEmpty() {
    306     HashMultimap<String, Integer> input = HashMultimap.create();
    307     Multimap<String, Integer> multimap = ImmutableSetMultimap.copyOf(input);
    308     assertEquals(multimap, input);
    309     assertEquals(input, multimap);
    310   }
    311 
    312   public void testCopyOfImmutableSetMultimap() {
    313     Multimap<String, Integer> multimap = createMultimap();
    314     assertSame(multimap, ImmutableSetMultimap.copyOf(multimap));
    315   }
    316 
    317   public void testCopyOfNullKey() {
    318     HashMultimap<String, Integer> input = HashMultimap.create();
    319     input.put(null, 1);
    320     try {
    321       ImmutableSetMultimap.copyOf(input);
    322       fail();
    323     } catch (NullPointerException expected) {}
    324   }
    325 
    326   public void testCopyOfNullValue() {
    327     HashMultimap<String, Integer> input = HashMultimap.create();
    328     input.putAll("foo", Arrays.asList(1, null, 3));
    329     try {
    330       ImmutableSetMultimap.copyOf(input);
    331       fail();
    332     } catch (NullPointerException expected) {}
    333   }
    334 
    335   public void testEmptyMultimapReads() {
    336     Multimap<String, Integer> multimap = ImmutableSetMultimap.of();
    337     assertFalse(multimap.containsKey("foo"));
    338     assertFalse(multimap.containsValue(1));
    339     assertFalse(multimap.containsEntry("foo", 1));
    340     assertTrue(multimap.entries().isEmpty());
    341     assertTrue(multimap.equals(HashMultimap.create()));
    342     assertEquals(Collections.emptySet(), multimap.get("foo"));
    343     assertEquals(0, multimap.hashCode());
    344     assertTrue(multimap.isEmpty());
    345     assertEquals(HashMultiset.create(), multimap.keys());
    346     assertEquals(Collections.emptySet(), multimap.keySet());
    347     assertEquals(0, multimap.size());
    348     assertTrue(multimap.values().isEmpty());
    349     assertEquals("{}", multimap.toString());
    350   }
    351 
    352   public void testEmptyMultimapWrites() {
    353     Multimap<String, Integer> multimap = ImmutableSetMultimap.of();
    354     UnmodifiableCollectionTests.assertMultimapIsUnmodifiable(
    355         multimap, "foo", 1);
    356   }
    357 
    358   public void testMultimapReads() {
    359     Multimap<String, Integer> multimap = createMultimap();
    360     assertTrue(multimap.containsKey("foo"));
    361     assertFalse(multimap.containsKey("cat"));
    362     assertTrue(multimap.containsValue(1));
    363     assertFalse(multimap.containsValue(5));
    364     assertTrue(multimap.containsEntry("foo", 1));
    365     assertFalse(multimap.containsEntry("cat", 1));
    366     assertFalse(multimap.containsEntry("foo", 5));
    367     assertFalse(multimap.entries().isEmpty());
    368     assertEquals(3, multimap.size());
    369     assertFalse(multimap.isEmpty());
    370     assertEquals("{foo=[1, 3], bar=[2]}", multimap.toString());
    371   }
    372 
    373   public void testMultimapWrites() {
    374     Multimap<String, Integer> multimap = createMultimap();
    375     UnmodifiableCollectionTests.assertMultimapIsUnmodifiable(
    376         multimap, "bar", 2);
    377   }
    378 
    379   public void testMultimapEquals() {
    380     Multimap<String, Integer> multimap = createMultimap();
    381     Multimap<String, Integer> hashMultimap = HashMultimap.create();
    382     hashMultimap.putAll("foo", Arrays.asList(1, 3));
    383     hashMultimap.put("bar", 2);
    384 
    385     new EqualsTester()
    386         .addEqualityGroup(
    387             multimap,
    388             createMultimap(),
    389             hashMultimap,
    390             ImmutableSetMultimap.<String, Integer>builder()
    391                 .put("bar", 2).put("foo", 1).put("foo", 3).build(),
    392             ImmutableSetMultimap.<String, Integer>builder()
    393                 .put("bar", 2).put("foo", 3).put("foo", 1).build())
    394         .addEqualityGroup(ImmutableSetMultimap.<String, Integer>builder()
    395             .put("foo", 2).put("foo", 3).put("foo", 1).build())
    396         .addEqualityGroup(ImmutableSetMultimap.<String, Integer>builder()
    397             .put("bar", 2).put("foo", 3).build())
    398         .testEquals();
    399   }
    400 
    401   public void testOf() {
    402     assertMultimapEquals(
    403         ImmutableSetMultimap.of("one", 1),
    404         "one", 1);
    405     assertMultimapEquals(
    406         ImmutableSetMultimap.of("one", 1, "two", 2),
    407         "one", 1, "two", 2);
    408     assertMultimapEquals(
    409         ImmutableSetMultimap.of("one", 1, "two", 2, "three", 3),
    410         "one", 1, "two", 2, "three", 3);
    411     assertMultimapEquals(
    412         ImmutableSetMultimap.of("one", 1, "two", 2, "three", 3, "four", 4),
    413         "one", 1, "two", 2, "three", 3, "four", 4);
    414     assertMultimapEquals(
    415         ImmutableSetMultimap.of(
    416             "one", 1, "two", 2, "three", 3, "four", 4, "five", 5),
    417         "one", 1, "two", 2, "three", 3, "four", 4, "five", 5);
    418   }
    419 
    420   public void testInverse() {
    421     assertEquals(
    422         ImmutableSetMultimap.<Integer, String>of(),
    423         ImmutableSetMultimap.<String, Integer>of().inverse());
    424     assertEquals(
    425         ImmutableSetMultimap.of(1, "one"),
    426         ImmutableSetMultimap.of("one", 1).inverse());
    427     assertEquals(
    428         ImmutableSetMultimap.of(1, "one", 2, "two"),
    429         ImmutableSetMultimap.of("one", 1, "two", 2).inverse());
    430     assertEquals(
    431         ImmutableSetMultimap.of('o', "of", 'f', "of", 't', "to", 'o', "to"),
    432         ImmutableSetMultimap.of("of", 'o', "of", 'f', "to", 't', "to", 'o').inverse());
    433   }
    434 
    435   public void testInverseMinimizesWork() {
    436     ImmutableSetMultimap<String, Character> multimap =
    437         ImmutableSetMultimap.of("of", 'o', "of", 'f', "to", 't', "to", 'o');
    438     assertSame(multimap.inverse(), multimap.inverse());
    439     assertSame(multimap, multimap.inverse().inverse());
    440   }
    441 
    442   private static <K, V> void assertMultimapEquals(Multimap<K, V> multimap,
    443       Object... alternatingKeysAndValues) {
    444     assertEquals(multimap.size(), alternatingKeysAndValues.length / 2);
    445     int i = 0;
    446     for (Entry<K, V> entry : multimap.entries()) {
    447       assertEquals(alternatingKeysAndValues[i++], entry.getKey());
    448       assertEquals(alternatingKeysAndValues[i++], entry.getValue());
    449     }
    450   }
    451 
    452   @GwtIncompatible("SerializableTester")
    453   public void testSerialization() {
    454     Multimap<String, Integer> multimap = createMultimap();
    455     SerializableTester.reserializeAndAssert(multimap);
    456     assertEquals(multimap.size(),
    457         SerializableTester.reserialize(multimap).size());
    458     SerializableTester.reserializeAndAssert(multimap.get("foo"));
    459     LenientSerializableTester.reserializeAndAssertLenient(multimap.keySet());
    460     SerializableTester.reserializeAndAssert(multimap.keys());
    461     SerializableTester.reserializeAndAssert(multimap.asMap());
    462     Collection<Integer> valuesCopy
    463         = SerializableTester.reserialize(multimap.values());
    464     assertEquals(HashMultiset.create(multimap.values()),
    465         HashMultiset.create(valuesCopy));
    466   }
    467 
    468   @GwtIncompatible("SerializableTester")
    469   public void testEmptySerialization() {
    470     Multimap<String, Integer> multimap = ImmutableSetMultimap.of();
    471     assertSame(multimap, SerializableTester.reserialize(multimap));
    472   }
    473 
    474   private ImmutableSetMultimap<String, Integer> createMultimap() {
    475     return ImmutableSetMultimap.<String, Integer>builder()
    476         .put("foo", 1).put("bar", 2).put("foo", 3).build();
    477   }
    478 }
    479