View Javadoc
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.base.Preconditions.checkArgument;
20  import static com.google.common.truth.Truth.assertThat;
21  import static java.util.Arrays.asList;
22  
23  import com.google.common.annotations.GwtCompatible;
24  import com.google.common.annotations.GwtIncompatible;
25  import com.google.common.collect.testing.ListTestSuiteBuilder;
26  import com.google.common.collect.testing.MinimalCollection;
27  import com.google.common.collect.testing.SetTestSuiteBuilder;
28  import com.google.common.collect.testing.TestStringListGenerator;
29  import com.google.common.collect.testing.TestStringSetGenerator;
30  import com.google.common.collect.testing.features.CollectionFeature;
31  import com.google.common.collect.testing.features.CollectionSize;
32  import com.google.common.collect.testing.google.MultisetTestSuiteBuilder;
33  import com.google.common.collect.testing.google.TestStringMultisetGenerator;
34  import com.google.common.collect.testing.google.UnmodifiableCollectionTests;
35  import com.google.common.testing.EqualsTester;
36  import com.google.common.testing.NullPointerTester;
37  import com.google.common.testing.SerializableTester;
38  
39  import junit.framework.Test;
40  import junit.framework.TestCase;
41  import junit.framework.TestSuite;
42  
43  import java.util.ArrayList;
44  import java.util.Collection;
45  import java.util.HashSet;
46  import java.util.Iterator;
47  import java.util.List;
48  import java.util.Set;
49  
50  /**
51   * Tests for {@link ImmutableMultiset}.
52   *
53   * @author Jared Levy
54   */
55  @GwtCompatible(emulated = true)
56  public class ImmutableMultisetTest extends TestCase {
57  
58    @GwtIncompatible("suite") // TODO(cpovirk): add to collect/gwt/suites
59    public static Test suite() {
60      TestSuite suite = new TestSuite();
61      suite.addTestSuite(ImmutableMultisetTest.class);
62  
63      suite.addTest(MultisetTestSuiteBuilder.using(
64          new TestStringMultisetGenerator() {
65            @Override protected Multiset<String> create(String[] elements) {
66              return ImmutableMultiset.copyOf(elements);
67            }
68          })
69          .named("ImmutableMultiset")
70          .withFeatures(CollectionSize.ANY,
71              CollectionFeature.SERIALIZABLE_INCLUDING_VIEWS,
72              CollectionFeature.ALLOWS_NULL_QUERIES)
73          .createTestSuite());
74  
75      suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() {
76            @Override protected Set<String> create(String[] elements) {
77              return ImmutableMultiset.copyOf(elements).elementSet();
78            }
79          })
80          .named("ImmutableMultiset, element set")
81          .withFeatures(CollectionSize.ANY,
82              CollectionFeature.SERIALIZABLE,
83              CollectionFeature.ALLOWS_NULL_QUERIES)
84          .createTestSuite());
85  
86      suite.addTest(ListTestSuiteBuilder.using(new TestStringListGenerator() {
87            @Override protected List<String> create(String[] elements) {
88              return ImmutableMultiset.copyOf(elements).asList();
89            }
90  
91            @Override
92            public List<String> order(List<String> insertionOrder) {
93              List<String> order = new ArrayList<String>();
94              for (String s : insertionOrder) {
95                int index = order.indexOf(s);
96                if (index == -1) {
97                  order.add(s);
98                } else {
99                  order.add(index, s);
100               }
101             }
102             return order;
103           }
104         })
105         .named("ImmutableMultiset.asList")
106         .withFeatures(CollectionSize.ANY,
107             CollectionFeature.SERIALIZABLE,
108             CollectionFeature.ALLOWS_NULL_QUERIES)
109         .createTestSuite());
110 
111     suite.addTest(ListTestSuiteBuilder.using(new TestStringListGenerator() {
112           @Override protected List<String> create(String[] elements) {
113             Set<String> set = new HashSet<String>();
114             ImmutableMultiset.Builder<String> builder = ImmutableMultiset.builder();
115             for (String s : elements) {
116               checkArgument(set.add(s));
117               builder.addCopies(s, 2);
118             }
119             ImmutableSet<String> elementSet = (ImmutableSet<String>) builder.build().elementSet();
120             return elementSet.asList();
121           }
122         })
123         .named("ImmutableMultiset.elementSet.asList")
124         .withFeatures(CollectionSize.ANY,
125             CollectionFeature.REJECTS_DUPLICATES_AT_CREATION,
126             CollectionFeature.SERIALIZABLE,
127             CollectionFeature.ALLOWS_NULL_QUERIES)
128         .createTestSuite());
129 
130     return suite;
131   }
132 
133   public void testCreation_noArgs() {
134     Multiset<String> multiset = ImmutableMultiset.of();
135     assertTrue(multiset.isEmpty());
136   }
137 
138   public void testCreation_oneElement() {
139     Multiset<String> multiset = ImmutableMultiset.of("a");
140     assertEquals(HashMultiset.create(asList("a")), multiset);
141   }
142 
143   public void testCreation_twoElements() {
144     Multiset<String> multiset = ImmutableMultiset.of("a", "b");
145     assertEquals(HashMultiset.create(asList("a", "b")), multiset);
146   }
147 
148   public void testCreation_threeElements() {
149     Multiset<String> multiset = ImmutableMultiset.of("a", "b", "c");
150     assertEquals(HashMultiset.create(asList("a", "b", "c")), multiset);
151   }
152 
153   public void testCreation_fourElements() {
154     Multiset<String> multiset = ImmutableMultiset.of("a", "b", "c", "d");
155     assertEquals(HashMultiset.create(asList("a", "b", "c", "d")), multiset);
156   }
157 
158   public void testCreation_fiveElements() {
159     Multiset<String> multiset = ImmutableMultiset.of("a", "b", "c", "d", "e");
160     assertEquals(HashMultiset.create(asList("a", "b", "c", "d", "e")),
161         multiset);
162   }
163 
164   public void testCreation_sixElements() {
165     Multiset<String> multiset = ImmutableMultiset.of(
166         "a", "b", "c", "d", "e", "f");
167     assertEquals(HashMultiset.create(asList("a", "b", "c", "d", "e", "f")),
168         multiset);
169   }
170 
171   public void testCreation_sevenElements() {
172     Multiset<String> multiset = ImmutableMultiset.of(
173         "a", "b", "c", "d", "e", "f", "g");
174     assertEquals(
175         HashMultiset.create(asList("a", "b", "c", "d", "e", "f", "g")),
176         multiset);
177   }
178 
179   public void testCreation_emptyArray() {
180     String[] array = new String[0];
181     Multiset<String> multiset = ImmutableMultiset.copyOf(array);
182     assertTrue(multiset.isEmpty());
183   }
184 
185   public void testCreation_arrayOfOneElement() {
186     String[] array = new String[] { "a" };
187     Multiset<String> multiset = ImmutableMultiset.copyOf(array);
188     assertEquals(HashMultiset.create(asList("a")), multiset);
189   }
190 
191   public void testCreation_arrayOfArray() {
192     String[] array = new String[] { "a" };
193     Multiset<String[]> multiset = ImmutableMultiset.<String[]>of(array);
194     Multiset<String[]> expected = HashMultiset.create();
195     expected.add(array);
196     assertEquals(expected, multiset);
197   }
198 
199   public void testCreation_arrayContainingOnlyNull() {
200     String[] array = new String[] { null };
201     try {
202       ImmutableMultiset.copyOf(array);
203       fail();
204     } catch (NullPointerException expected) {}
205   }
206 
207   public void testCopyOf_collection_empty() {
208     // "<String>" is required to work around a javac 1.5 bug.
209     Collection<String> c = MinimalCollection.<String>of();
210     Multiset<String> multiset = ImmutableMultiset.copyOf(c);
211     assertTrue(multiset.isEmpty());
212   }
213 
214   public void testCopyOf_collection_oneElement() {
215     Collection<String> c = MinimalCollection.of("a");
216     Multiset<String> multiset = ImmutableMultiset.copyOf(c);
217     assertEquals(HashMultiset.create(asList("a")), multiset);
218   }
219 
220   public void testCopyOf_collection_general() {
221     Collection<String> c = MinimalCollection.of("a", "b", "a");
222     Multiset<String> multiset = ImmutableMultiset.copyOf(c);
223     assertEquals(HashMultiset.create(asList("a", "b", "a")), multiset);
224   }
225 
226   public void testCopyOf_collectionContainingNull() {
227     Collection<String> c = MinimalCollection.of("a", null, "b");
228     try {
229       ImmutableMultiset.copyOf(c);
230       fail();
231     } catch (NullPointerException expected) {}
232   }
233 
234   public void testCopyOf_multiset_empty() {
235     Multiset<String> c = HashMultiset.create();
236     Multiset<String> multiset = ImmutableMultiset.copyOf(c);
237     assertTrue(multiset.isEmpty());
238   }
239 
240   public void testCopyOf_multiset_oneElement() {
241     Multiset<String> c = HashMultiset.create(asList("a"));
242     Multiset<String> multiset = ImmutableMultiset.copyOf(c);
243     assertEquals(HashMultiset.create(asList("a")), multiset);
244   }
245 
246   public void testCopyOf_multiset_general() {
247     Multiset<String> c = HashMultiset.create(asList("a", "b", "a"));
248     Multiset<String> multiset = ImmutableMultiset.copyOf(c);
249     assertEquals(HashMultiset.create(asList("a", "b", "a")), multiset);
250   }
251 
252   public void testCopyOf_multisetContainingNull() {
253     Multiset<String> c = HashMultiset.create(asList("a", null, "b"));
254     try {
255       ImmutableMultiset.copyOf(c);
256       fail();
257     } catch (NullPointerException expected) {}
258   }
259 
260   public void testCopyOf_iterator_empty() {
261     Iterator<String> iterator = Iterators.emptyIterator();
262     Multiset<String> multiset = ImmutableMultiset.copyOf(iterator);
263     assertTrue(multiset.isEmpty());
264   }
265 
266   public void testCopyOf_iterator_oneElement() {
267     Iterator<String> iterator = Iterators.singletonIterator("a");
268     Multiset<String> multiset = ImmutableMultiset.copyOf(iterator);
269     assertEquals(HashMultiset.create(asList("a")), multiset);
270   }
271 
272   public void testCopyOf_iterator_general() {
273     Iterator<String> iterator = asList("a", "b", "a").iterator();
274     Multiset<String> multiset = ImmutableMultiset.copyOf(iterator);
275     assertEquals(HashMultiset.create(asList("a", "b", "a")), multiset);
276   }
277 
278   public void testCopyOf_iteratorContainingNull() {
279     Iterator<String> iterator = asList("a", null, "b").iterator();
280     try {
281       ImmutableMultiset.copyOf(iterator);
282       fail();
283     } catch (NullPointerException expected) {}
284   }
285 
286   private static class CountingIterable implements Iterable<String> {
287     int count = 0;
288     @Override
289     public Iterator<String> iterator() {
290       count++;
291       return asList("a", "b", "a").iterator();
292     }
293   }
294 
295   public void testCopyOf_plainIterable() {
296     CountingIterable iterable = new CountingIterable();
297     Multiset<String> multiset = ImmutableMultiset.copyOf(iterable);
298     assertEquals(HashMultiset.create(asList("a", "b", "a")), multiset);
299     assertEquals(1, iterable.count);
300   }
301 
302   public void testCopyOf_shortcut_empty() {
303     Collection<String> c = ImmutableMultiset.of();
304     assertSame(c, ImmutableMultiset.copyOf(c));
305   }
306 
307   public void testCopyOf_shortcut_singleton() {
308     Collection<String> c = ImmutableMultiset.of("a");
309     assertSame(c, ImmutableMultiset.copyOf(c));
310   }
311 
312   public void testCopyOf_shortcut_immutableMultiset() {
313     Collection<String> c = ImmutableMultiset.of("a", "b", "c");
314     assertSame(c, ImmutableMultiset.copyOf(c));
315   }
316 
317   public void testBuilderAdd() {
318     ImmutableMultiset<String> multiset = new ImmutableMultiset.Builder<String>()
319         .add("a")
320         .add("b")
321         .add("a")
322         .add("c")
323         .build();
324     assertEquals(HashMultiset.create(asList("a", "b", "a", "c")), multiset);
325   }
326 
327   public void testBuilderAddAll() {
328     List<String> a = asList("a", "b");
329     List<String> b = asList("c", "d");
330     ImmutableMultiset<String> multiset = new ImmutableMultiset.Builder<String>()
331         .addAll(a)
332         .addAll(b)
333         .build();
334     assertEquals(HashMultiset.create(asList("a", "b", "c", "d")), multiset);
335   }
336 
337   public void testBuilderAddAllMultiset() {
338     Multiset<String> a = HashMultiset.create(asList("a", "b", "b"));
339     Multiset<String> b = HashMultiset.create(asList("c", "b"));
340     ImmutableMultiset<String> multiset = new ImmutableMultiset.Builder<String>()
341         .addAll(a)
342         .addAll(b)
343         .build();
344     assertEquals(
345         HashMultiset.create(asList("a", "b", "b", "b", "c")), multiset);
346   }
347 
348   public void testBuilderAddAllIterator() {
349     Iterator<String> iterator = asList("a", "b", "a", "c").iterator();
350     ImmutableMultiset<String> multiset = new ImmutableMultiset.Builder<String>()
351         .addAll(iterator)
352         .build();
353     assertEquals(HashMultiset.create(asList("a", "b", "a", "c")), multiset);
354   }
355 
356   public void testBuilderAddCopies() {
357     ImmutableMultiset<String> multiset = new ImmutableMultiset.Builder<String>()
358         .addCopies("a", 2)
359         .addCopies("b", 3)
360         .addCopies("c", 0)
361         .build();
362     assertEquals(
363         HashMultiset.create(asList("a", "a", "b", "b", "b")), multiset);
364   }
365 
366   public void testBuilderSetCount() {
367     ImmutableMultiset<String> multiset = new ImmutableMultiset.Builder<String>()
368         .add("a")
369         .setCount("a", 2)
370         .setCount("b", 3)
371         .build();
372     assertEquals(
373         HashMultiset.create(asList("a", "a", "b", "b", "b")), multiset);
374   }
375 
376   public void testBuilderAddHandlesNullsCorrectly() {
377     ImmutableMultiset.Builder<String> builder = ImmutableMultiset.builder();
378     try {
379       builder.add((String) null);
380       fail("expected NullPointerException");
381     } catch (NullPointerException expected) {}
382   }
383 
384   public void testBuilderAddAllHandlesNullsCorrectly() {
385     ImmutableMultiset.Builder<String> builder = ImmutableMultiset.builder();
386     try {
387       builder.addAll((Collection<String>) null);
388       fail("expected NullPointerException");
389     } catch (NullPointerException expected) {}
390 
391     builder = ImmutableMultiset.builder();
392     List<String> listWithNulls = asList("a", null, "b");
393     try {
394       builder.addAll(listWithNulls);
395       fail("expected NullPointerException");
396     } catch (NullPointerException expected) {}
397 
398     builder = ImmutableMultiset.builder();
399     Multiset<String> multisetWithNull
400         = LinkedHashMultiset.create(asList("a", null, "b"));
401     try {
402       builder.addAll(multisetWithNull);
403       fail("expected NullPointerException");
404     } catch (NullPointerException expected) {}
405   }
406 
407   public void testBuilderAddCopiesHandlesNullsCorrectly() {
408     ImmutableMultiset.Builder<String> builder = ImmutableMultiset.builder();
409     try {
410       builder.addCopies(null, 2);
411       fail("expected NullPointerException");
412     } catch (NullPointerException expected) {}
413   }
414 
415   public void testBuilderAddCopiesIllegal() {
416     ImmutableMultiset.Builder<String> builder = ImmutableMultiset.builder();
417     try {
418       builder.addCopies("a", -2);
419       fail("expected IllegalArgumentException");
420     } catch (IllegalArgumentException expected) {}
421   }
422 
423   public void testBuilderSetCountHandlesNullsCorrectly() {
424     ImmutableMultiset.Builder<String> builder = ImmutableMultiset.builder();
425     try {
426       builder.setCount(null, 2);
427       fail("expected NullPointerException");
428     } catch (NullPointerException expected) {}
429   }
430 
431   public void testBuilderSetCountIllegal() {
432     ImmutableMultiset.Builder<String> builder = ImmutableMultiset.builder();
433     try {
434       builder.setCount("a", -2);
435       fail("expected IllegalArgumentException");
436     } catch (IllegalArgumentException expected) {}
437   }
438 
439   @GwtIncompatible("NullPointerTester")
440   public void testNullPointers() {
441     NullPointerTester tester = new NullPointerTester();
442     tester.testAllPublicStaticMethods(ImmutableMultiset.class);
443   }
444 
445   @GwtIncompatible("SerializableTester")
446   public void testSerialization_empty() {
447     Collection<String> c = ImmutableMultiset.of();
448     assertSame(c, SerializableTester.reserialize(c));
449   }
450 
451   @GwtIncompatible("SerializableTester")
452   public void testSerialization_multiple() {
453     Collection<String> c = ImmutableMultiset.of("a", "b", "a");
454     Collection<String> copy = SerializableTester.reserializeAndAssert(c);
455     assertThat(copy).has().exactly("a", "a", "b").inOrder();
456   }
457 
458   @GwtIncompatible("SerializableTester")
459   public void testSerialization_elementSet() {
460     Multiset<String> c = ImmutableMultiset.of("a", "b", "a");
461     Collection<String> copy =
462         LenientSerializableTester.reserializeAndAssertLenient(c.elementSet());
463     assertThat(copy).has().exactly("a", "b").inOrder();
464   }
465 
466   @GwtIncompatible("SerializableTester")
467   public void testSerialization_entrySet() {
468     Multiset<String> c = ImmutableMultiset.of("a", "b", "c");
469     SerializableTester.reserializeAndAssert(c.entrySet());
470   }
471 
472   public void testEquals_immutableMultiset() {
473     Collection<String> c = ImmutableMultiset.of("a", "b", "a");
474     assertEquals(c, ImmutableMultiset.of("a", "b", "a"));
475     assertEquals(c, ImmutableMultiset.of("a", "a", "b"));
476     assertThat(c).isNotEqualTo(ImmutableMultiset.of("a", "b"));
477     assertThat(c).isNotEqualTo(ImmutableMultiset.of("a", "b", "c", "d"));
478   }
479 
480   public void testIterationOrder() {
481     Collection<String> c = ImmutableMultiset.of("a", "b", "a");
482     assertThat(c).has().exactly("a", "a", "b").inOrder();
483   }
484 
485   public void testMultisetWrites() {
486     Multiset<String> multiset = ImmutableMultiset.of("a", "b", "a");
487     UnmodifiableCollectionTests.assertMultisetIsUnmodifiable(multiset, "test");
488   }
489 
490   public void testAsList() {
491     ImmutableMultiset<String> multiset
492         = ImmutableMultiset.of("a", "a", "b", "b", "b");
493     ImmutableList<String> list = multiset.asList();
494     assertEquals(ImmutableList.of("a", "a", "b", "b", "b"), list);
495     assertEquals(2, list.indexOf("b"));
496     assertEquals(4, list.lastIndexOf("b"));
497   }
498 
499   @GwtIncompatible("SerializableTester")
500   public void testSerialization_asList() {
501     ImmutableMultiset<String> multiset
502         = ImmutableMultiset.of("a", "a", "b", "b", "b");
503     SerializableTester.reserializeAndAssert(multiset.asList());
504   }
505 
506   public void testEquals() {
507     new EqualsTester()
508         .addEqualityGroup(ImmutableMultiset.of(), ImmutableMultiset.of())
509         .addEqualityGroup(ImmutableMultiset.of(1), ImmutableMultiset.of(1))
510         .addEqualityGroup(ImmutableMultiset.of(1, 1), ImmutableMultiset.of(1, 1))
511         .addEqualityGroup(ImmutableMultiset.of(1, 2, 1), ImmutableMultiset.of(2, 1, 1))
512         .testEquals();
513   }
514 }