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