View Javadoc
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.truth.Truth.assertThat;
20  import static java.util.Arrays.asList;
21  
22  import com.google.common.annotations.GwtCompatible;
23  import com.google.common.testing.EqualsTester;
24  
25  import junit.framework.TestCase;
26  
27  import java.util.Arrays;
28  import java.util.Collection;
29  import java.util.Collections;
30  import java.util.Iterator;
31  import java.util.List;
32  import java.util.Map;
33  import java.util.RandomAccess;
34  
35  /**
36   * Tests for {@code LinkedListMultimap}.
37   *
38   * @author Mike Bostock
39   */
40  @GwtCompatible(emulated = true)
41  public class LinkedListMultimapTest extends TestCase {
42  
43    protected LinkedListMultimap<String, Integer> create() {
44      return LinkedListMultimap.create();
45    }
46  
47    /**
48     * Confirm that get() returns a List that doesn't implement RandomAccess.
49     */
50    public void testGetRandomAccess() {
51      Multimap<String, Integer> multimap = create();
52      multimap.put("foo", 1);
53      multimap.put("foo", 3);
54      assertFalse(multimap.get("foo") instanceof RandomAccess);
55      assertFalse(multimap.get("bar") instanceof RandomAccess);
56    }
57  
58    /**
59     * Confirm that removeAll() returns a List that implements RandomAccess, even
60     * though get() doesn't.
61     */
62    public void testRemoveAllRandomAccess() {
63      Multimap<String, Integer> multimap = create();
64      multimap.put("foo", 1);
65      multimap.put("foo", 3);
66      assertTrue(multimap.removeAll("foo") instanceof RandomAccess);
67      assertTrue(multimap.removeAll("bar") instanceof RandomAccess);
68    }
69  
70    /**
71     * Confirm that replaceValues() returns a List that implements RandomAccess,
72     * even though get() doesn't.
73     */
74    public void testReplaceValuesRandomAccess() {
75      Multimap<String, Integer> multimap = create();
76      multimap.put("foo", 1);
77      multimap.put("foo", 3);
78      assertTrue(multimap.replaceValues("foo", Arrays.asList(2, 4))
79          instanceof RandomAccess);
80      assertTrue(multimap.replaceValues("bar", Arrays.asList(2, 4))
81          instanceof RandomAccess);
82    }
83  
84    public void testCreateFromMultimap() {
85      Multimap<String, Integer> multimap = LinkedListMultimap.create();
86      multimap.put("foo", 1);
87      multimap.put("bar", 3);
88      multimap.put("foo", 2);
89      LinkedListMultimap<String, Integer> copy =
90          LinkedListMultimap.create(multimap);
91      assertEquals(multimap, copy);
92      assertThat(copy.entries()).has().exactlyAs(multimap.entries()).inOrder();
93    }
94  
95    public void testCreateFromSize() {
96      LinkedListMultimap<String, Integer> multimap
97          = LinkedListMultimap.create(20);
98      multimap.put("foo", 1);
99      multimap.put("bar", 2);
100     multimap.put("foo", 3);
101     assertEquals(ImmutableList.of(1, 3), multimap.get("foo"));
102   }
103 
104   public void testCreateFromIllegalSize() {
105     try {
106       LinkedListMultimap.create(-20);
107       fail();
108     } catch (IllegalArgumentException expected) {}
109   }
110 
111   public void testLinkedGetAdd() {
112     LinkedListMultimap<String, Integer> map = create();
113     map.put("bar", 1);
114     Collection<Integer> foos = map.get("foo");
115     foos.add(2);
116     foos.add(3);
117     map.put("bar", 4);
118     map.put("foo", 5);
119     assertEquals("{bar=[1, 4], foo=[2, 3, 5]}", map.toString());
120     assertEquals("[bar=1, foo=2, foo=3, bar=4, foo=5]",
121         map.entries().toString());
122   }
123 
124   public void testLinkedGetInsert() {
125     ListMultimap<String, Integer> map = create();
126     map.put("bar", 1);
127     List<Integer> foos = map.get("foo");
128     foos.add(2);
129     foos.add(0, 3);
130     map.put("bar", 4);
131     map.put("foo", 5);
132     assertEquals("{bar=[1, 4], foo=[3, 2, 5]}", map.toString());
133     assertEquals("[bar=1, foo=3, foo=2, bar=4, foo=5]",
134         map.entries().toString());
135   }
136 
137   public void testLinkedPutInOrder() {
138     Multimap<String, Integer> map = create();
139     map.put("foo", 1);
140     map.put("bar", 2);
141     map.put("bar", 3);
142     assertEquals("{foo=[1], bar=[2, 3]}", map.toString());
143     assertEquals("[foo=1, bar=2, bar=3]", map.entries().toString());
144   }
145 
146   public void testLinkedPutOutOfOrder() {
147     Multimap<String, Integer> map = create();
148     map.put("bar", 1);
149     map.put("foo", 2);
150     map.put("bar", 3);
151     assertEquals("{bar=[1, 3], foo=[2]}", map.toString());
152     assertEquals("[bar=1, foo=2, bar=3]", map.entries().toString());
153   }
154 
155   public void testLinkedPutAllMultimap() {
156     Multimap<String, Integer> src = create();
157     src.put("bar", 1);
158     src.put("foo", 2);
159     src.put("bar", 3);
160     Multimap<String, Integer> dst = create();
161     dst.putAll(src);
162     assertEquals("{bar=[1, 3], foo=[2]}", dst.toString());
163     assertEquals("[bar=1, foo=2, bar=3]", src.entries().toString());
164   }
165 
166   public void testLinkedReplaceValues() {
167     Multimap<String, Integer> map = create();
168     map.put("bar", 1);
169     map.put("foo", 2);
170     map.put("bar", 3);
171     map.put("bar", 4);
172     assertEquals("{bar=[1, 3, 4], foo=[2]}", map.toString());
173     map.replaceValues("bar", asList(1, 2));
174     assertEquals("[bar=1, foo=2, bar=2]", map.entries().toString());
175     assertEquals("{bar=[1, 2], foo=[2]}", map.toString());
176   }
177 
178   public void testLinkedClear() {
179     ListMultimap<String, Integer> map = create();
180     map.put("foo", 1);
181     map.put("foo", 2);
182     map.put("bar", 3);
183     List<Integer> foos = map.get("foo");
184     Collection<Integer> values = map.values();
185     assertEquals(asList(1, 2), foos);
186     assertThat(values).has().exactly(1, 2, 3).inOrder();
187     map.clear();
188     assertEquals(Collections.emptyList(), foos);
189     assertThat(values).isEmpty();
190     assertEquals("[]", map.entries().toString());
191     assertEquals("{}", map.toString());
192   }
193 
194   public void testLinkedKeySet() {
195     Multimap<String, Integer> map = create();
196     map.put("bar", 1);
197     map.put("foo", 2);
198     map.put("bar", 3);
199     map.put("bar", 4);
200     assertEquals("[bar, foo]", map.keySet().toString());
201     map.keySet().remove("bar");
202     assertEquals("{foo=[2]}", map.toString());
203   }
204 
205   public void testLinkedKeys() {
206     Multimap<String, Integer> map = create();
207     map.put("bar", 1);
208     map.put("foo", 2);
209     map.put("bar", 3);
210     map.put("bar", 4);
211     assertEquals("[bar=1, foo=2, bar=3, bar=4]",
212         map.entries().toString());
213     assertThat(map.keys()).has().exactly("bar", "foo", "bar", "bar").inOrder();
214     map.keys().remove("bar"); // bar is no longer the first key!
215     assertEquals("{foo=[2], bar=[3, 4]}", map.toString());
216   }
217 
218   public void testLinkedValues() {
219     Multimap<String, Integer> map = create();
220     map.put("bar", 1);
221     map.put("foo", 2);
222     map.put("bar", 3);
223     map.put("bar", 4);
224     assertEquals("[1, 2, 3, 4]", map.values().toString());
225     map.values().remove(2);
226     assertEquals("{bar=[1, 3, 4]}", map.toString());
227   }
228 
229   public void testLinkedEntries() {
230     Multimap<String, Integer> map = create();
231     map.put("bar", 1);
232     map.put("foo", 2);
233     map.put("bar", 3);
234     Iterator<Map.Entry<String, Integer>> entries = map.entries().iterator();
235     Map.Entry<String, Integer> entry = entries.next();
236     assertEquals("bar", entry.getKey());
237     assertEquals(1, (int) entry.getValue());
238     entry = entries.next();
239     assertEquals("foo", entry.getKey());
240     assertEquals(2, (int) entry.getValue());
241     entry.setValue(4);
242     entry = entries.next();
243     assertEquals("bar", entry.getKey());
244     assertEquals(3, (int) entry.getValue());
245     assertFalse(entries.hasNext());
246     entries.remove();
247     assertEquals("{bar=[1], foo=[4]}", map.toString());
248   }
249 
250   public void testLinkedAsMapEntries() {
251     Multimap<String, Integer> map = create();
252     map.put("bar", 1);
253     map.put("foo", 2);
254     map.put("bar", 3);
255     Iterator<Map.Entry<String, Collection<Integer>>> entries
256         = map.asMap().entrySet().iterator();
257     Map.Entry<String, Collection<Integer>> entry = entries.next();
258     assertEquals("bar", entry.getKey());
259     assertThat(entry.getValue()).has().exactly(1, 3).inOrder();
260     try {
261       entry.setValue(Arrays.<Integer>asList());
262       fail("UnsupportedOperationException expected");
263     } catch (UnsupportedOperationException expected) {}
264     entries.remove(); // clear
265     entry = entries.next();
266     assertEquals("foo", entry.getKey());
267     assertThat(entry.getValue()).has().item(2);
268     assertFalse(entries.hasNext());
269     assertEquals("{foo=[2]}", map.toString());
270   }
271 
272   public void testEntriesAfterMultimapUpdate() {
273     ListMultimap<String, Integer> multimap = create();
274     multimap.put("foo", 2);
275     multimap.put("bar", 3);
276     Collection<Map.Entry<String, Integer>> entries = multimap.entries();
277     Iterator<Map.Entry<String, Integer>> iterator = entries.iterator();
278     Map.Entry<String, Integer> entrya = iterator.next();
279     Map.Entry<String, Integer> entryb = iterator.next();
280 
281     assertEquals(2, (int) multimap.get("foo").set(0, 4));
282     assertFalse(multimap.containsEntry("foo", 2));
283     assertTrue(multimap.containsEntry("foo", 4));
284     assertTrue(multimap.containsEntry("bar", 3));
285     assertEquals(4, (int) entrya.getValue());
286     assertEquals(3, (int) entryb.getValue());
287 
288     assertTrue(multimap.put("foo", 5));
289     assertTrue(multimap.containsEntry("foo", 5));
290     assertTrue(multimap.containsEntry("foo", 4));
291     assertTrue(multimap.containsEntry("bar", 3));
292     assertEquals(4, (int) entrya.getValue());
293     assertEquals(3, (int) entryb.getValue());
294   }
295 
296   public void testEquals() {
297     new EqualsTester()
298         .addEqualityGroup(
299             LinkedListMultimap.create(),
300             LinkedListMultimap.create(),
301             LinkedListMultimap.create(1))
302         .testEquals();
303   }
304 }
305