• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.CollectorTester;
36 import com.google.common.testing.EqualsTester;
37 import com.google.common.testing.NullPointerTester;
38 import com.google.common.testing.SerializableTester;
39 import com.google.errorprone.annotations.CanIgnoreReturnValue;
40 import java.util.ArrayList;
41 import java.util.Arrays;
42 import java.util.Collection;
43 import java.util.HashSet;
44 import java.util.Iterator;
45 import java.util.List;
46 import java.util.Set;
47 import java.util.function.BiPredicate;
48 import java.util.stream.Collector;
49 import junit.framework.Test;
50 import junit.framework.TestCase;
51 import junit.framework.TestSuite;
52 
53 /**
54  * Tests for {@link ImmutableMultiset}.
55  *
56  * @author Jared Levy
57  */
58 @GwtCompatible(emulated = true)
59 public class ImmutableMultisetTest extends TestCase {
60 
61   @GwtIncompatible // suite // TODO(cpovirk): add to collect/gwt/suites
suite()62   public static Test suite() {
63     TestSuite suite = new TestSuite();
64     suite.addTestSuite(ImmutableMultisetTest.class);
65     suite.addTestSuite(FloodingTest.class);
66 
67     suite.addTest(
68         MultisetTestSuiteBuilder.using(
69                 new TestStringMultisetGenerator() {
70                   @Override
71                   protected Multiset<String> create(String[] elements) {
72                     return ImmutableMultiset.copyOf(elements);
73                   }
74                 })
75             .named("ImmutableMultiset")
76             .withFeatures(
77                 CollectionSize.ANY,
78                 CollectionFeature.SERIALIZABLE_INCLUDING_VIEWS,
79                 CollectionFeature.ALLOWS_NULL_QUERIES)
80             .createTestSuite());
81 
82     suite.addTest(
83         MultisetTestSuiteBuilder.using(
84                 new TestStringMultisetGenerator() {
85                   @Override
86                   protected Multiset<String> create(String[] elements) {
87                     return ImmutableMultiset.<String>builder().add(elements).buildJdkBacked();
88                   }
89                 })
90             .named("ImmutableMultiset [JDK backed]")
91             .withFeatures(
92                 CollectionSize.ANY,
93                 CollectionFeature.SERIALIZABLE_INCLUDING_VIEWS,
94                 CollectionFeature.ALLOWS_NULL_QUERIES)
95             .createTestSuite());
96 
97     suite.addTest(
98         SetTestSuiteBuilder.using(
99                 new TestStringSetGenerator() {
100                   @Override
101                   protected Set<String> create(String[] elements) {
102                     return ImmutableMultiset.copyOf(elements).elementSet();
103                   }
104                 })
105             .named("ImmutableMultiset, element set")
106             .withFeatures(
107                 CollectionSize.ANY,
108                 CollectionFeature.SERIALIZABLE,
109                 CollectionFeature.ALLOWS_NULL_QUERIES)
110             .createTestSuite());
111 
112     suite.addTest(
113         ListTestSuiteBuilder.using(
114                 new TestStringListGenerator() {
115                   @Override
116                   protected List<String> create(String[] elements) {
117                     return ImmutableMultiset.copyOf(elements).asList();
118                   }
119 
120                   @Override
121                   public List<String> order(List<String> insertionOrder) {
122                     List<String> order = new ArrayList<>();
123                     for (String s : insertionOrder) {
124                       int index = order.indexOf(s);
125                       if (index == -1) {
126                         order.add(s);
127                       } else {
128                         order.add(index, s);
129                       }
130                     }
131                     return order;
132                   }
133                 })
134             .named("ImmutableMultiset.asList")
135             .withFeatures(
136                 CollectionSize.ANY,
137                 CollectionFeature.SERIALIZABLE,
138                 CollectionFeature.ALLOWS_NULL_QUERIES)
139             .createTestSuite());
140 
141     suite.addTest(
142         ListTestSuiteBuilder.using(
143                 new TestStringListGenerator() {
144                   @Override
145                   protected List<String> create(String[] elements) {
146                     Set<String> set = new HashSet<>();
147                     ImmutableMultiset.Builder<String> builder = ImmutableMultiset.builder();
148                     for (String s : elements) {
149                       checkArgument(set.add(s));
150                       builder.addCopies(s, 2);
151                     }
152                     ImmutableSet<String> elementSet =
153                         (ImmutableSet<String>) builder.build().elementSet();
154                     return elementSet.asList();
155                   }
156                 })
157             .named("ImmutableMultiset.elementSet.asList")
158             .withFeatures(
159                 CollectionSize.ANY,
160                 CollectionFeature.REJECTS_DUPLICATES_AT_CREATION,
161                 CollectionFeature.SERIALIZABLE,
162                 CollectionFeature.ALLOWS_NULL_QUERIES)
163             .createTestSuite());
164 
165     return suite;
166   }
167 
testCreation_noArgs()168   public void testCreation_noArgs() {
169     Multiset<String> multiset = ImmutableMultiset.of();
170     assertTrue(multiset.isEmpty());
171   }
172 
testCreation_oneElement()173   public void testCreation_oneElement() {
174     Multiset<String> multiset = ImmutableMultiset.of("a");
175     assertEquals(HashMultiset.create(asList("a")), multiset);
176   }
177 
testCreation_twoElements()178   public void testCreation_twoElements() {
179     Multiset<String> multiset = ImmutableMultiset.of("a", "b");
180     assertEquals(HashMultiset.create(asList("a", "b")), multiset);
181   }
182 
testCreation_threeElements()183   public void testCreation_threeElements() {
184     Multiset<String> multiset = ImmutableMultiset.of("a", "b", "c");
185     assertEquals(HashMultiset.create(asList("a", "b", "c")), multiset);
186   }
187 
testCreation_fourElements()188   public void testCreation_fourElements() {
189     Multiset<String> multiset = ImmutableMultiset.of("a", "b", "c", "d");
190     assertEquals(HashMultiset.create(asList("a", "b", "c", "d")), multiset);
191   }
192 
testCreation_fiveElements()193   public void testCreation_fiveElements() {
194     Multiset<String> multiset = ImmutableMultiset.of("a", "b", "c", "d", "e");
195     assertEquals(HashMultiset.create(asList("a", "b", "c", "d", "e")), multiset);
196   }
197 
testCreation_sixElements()198   public void testCreation_sixElements() {
199     Multiset<String> multiset = ImmutableMultiset.of("a", "b", "c", "d", "e", "f");
200     assertEquals(HashMultiset.create(asList("a", "b", "c", "d", "e", "f")), multiset);
201   }
202 
testCreation_sevenElements()203   public void testCreation_sevenElements() {
204     Multiset<String> multiset = ImmutableMultiset.of("a", "b", "c", "d", "e", "f", "g");
205     assertEquals(HashMultiset.create(asList("a", "b", "c", "d", "e", "f", "g")), multiset);
206   }
207 
testCreation_emptyArray()208   public void testCreation_emptyArray() {
209     String[] array = new String[0];
210     Multiset<String> multiset = ImmutableMultiset.copyOf(array);
211     assertTrue(multiset.isEmpty());
212   }
213 
testCreation_arrayOfOneElement()214   public void testCreation_arrayOfOneElement() {
215     String[] array = new String[] {"a"};
216     Multiset<String> multiset = ImmutableMultiset.copyOf(array);
217     assertEquals(HashMultiset.create(asList("a")), multiset);
218   }
219 
testCreation_arrayOfArray()220   public void testCreation_arrayOfArray() {
221     String[] array = new String[] {"a"};
222     Multiset<String[]> multiset = ImmutableMultiset.<String[]>of(array);
223     Multiset<String[]> expected = HashMultiset.create();
224     expected.add(array);
225     assertEquals(expected, multiset);
226   }
227 
testCreation_arrayContainingOnlyNull()228   public void testCreation_arrayContainingOnlyNull() {
229     String[] array = new String[] {null};
230     try {
231       ImmutableMultiset.copyOf(array);
232       fail();
233     } catch (NullPointerException expected) {
234     }
235   }
236 
testCopyOf_collection_empty()237   public void testCopyOf_collection_empty() {
238     // "<String>" is required to work around a javac 1.5 bug.
239     Collection<String> c = MinimalCollection.<String>of();
240     Multiset<String> multiset = ImmutableMultiset.copyOf(c);
241     assertTrue(multiset.isEmpty());
242   }
243 
testCopyOf_collection_oneElement()244   public void testCopyOf_collection_oneElement() {
245     Collection<String> c = MinimalCollection.of("a");
246     Multiset<String> multiset = ImmutableMultiset.copyOf(c);
247     assertEquals(HashMultiset.create(asList("a")), multiset);
248   }
249 
testCopyOf_collection_general()250   public void testCopyOf_collection_general() {
251     Collection<String> c = MinimalCollection.of("a", "b", "a");
252     Multiset<String> multiset = ImmutableMultiset.copyOf(c);
253     assertEquals(HashMultiset.create(asList("a", "b", "a")), multiset);
254   }
255 
testCopyOf_collectionContainingNull()256   public void testCopyOf_collectionContainingNull() {
257     Collection<String> c = MinimalCollection.of("a", null, "b");
258     try {
259       ImmutableMultiset.copyOf(c);
260       fail();
261     } catch (NullPointerException expected) {
262     }
263   }
264 
testCopyOf_multiset_empty()265   public void testCopyOf_multiset_empty() {
266     Multiset<String> c = HashMultiset.create();
267     Multiset<String> multiset = ImmutableMultiset.copyOf(c);
268     assertTrue(multiset.isEmpty());
269   }
270 
testCopyOf_multiset_oneElement()271   public void testCopyOf_multiset_oneElement() {
272     Multiset<String> c = HashMultiset.create(asList("a"));
273     Multiset<String> multiset = ImmutableMultiset.copyOf(c);
274     assertEquals(HashMultiset.create(asList("a")), multiset);
275   }
276 
testCopyOf_multiset_general()277   public void testCopyOf_multiset_general() {
278     Multiset<String> c = HashMultiset.create(asList("a", "b", "a"));
279     Multiset<String> multiset = ImmutableMultiset.copyOf(c);
280     assertEquals(HashMultiset.create(asList("a", "b", "a")), multiset);
281   }
282 
testCopyOf_multisetContainingNull()283   public void testCopyOf_multisetContainingNull() {
284     Multiset<String> c = HashMultiset.create(asList("a", null, "b"));
285     try {
286       ImmutableMultiset.copyOf(c);
287       fail();
288     } catch (NullPointerException expected) {
289     }
290   }
291 
testCopyOf_iterator_empty()292   public void testCopyOf_iterator_empty() {
293     Iterator<String> iterator = Iterators.emptyIterator();
294     Multiset<String> multiset = ImmutableMultiset.copyOf(iterator);
295     assertTrue(multiset.isEmpty());
296   }
297 
testCopyOf_iterator_oneElement()298   public void testCopyOf_iterator_oneElement() {
299     Iterator<String> iterator = Iterators.singletonIterator("a");
300     Multiset<String> multiset = ImmutableMultiset.copyOf(iterator);
301     assertEquals(HashMultiset.create(asList("a")), multiset);
302   }
303 
testCopyOf_iterator_general()304   public void testCopyOf_iterator_general() {
305     Iterator<String> iterator = asList("a", "b", "a").iterator();
306     Multiset<String> multiset = ImmutableMultiset.copyOf(iterator);
307     assertEquals(HashMultiset.create(asList("a", "b", "a")), multiset);
308   }
309 
testCopyOf_iteratorContainingNull()310   public void testCopyOf_iteratorContainingNull() {
311     Iterator<String> iterator = asList("a", null, "b").iterator();
312     try {
313       ImmutableMultiset.copyOf(iterator);
314       fail();
315     } catch (NullPointerException expected) {
316     }
317   }
318 
testToImmutableMultiset()319   public void testToImmutableMultiset() {
320     BiPredicate<ImmutableMultiset<String>, ImmutableMultiset<String>> equivalence =
321         (ms1, ms2) -> ms1.equals(ms2) && ms1.entrySet().asList().equals(ms2.entrySet().asList());
322     CollectorTester.of(ImmutableMultiset.<String>toImmutableMultiset(), equivalence)
323         .expectCollects(ImmutableMultiset.of())
324         .expectCollects(
325             ImmutableMultiset.of("a", "a", "b", "c", "c", "c"), "a", "a", "b", "c", "c", "c");
326   }
327 
testToImmutableMultisetCountFunction()328   public void testToImmutableMultisetCountFunction() {
329     BiPredicate<ImmutableMultiset<String>, ImmutableMultiset<String>> equivalence =
330         (ms1, ms2) -> ms1.equals(ms2) && ms1.entrySet().asList().equals(ms2.entrySet().asList());
331     CollectorTester.of(
332             ImmutableMultiset.<Multiset.Entry<String>, String>toImmutableMultiset(
333                 Multiset.Entry::getElement, Multiset.Entry::getCount),
334             equivalence)
335         .expectCollects(ImmutableMultiset.of())
336         .expectCollects(
337             ImmutableMultiset.of("a", "a", "b", "c", "c", "c"),
338             Multisets.immutableEntry("a", 1),
339             Multisets.immutableEntry("b", 1),
340             Multisets.immutableEntry("a", 1),
341             Multisets.immutableEntry("c", 3));
342   }
343 
testToImmutableMultiset_duplicates()344   public void testToImmutableMultiset_duplicates() {
345     class TypeWithDuplicates {
346       final int a;
347       final int b;
348 
349       TypeWithDuplicates(int a, int b) {
350         this.a = a;
351         this.b = b;
352       }
353 
354       @Override
355       public int hashCode() {
356         return a;
357       }
358 
359       @Override
360       public boolean equals(Object obj) {
361         return obj instanceof TypeWithDuplicates && ((TypeWithDuplicates) obj).a == a;
362       }
363 
364       public boolean fullEquals(TypeWithDuplicates other) {
365         return other != null && a == other.a && b == other.b;
366       }
367     }
368 
369     Collector<TypeWithDuplicates, ?, ImmutableMultiset<TypeWithDuplicates>> collector =
370         ImmutableMultiset.toImmutableMultiset();
371     BiPredicate<ImmutableMultiset<TypeWithDuplicates>, ImmutableMultiset<TypeWithDuplicates>>
372         equivalence =
373             (ms1, ms2) -> {
374               if (!ms1.equals(ms2)) {
375                 return false;
376               }
377               List<TypeWithDuplicates> elements1 = ImmutableList.copyOf(ms1.elementSet());
378               List<TypeWithDuplicates> elements2 = ImmutableList.copyOf(ms2.elementSet());
379               for (int i = 0; i < ms1.elementSet().size(); i++) {
380                 if (!elements1.get(i).fullEquals(elements2.get(i))) {
381                   return false;
382                 }
383               }
384               return true;
385             };
386     TypeWithDuplicates a = new TypeWithDuplicates(1, 1);
387     TypeWithDuplicates b1 = new TypeWithDuplicates(2, 1);
388     TypeWithDuplicates b2 = new TypeWithDuplicates(2, 2);
389     TypeWithDuplicates c = new TypeWithDuplicates(3, 1);
390     CollectorTester.of(collector, equivalence)
391         .expectCollects(
392             ImmutableMultiset.<TypeWithDuplicates>builder().add(a).addCopies(b1, 2).add(c).build(),
393             a,
394             b1,
395             c,
396             b2);
397     collector = ImmutableMultiset.toImmutableMultiset(e -> e, e -> 1);
398     CollectorTester.of(collector, equivalence)
399         .expectCollects(
400             ImmutableMultiset.<TypeWithDuplicates>builder().add(a).addCopies(b1, 2).add(c).build(),
401             a,
402             b1,
403             c,
404             b2);
405   }
406 
407   private static class CountingIterable implements Iterable<String> {
408     int count = 0;
409 
410     @Override
iterator()411     public Iterator<String> iterator() {
412       count++;
413       return asList("a", "b", "a").iterator();
414     }
415   }
416 
testCopyOf_plainIterable()417   public void testCopyOf_plainIterable() {
418     CountingIterable iterable = new CountingIterable();
419     Multiset<String> multiset = ImmutableMultiset.copyOf(iterable);
420     assertEquals(HashMultiset.create(asList("a", "b", "a")), multiset);
421     assertEquals(1, iterable.count);
422   }
423 
testCopyOf_hashMultiset()424   public void testCopyOf_hashMultiset() {
425     Multiset<String> iterable = HashMultiset.create(asList("a", "b", "a"));
426     Multiset<String> multiset = ImmutableMultiset.copyOf(iterable);
427     assertEquals(HashMultiset.create(asList("a", "b", "a")), multiset);
428   }
429 
testCopyOf_treeMultiset()430   public void testCopyOf_treeMultiset() {
431     Multiset<String> iterable = TreeMultiset.create(asList("a", "b", "a"));
432     Multiset<String> multiset = ImmutableMultiset.copyOf(iterable);
433     assertEquals(HashMultiset.create(asList("a", "b", "a")), multiset);
434   }
435 
testCopyOf_shortcut_empty()436   public void testCopyOf_shortcut_empty() {
437     Collection<String> c = ImmutableMultiset.of();
438     assertSame(c, ImmutableMultiset.copyOf(c));
439   }
440 
testCopyOf_shortcut_singleton()441   public void testCopyOf_shortcut_singleton() {
442     Collection<String> c = ImmutableMultiset.of("a");
443     assertSame(c, ImmutableMultiset.copyOf(c));
444   }
445 
testCopyOf_shortcut_immutableMultiset()446   public void testCopyOf_shortcut_immutableMultiset() {
447     Collection<String> c = ImmutableMultiset.of("a", "b", "c");
448     assertSame(c, ImmutableMultiset.copyOf(c));
449   }
450 
testBuilderAdd()451   public void testBuilderAdd() {
452     ImmutableMultiset<String> multiset =
453         new ImmutableMultiset.Builder<String>().add("a").add("b").add("a").add("c").build();
454     assertEquals(HashMultiset.create(asList("a", "b", "a", "c")), multiset);
455   }
456 
testBuilderAddAll()457   public void testBuilderAddAll() {
458     List<String> a = asList("a", "b");
459     List<String> b = asList("c", "d");
460     ImmutableMultiset<String> multiset =
461         new ImmutableMultiset.Builder<String>().addAll(a).addAll(b).build();
462     assertEquals(HashMultiset.create(asList("a", "b", "c", "d")), multiset);
463   }
464 
testBuilderAddAllHashMultiset()465   public void testBuilderAddAllHashMultiset() {
466     Multiset<String> a = HashMultiset.create(asList("a", "b", "b"));
467     Multiset<String> b = HashMultiset.create(asList("c", "b"));
468     ImmutableMultiset<String> multiset =
469         new ImmutableMultiset.Builder<String>().addAll(a).addAll(b).build();
470     assertEquals(HashMultiset.create(asList("a", "b", "b", "b", "c")), multiset);
471   }
472 
testBuilderAddAllImmutableMultiset()473   public void testBuilderAddAllImmutableMultiset() {
474     Multiset<String> a = ImmutableMultiset.of("a", "b", "b");
475     Multiset<String> b = ImmutableMultiset.of("c", "b");
476     ImmutableMultiset<String> multiset =
477         new ImmutableMultiset.Builder<String>().addAll(a).addAll(b).build();
478     assertEquals(HashMultiset.create(asList("a", "b", "b", "b", "c")), multiset);
479   }
480 
testBuilderAddAllTreeMultiset()481   public void testBuilderAddAllTreeMultiset() {
482     Multiset<String> a = TreeMultiset.create(asList("a", "b", "b"));
483     Multiset<String> b = TreeMultiset.create(asList("c", "b"));
484     ImmutableMultiset<String> multiset =
485         new ImmutableMultiset.Builder<String>().addAll(a).addAll(b).build();
486     assertEquals(HashMultiset.create(asList("a", "b", "b", "b", "c")), multiset);
487   }
488 
testBuilderAddAllIterator()489   public void testBuilderAddAllIterator() {
490     Iterator<String> iterator = asList("a", "b", "a", "c").iterator();
491     ImmutableMultiset<String> multiset =
492         new ImmutableMultiset.Builder<String>().addAll(iterator).build();
493     assertEquals(HashMultiset.create(asList("a", "b", "a", "c")), multiset);
494   }
495 
testBuilderAddCopies()496   public void testBuilderAddCopies() {
497     ImmutableMultiset<String> multiset =
498         new ImmutableMultiset.Builder<String>()
499             .addCopies("a", 2)
500             .addCopies("b", 3)
501             .addCopies("c", 0)
502             .build();
503     assertEquals(HashMultiset.create(asList("a", "a", "b", "b", "b")), multiset);
504   }
505 
testBuilderSetCount()506   public void testBuilderSetCount() {
507     ImmutableMultiset<String> multiset =
508         new ImmutableMultiset.Builder<String>().add("a").setCount("a", 2).setCount("b", 3).build();
509     assertEquals(HashMultiset.create(asList("a", "a", "b", "b", "b")), multiset);
510   }
511 
testBuilderAddHandlesNullsCorrectly()512   public void testBuilderAddHandlesNullsCorrectly() {
513     ImmutableMultiset.Builder<String> builder = ImmutableMultiset.builder();
514     try {
515       builder.add((String) null);
516       fail("expected NullPointerException");
517     } catch (NullPointerException expected) {
518     }
519   }
520 
testBuilderAddAllHandlesNullsCorrectly()521   public void testBuilderAddAllHandlesNullsCorrectly() {
522     ImmutableMultiset.Builder<String> builder = ImmutableMultiset.builder();
523     try {
524       builder.addAll((Collection<String>) null);
525       fail("expected NullPointerException");
526     } catch (NullPointerException expected) {
527     }
528 
529     builder = ImmutableMultiset.builder();
530     List<String> listWithNulls = asList("a", null, "b");
531     try {
532       builder.addAll(listWithNulls);
533       fail("expected NullPointerException");
534     } catch (NullPointerException expected) {
535     }
536 
537     builder = ImmutableMultiset.builder();
538     Multiset<String> multisetWithNull = LinkedHashMultiset.create(asList("a", null, "b"));
539     try {
540       builder.addAll(multisetWithNull);
541       fail("expected NullPointerException");
542     } catch (NullPointerException expected) {
543     }
544   }
545 
testBuilderAddCopiesHandlesNullsCorrectly()546   public void testBuilderAddCopiesHandlesNullsCorrectly() {
547     ImmutableMultiset.Builder<String> builder = ImmutableMultiset.builder();
548     try {
549       builder.addCopies(null, 2);
550       fail("expected NullPointerException");
551     } catch (NullPointerException expected) {
552     }
553   }
554 
testBuilderAddCopiesIllegal()555   public void testBuilderAddCopiesIllegal() {
556     ImmutableMultiset.Builder<String> builder = ImmutableMultiset.builder();
557     try {
558       builder.addCopies("a", -2);
559       fail("expected IllegalArgumentException");
560     } catch (IllegalArgumentException expected) {
561     }
562   }
563 
testBuilderSetCountHandlesNullsCorrectly()564   public void testBuilderSetCountHandlesNullsCorrectly() {
565     ImmutableMultiset.Builder<String> builder = ImmutableMultiset.builder();
566     try {
567       builder.setCount(null, 2);
568       fail("expected NullPointerException");
569     } catch (NullPointerException expected) {
570     }
571   }
572 
testBuilderSetCountIllegal()573   public void testBuilderSetCountIllegal() {
574     ImmutableMultiset.Builder<String> builder = ImmutableMultiset.builder();
575     try {
576       builder.setCount("a", -2);
577       fail("expected IllegalArgumentException");
578     } catch (IllegalArgumentException expected) {
579     }
580   }
581 
582   @GwtIncompatible // NullPointerTester
testNullPointers()583   public void testNullPointers() {
584     NullPointerTester tester = new NullPointerTester();
585     tester.testAllPublicStaticMethods(ImmutableMultiset.class);
586   }
587 
588   @GwtIncompatible // SerializableTester
testSerialization_empty()589   public void testSerialization_empty() {
590     Collection<String> c = ImmutableMultiset.of();
591     assertSame(c, SerializableTester.reserialize(c));
592   }
593 
594   @GwtIncompatible // SerializableTester
testSerialization_multiple()595   public void testSerialization_multiple() {
596     Collection<String> c = ImmutableMultiset.of("a", "b", "a");
597     Collection<String> copy = SerializableTester.reserializeAndAssert(c);
598     assertThat(copy).containsExactly("a", "a", "b").inOrder();
599   }
600 
601   @GwtIncompatible // SerializableTester
testSerialization_elementSet()602   public void testSerialization_elementSet() {
603     Multiset<String> c = ImmutableMultiset.of("a", "b", "a");
604     Collection<String> copy = LenientSerializableTester.reserializeAndAssertLenient(c.elementSet());
605     assertThat(copy).containsExactly("a", "b").inOrder();
606   }
607 
608   @GwtIncompatible // SerializableTester
testSerialization_entrySet()609   public void testSerialization_entrySet() {
610     Multiset<String> c = ImmutableMultiset.of("a", "b", "c");
611     SerializableTester.reserializeAndAssert(c.entrySet());
612   }
613 
testEquals_immutableMultiset()614   public void testEquals_immutableMultiset() {
615     Collection<String> c = ImmutableMultiset.of("a", "b", "a");
616     assertEquals(c, ImmutableMultiset.of("a", "b", "a"));
617     assertEquals(c, ImmutableMultiset.of("a", "a", "b"));
618     assertThat(c).isNotEqualTo(ImmutableMultiset.of("a", "b"));
619     assertThat(c).isNotEqualTo(ImmutableMultiset.of("a", "b", "c", "d"));
620   }
621 
testIterationOrder()622   public void testIterationOrder() {
623     Collection<String> c = ImmutableMultiset.of("a", "b", "a");
624     assertThat(c).containsExactly("a", "a", "b").inOrder();
625     assertThat(ImmutableMultiset.of("c", "b", "a", "c").elementSet())
626         .containsExactly("c", "b", "a")
627         .inOrder();
628   }
629 
testMultisetWrites()630   public void testMultisetWrites() {
631     Multiset<String> multiset = ImmutableMultiset.of("a", "b", "a");
632     UnmodifiableCollectionTests.assertMultisetIsUnmodifiable(multiset, "test");
633   }
634 
testAsList()635   public void testAsList() {
636     ImmutableMultiset<String> multiset = ImmutableMultiset.of("a", "a", "b", "b", "b");
637     ImmutableList<String> list = multiset.asList();
638     assertEquals(ImmutableList.of("a", "a", "b", "b", "b"), list);
639     assertEquals(2, list.indexOf("b"));
640     assertEquals(4, list.lastIndexOf("b"));
641   }
642 
643   @GwtIncompatible // SerializableTester
testSerialization_asList()644   public void testSerialization_asList() {
645     ImmutableMultiset<String> multiset = ImmutableMultiset.of("a", "a", "b", "b", "b");
646     SerializableTester.reserializeAndAssert(multiset.asList());
647   }
648 
testEquals()649   public void testEquals() {
650     new EqualsTester()
651         .addEqualityGroup(ImmutableMultiset.of(), ImmutableMultiset.of())
652         .addEqualityGroup(ImmutableMultiset.of(1), ImmutableMultiset.of(1))
653         .addEqualityGroup(ImmutableMultiset.of(1, 1), ImmutableMultiset.of(1, 1))
654         .addEqualityGroup(ImmutableMultiset.of(1, 2, 1), ImmutableMultiset.of(2, 1, 1))
655         .testEquals();
656   }
657 
testIterationOrderThroughBuilderRemovals()658   public void testIterationOrderThroughBuilderRemovals() {
659     ImmutableMultiset.Builder<String> builder = ImmutableMultiset.builder();
660     builder.addCopies("a", 2);
661     builder.add("b");
662     builder.add("c");
663     builder.setCount("b", 0);
664     ImmutableMultiset<String> multiset = builder.build();
665     assertThat(multiset.elementSet()).containsExactly("a", "c").inOrder();
666     builder.add("b");
667     assertThat(builder.build().elementSet()).containsExactly("a", "c", "b").inOrder();
668     assertThat(multiset.elementSet()).containsExactly("a", "c").inOrder();
669   }
670 
671   public static class FloodingTest extends AbstractHashFloodingTest<Multiset<Object>> {
FloodingTest()672     public FloodingTest() {
673       super(
674           Arrays.asList(ConstructionPathway.values()),
675           n -> n * Math.log(n),
676           ImmutableList.of(
677               QueryOp.create(
678                   "count",
679                   (ms, o) -> {
680                     int unused = ms.count(o);
681                   },
682                   Math::log)));
683     }
684 
685     /** All the ways to create an ImmutableMultiset. */
686     enum ConstructionPathway implements Construction<Multiset<Object>> {
687       COPY_OF_COLLECTION {
688         @Override
create(List<?> keys)689         public ImmutableMultiset<Object> create(List<?> keys) {
690           return ImmutableMultiset.copyOf(keys);
691         }
692       },
693       COPY_OF_ITERATOR {
694         @Override
create(List<?> keys)695         public ImmutableMultiset<Object> create(List<?> keys) {
696           return ImmutableMultiset.copyOf(keys.iterator());
697         }
698       },
699       BUILDER_ADD_ENTRY_BY_ENTRY {
700         @Override
create(List<?> keys)701         public ImmutableMultiset<Object> create(List<?> keys) {
702           ImmutableMultiset.Builder<Object> builder = ImmutableMultiset.builder();
703           for (Object o : keys) {
704             builder.add(o);
705           }
706           return builder.build();
707         }
708       },
709       BUILDER_ADD_ALL_COLLECTION {
710         @Override
create(List<?> keys)711         public ImmutableMultiset<Object> create(List<?> keys) {
712           ImmutableMultiset.Builder<Object> builder = ImmutableMultiset.builder();
713           builder.addAll(keys);
714           return builder.build();
715         }
716       };
717 
718       @CanIgnoreReturnValue
719       @Override
create(List<?> keys)720       public abstract ImmutableMultiset<Object> create(List<?> keys);
721     }
722   }
723 }
724