Home | History | Annotate | Download | only in collect
      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 
     17 package com.google.common.collect;
     18 
     19 import static com.google.common.collect.Lists.newArrayList;
     20 import static com.google.common.collect.Sets.newHashSet;
     21 import static com.google.common.collect.Sets.newLinkedHashSet;
     22 import static com.google.common.collect.testing.IteratorFeature.MODIFIABLE;
     23 import static java.util.Arrays.asList;
     24 import static org.junit.contrib.truth.Truth.ASSERT;
     25 
     26 import com.google.common.annotations.GwtCompatible;
     27 import com.google.common.annotations.GwtIncompatible;
     28 import com.google.common.collect.testing.IteratorTester;
     29 import com.google.common.testing.SerializableTester;
     30 
     31 import java.util.Collection;
     32 import java.util.Iterator;
     33 import java.util.List;
     34 import java.util.Map;
     35 import java.util.Map.Entry;
     36 import java.util.Set;
     37 
     38 /**
     39  * Unit tests for {@code LinkedHashMultimap}.
     40  *
     41  * @author Jared Levy
     42  */
     43 @GwtCompatible(emulated = true)
     44 public class LinkedHashMultimapTest extends AbstractSetMultimapTest {
     45 
     46   @Override protected Multimap<String, Integer> create() {
     47     return LinkedHashMultimap.create();
     48   }
     49 
     50   private Multimap<String, Integer> initializeMultimap5() {
     51     Multimap<String, Integer> multimap = getMultimap();
     52     multimap.put("foo", 5);
     53     multimap.put("bar", 4);
     54     multimap.put("foo", 3);
     55     multimap.put("cow", 2);
     56     multimap.put("bar", 1);
     57     return multimap;
     58   }
     59 
     60   public void testToString() {
     61     assertEquals("{foo=[3, -1, 2, 4, 1], bar=[1, 2, 3]}",
     62         createSample().toString());
     63   }
     64 
     65   public void testOrderingReadOnly() {
     66     Multimap<String, Integer> multimap = initializeMultimap5();
     67     assertOrderingReadOnly(multimap);
     68   }
     69 
     70   public void testOrderingUnmodifiable() {
     71     Multimap<String, Integer> multimap = initializeMultimap5();
     72     assertOrderingReadOnly(Multimaps.unmodifiableMultimap(multimap));
     73   }
     74 
     75   public void testOrderingSynchronized() {
     76     Multimap<String, Integer> multimap = initializeMultimap5();
     77     assertOrderingReadOnly(Multimaps.synchronizedMultimap(multimap));
     78   }
     79 
     80   @GwtIncompatible("SeriazableTester")
     81   public void testSerializationOrdering() {
     82     Multimap<String, Integer> multimap = initializeMultimap5();
     83     Multimap<String, Integer> copy
     84         = SerializableTester.reserializeAndAssert(multimap);
     85     assertOrderingReadOnly(copy);
     86   }
     87 
     88   private void assertOrderingReadOnly(Multimap<String, Integer> multimap) {
     89     ASSERT.that(multimap.get("foo")).hasContentsInOrder(5, 3);
     90     ASSERT.that(multimap.get("bar")).hasContentsInOrder(4, 1);
     91     ASSERT.that(multimap.get("cow")).hasContentsInOrder(2);
     92 
     93     ASSERT.that(multimap.keySet()).hasContentsInOrder("foo", "bar", "cow");
     94     ASSERT.that(multimap.values()).hasContentsInOrder(5, 4, 3, 2, 1);
     95 
     96     Iterator<Map.Entry<String, Integer>> entryIterator =
     97         multimap.entries().iterator();
     98     assertEquals(Maps.immutableEntry("foo", 5), entryIterator.next());
     99     assertEquals(Maps.immutableEntry("bar", 4), entryIterator.next());
    100     assertEquals(Maps.immutableEntry("foo", 3), entryIterator.next());
    101     assertEquals(Maps.immutableEntry("cow", 2), entryIterator.next());
    102     assertEquals(Maps.immutableEntry("bar", 1), entryIterator.next());
    103 
    104     Iterator<Map.Entry<String, Collection<Integer>>> collectionIterator =
    105         multimap.asMap().entrySet().iterator();
    106     Map.Entry<String, Collection<Integer>> entry = collectionIterator.next();
    107     assertEquals("foo", entry.getKey());
    108     ASSERT.that(entry.getValue()).hasContentsInOrder(5, 3);
    109     entry = collectionIterator.next();
    110     assertEquals("bar", entry.getKey());
    111     ASSERT.that(entry.getValue()).hasContentsInOrder(4, 1);
    112     entry = collectionIterator.next();
    113     assertEquals("cow", entry.getKey());
    114     ASSERT.that(entry.getValue()).hasContentsInOrder(2);
    115   }
    116 
    117   public void testOrderingUpdates() {
    118     Multimap<String, Integer> multimap = initializeMultimap5();
    119 
    120     ASSERT.that(multimap.replaceValues("foo", asList(6, 7))).hasContentsInOrder(5, 3);
    121     ASSERT.that(multimap.keySet()).hasContentsInOrder("foo", "bar", "cow");
    122     ASSERT.that(multimap.removeAll("foo")).hasContentsInOrder(6, 7);
    123     ASSERT.that(multimap.keySet()).hasContentsInOrder("bar", "cow");
    124     assertTrue(multimap.remove("bar", 4));
    125     ASSERT.that(multimap.keySet()).hasContentsInOrder("bar", "cow");
    126     assertTrue(multimap.remove("bar", 1));
    127     ASSERT.that(multimap.keySet()).hasContentsInOrder("cow");
    128     multimap.put("bar", 9);
    129     ASSERT.that(multimap.keySet()).hasContentsInOrder("cow", "bar");
    130   }
    131 
    132   public void testToStringNullExact() {
    133     Multimap<String, Integer> multimap = getMultimap();
    134 
    135     multimap.put("foo", 3);
    136     multimap.put("foo", -1);
    137     multimap.put(null, null);
    138     multimap.put("bar", 1);
    139     multimap.put("foo", 2);
    140     multimap.put(null, 0);
    141     multimap.put("bar", 2);
    142     multimap.put("bar", null);
    143     multimap.put("foo", null);
    144     multimap.put("foo", 4);
    145     multimap.put(null, -1);
    146     multimap.put("bar", 3);
    147     multimap.put("bar", 1);
    148     multimap.put("foo", 1);
    149 
    150     assertEquals(
    151         "{foo=[3, -1, 2, null, 4, 1], null=[null, 0, -1], bar=[1, 2, null, 3]}",
    152         multimap.toString());
    153   }
    154 
    155   public void testPutMultimapOrdered() {
    156     Multimap<String, Integer> multimap = LinkedHashMultimap.create();
    157     multimap.putAll(initializeMultimap5());
    158     assertOrderingReadOnly(multimap);
    159   }
    160 
    161   public void testKeysToString_ordering() {
    162     Multimap<String, Integer> multimap = initializeMultimap5();
    163     assertEquals("[foo x 2, bar x 2, cow]", multimap.keys().toString());
    164   }
    165 
    166   public void testCreate() {
    167     LinkedHashMultimap<String, Integer> multimap = LinkedHashMultimap.create();
    168     multimap.put("foo", 1);
    169     multimap.put("bar", 2);
    170     multimap.put("foo", 3);
    171     assertEquals(ImmutableSet.of(1, 3), multimap.get("foo"));
    172     assertEquals(8, multimap.expectedValuesPerKey);
    173   }
    174 
    175   public void testCreateFromMultimap() {
    176     Multimap<String, Integer> multimap = createSample();
    177     LinkedHashMultimap<String, Integer> copy =
    178         LinkedHashMultimap.create(multimap);
    179     assertEquals(multimap, copy);
    180     assertEquals(8, copy.expectedValuesPerKey);
    181   }
    182 
    183   public void testCreateFromSizes() {
    184     LinkedHashMultimap<String, Integer> multimap
    185         = LinkedHashMultimap.create(20, 15);
    186     multimap.put("foo", 1);
    187     multimap.put("bar", 2);
    188     multimap.put("foo", 3);
    189     assertEquals(ImmutableSet.of(1, 3), multimap.get("foo"));
    190     assertEquals(15, multimap.expectedValuesPerKey);
    191   }
    192 
    193   public void testCreateFromIllegalSizes() {
    194     try {
    195       LinkedHashMultimap.create(-20, 15);
    196       fail();
    197     } catch (IllegalArgumentException expected) {}
    198 
    199     try {
    200       LinkedHashMultimap.create(20, -15);
    201       fail();
    202     } catch (IllegalArgumentException expected) {}
    203   }
    204 
    205   @GwtIncompatible("unreasonable slow")
    206   public void testGetIteration() {
    207     new IteratorTester<Integer>(6, MODIFIABLE,
    208         newLinkedHashSet(asList(2, 3, 4, 7, 8)),
    209         IteratorTester.KnownOrder.KNOWN_ORDER) {
    210       private Multimap<String, Integer> multimap;
    211 
    212       @Override protected Iterator<Integer> newTargetIterator() {
    213         multimap = create();
    214         multimap.putAll("foo", asList(2, 3, 4));
    215         multimap.putAll("bar", asList(5, 6));
    216         multimap.putAll("foo", asList(7, 8));
    217         return multimap.get("foo").iterator();
    218       }
    219 
    220       @Override protected void verify(List<Integer> elements) {
    221         assertEquals(newHashSet(elements), multimap.get("foo"));
    222       }
    223     }.test();
    224   }
    225 
    226   @GwtIncompatible("unreasonable slow")
    227   public void testEntriesIteration() {
    228     @SuppressWarnings("unchecked")
    229     Set<Entry<String, Integer>> set = Sets.newLinkedHashSet(asList(
    230         Maps.immutableEntry("foo", 2),
    231         Maps.immutableEntry("foo", 3),
    232         Maps.immutableEntry("bar", 4),
    233         Maps.immutableEntry("bar", 5),
    234         Maps.immutableEntry("foo", 6)));
    235 
    236     new IteratorTester<Entry<String, Integer>>(6, MODIFIABLE, set,
    237         IteratorTester.KnownOrder.KNOWN_ORDER) {
    238       private Multimap<String, Integer> multimap;
    239 
    240       @Override protected Iterator<Entry<String, Integer>> newTargetIterator() {
    241         multimap = create();
    242         multimap.putAll("foo", asList(2, 3));
    243         multimap.putAll("bar", asList(4, 5));
    244         multimap.putAll("foo", asList(6));
    245         return multimap.entries().iterator();
    246       }
    247 
    248       @Override protected void verify(List<Entry<String, Integer>> elements) {
    249         assertEquals(newHashSet(elements), multimap.entries());
    250       }
    251     }.test();
    252   }
    253 
    254   @GwtIncompatible("unreasonable slow")
    255   public void testKeysIteration() {
    256     new IteratorTester<String>(6, MODIFIABLE, newArrayList("foo", "foo", "bar",
    257         "bar", "foo"), IteratorTester.KnownOrder.KNOWN_ORDER) {
    258       private Multimap<String, Integer> multimap;
    259 
    260       @Override protected Iterator<String> newTargetIterator() {
    261         multimap = create();
    262         multimap.putAll("foo", asList(2, 3));
    263         multimap.putAll("bar", asList(4, 5));
    264         multimap.putAll("foo", asList(6));
    265         return multimap.keys().iterator();
    266       }
    267 
    268       @Override protected void verify(List<String> elements) {
    269         assertEquals(elements, Lists.newArrayList(multimap.keys()));
    270       }
    271     }.test();
    272   }
    273 
    274   @GwtIncompatible("unreasonable slow")
    275   public void testValuesIteration() {
    276     new IteratorTester<Integer>(6, MODIFIABLE, newArrayList(2, 3, 4, 5, 6),
    277         IteratorTester.KnownOrder.KNOWN_ORDER) {
    278       private Multimap<String, Integer> multimap;
    279 
    280       @Override protected Iterator<Integer> newTargetIterator() {
    281         multimap = create();
    282         multimap.putAll("foo", asList(2, 3));
    283         multimap.putAll("bar", asList(4, 5));
    284         multimap.putAll("foo", asList(6));
    285         return multimap.values().iterator();
    286       }
    287 
    288       @Override protected void verify(List<Integer> elements) {
    289         assertEquals(elements, Lists.newArrayList(multimap.values()));
    290       }
    291     }.test();
    292   }
    293 
    294   @GwtIncompatible("unreasonable slow")
    295   public void testKeySetIteration() {
    296     new IteratorTester<String>(6, MODIFIABLE, newLinkedHashSet(asList(
    297         "foo", "bar", "baz", "dog", "cat")),
    298         IteratorTester.KnownOrder.KNOWN_ORDER) {
    299       private Multimap<String, Integer> multimap;
    300 
    301       @Override protected Iterator<String> newTargetIterator() {
    302         multimap = create();
    303         multimap.putAll("foo", asList(2, 3));
    304         multimap.putAll("bar", asList(4, 5));
    305         multimap.putAll("foo", asList(6));
    306         multimap.putAll("baz", asList(7, 8));
    307         multimap.putAll("dog", asList(9));
    308         multimap.putAll("bar", asList(10, 11));
    309         multimap.putAll("cat", asList(12, 13, 14));
    310         return multimap.keySet().iterator();
    311       }
    312 
    313       @Override protected void verify(List<String> elements) {
    314         assertEquals(newHashSet(elements), multimap.keySet());
    315       }
    316     }.test();
    317   }
    318 
    319   @GwtIncompatible("unreasonable slow")
    320   public void testAsSetIteration() {
    321     @SuppressWarnings("unchecked")
    322     Set<Entry<String, Collection<Integer>>> set = newLinkedHashSet(asList(
    323         Maps.immutableEntry("foo",
    324             (Collection<Integer>) Sets.newHashSet(2, 3, 6)),
    325         Maps.immutableEntry("bar",
    326             (Collection<Integer>) Sets.newHashSet(4, 5, 10, 11)),
    327         Maps.immutableEntry("baz",
    328             (Collection<Integer>) Sets.newHashSet(7, 8)),
    329         Maps.immutableEntry("dog",
    330             (Collection<Integer>) Sets.newHashSet(9)),
    331         Maps.immutableEntry("cat",
    332             (Collection<Integer>) Sets.newHashSet(12, 13, 14))
    333     ));
    334     new IteratorTester<Entry<String, Collection<Integer>>>(6, MODIFIABLE, set,
    335         IteratorTester.KnownOrder.KNOWN_ORDER) {
    336       private Multimap<String, Integer> multimap;
    337 
    338       @Override protected Iterator<Entry<String, Collection<Integer>>>
    339           newTargetIterator() {
    340         multimap = create();
    341         multimap.putAll("foo", asList(2, 3));
    342         multimap.putAll("bar", asList(4, 5));
    343         multimap.putAll("foo", asList(6));
    344         multimap.putAll("baz", asList(7, 8));
    345         multimap.putAll("dog", asList(9));
    346         multimap.putAll("bar", asList(10, 11));
    347         multimap.putAll("cat", asList(12, 13, 14));
    348         return multimap.asMap().entrySet().iterator();
    349       }
    350 
    351       @Override protected void verify(
    352           List<Entry<String, Collection<Integer>>> elements) {
    353         assertEquals(newHashSet(elements), multimap.asMap().entrySet());
    354       }
    355     }.test();
    356   }
    357 
    358 }
    359