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
17package com.google.common.collect;
18
19import static org.truth0.Truth.ASSERT;
20
21import com.google.common.annotations.GwtCompatible;
22import com.google.common.annotations.GwtIncompatible;
23import com.google.common.collect.testing.DerivedComparable;
24import com.google.common.testing.NullPointerTester;
25
26import junit.framework.TestCase;
27
28import java.util.Arrays;
29import java.util.Collections;
30
31/**
32 * Tests for {@link Multisets}.
33 *
34 * @author Mike Bostock
35 * @author Jared Levy
36 * @author Louis Wasserman
37 */
38@GwtCompatible(emulated = true)
39public class MultisetsTest extends TestCase {
40
41  /* See MultisetsImmutableEntryTest for immutableEntry() tests. */
42
43  public void testNewTreeMultisetDerived() {
44    TreeMultiset<DerivedComparable> set = TreeMultiset.create();
45    assertTrue(set.isEmpty());
46    set.add(new DerivedComparable("foo"), 2);
47    set.add(new DerivedComparable("bar"), 3);
48    ASSERT.that(set).has().exactly(
49        new DerivedComparable("bar"), new DerivedComparable("bar"), new DerivedComparable("bar"),
50        new DerivedComparable("foo"), new DerivedComparable("foo")).inOrder();
51  }
52
53  public void testNewTreeMultisetNonGeneric() {
54    TreeMultiset<LegacyComparable> set = TreeMultiset.create();
55    assertTrue(set.isEmpty());
56    set.add(new LegacyComparable("foo"), 2);
57    set.add(new LegacyComparable("bar"), 3);
58    ASSERT.that(set).has().exactly(new LegacyComparable("bar"),
59        new LegacyComparable("bar"), new LegacyComparable("bar"),
60        new LegacyComparable("foo"), new LegacyComparable("foo")).inOrder();
61  }
62
63  public void testNewTreeMultisetComparator() {
64    TreeMultiset<String> multiset
65        = TreeMultiset.create(Collections.reverseOrder());
66    multiset.add("bar", 3);
67    multiset.add("foo", 2);
68    ASSERT.that(multiset).has().exactly("foo", "foo", "bar", "bar", "bar").inOrder();
69  }
70
71  public void testRetainOccurrencesEmpty() {
72    Multiset<String> multiset = HashMultiset.create();
73    Multiset<String> toRetain =
74        HashMultiset.create(Arrays.asList("a", "b", "a"));
75    assertFalse(Multisets.retainOccurrences(multiset, toRetain));
76    ASSERT.that(multiset).isEmpty();
77  }
78
79  public void testRemoveOccurrencesEmpty() {
80    Multiset<String> multiset = HashMultiset.create();
81    Multiset<String> toRemove =
82        HashMultiset.create(Arrays.asList("a", "b", "a"));
83    assertFalse(Multisets.retainOccurrences(multiset, toRemove));
84    assertTrue(multiset.isEmpty());
85  }
86
87  public void testUnion() {
88    Multiset<String> ms1 = HashMultiset.create(Arrays.asList("a", "b", "a"));
89    Multiset<String> ms2 = HashMultiset.create(
90        Arrays.asList("a", "b", "b", "c"));
91    ASSERT.that(Multisets.union(ms1, ms2)).has().exactly("a", "a", "b", "b", "c");
92  }
93
94  public void testUnionEqualMultisets() {
95    Multiset<String> ms1 = HashMultiset.create(Arrays.asList("a", "b", "a"));
96    Multiset<String> ms2 = HashMultiset.create(Arrays.asList("a", "b", "a"));
97    assertEquals(ms1, Multisets.union(ms1, ms2));
98  }
99
100  public void testUnionEmptyNonempty() {
101    Multiset<String> ms1 = HashMultiset.create();
102    Multiset<String> ms2 = HashMultiset.create(Arrays.asList("a", "b", "a"));
103    assertEquals(ms2, Multisets.union(ms1, ms2));
104  }
105
106  public void testUnionNonemptyEmpty() {
107    Multiset<String> ms1 = HashMultiset.create(Arrays.asList("a", "b", "a"));
108    Multiset<String> ms2 = HashMultiset.create();
109    assertEquals(ms1, Multisets.union(ms1, ms2));
110  }
111
112  public void testIntersectEmptyNonempty() {
113    Multiset<String> ms1 = HashMultiset.create();
114    Multiset<String> ms2 = HashMultiset.create(Arrays.asList("a", "b", "a"));
115    ASSERT.that(Multisets.intersection(ms1, ms2)).isEmpty();
116  }
117
118  public void testIntersectNonemptyEmpty() {
119    Multiset<String> ms1 = HashMultiset.create(Arrays.asList("a", "b", "a"));
120    Multiset<String> ms2 = HashMultiset.create();
121    ASSERT.that(Multisets.intersection(ms1, ms2)).isEmpty();
122  }
123
124  public void testSum() {
125    Multiset<String> ms1 = HashMultiset.create(Arrays.asList("a", "b", "a"));
126    Multiset<String> ms2 = HashMultiset.create(Arrays.asList("b", "c"));
127    ASSERT.that(Multisets.sum(ms1, ms2)).has().exactly("a", "a", "b", "b", "c");
128  }
129
130  public void testSumEmptyNonempty() {
131    Multiset<String> ms1 = HashMultiset.create();
132    Multiset<String> ms2 = HashMultiset.create(Arrays.asList("a", "b", "a"));
133    ASSERT.that(Multisets.sum(ms1, ms2)).has().exactly("a", "b", "a");
134  }
135
136  public void testSumNonemptyEmpty() {
137    Multiset<String> ms1 = HashMultiset.create(Arrays.asList("a", "b", "a"));
138    Multiset<String> ms2 = HashMultiset.create();
139    ASSERT.that(Multisets.sum(ms1, ms2)).has().exactly("a", "b", "a");
140  }
141
142  public void testDifferenceWithNoRemovedElements() {
143    Multiset<String> ms1 = HashMultiset.create(Arrays.asList("a", "b", "a"));
144    Multiset<String> ms2 = HashMultiset.create(Arrays.asList("a"));
145    ASSERT.that(Multisets.difference(ms1, ms2)).has().exactly("a", "b");
146  }
147
148  public void testDifferenceWithRemovedElement() {
149    Multiset<String> ms1 = HashMultiset.create(Arrays.asList("a", "b", "a"));
150    Multiset<String> ms2 = HashMultiset.create(Arrays.asList("b"));
151    ASSERT.that(Multisets.difference(ms1, ms2)).has().exactly("a", "a");
152  }
153
154  public void testDifferenceWithMoreElementsInSecondMultiset() {
155    Multiset<String> ms1 = HashMultiset.create(Arrays.asList("a", "b", "a"));
156    Multiset<String> ms2 = HashMultiset.create(Arrays.asList("a", "b", "b", "b"));
157    Multiset<String> diff = Multisets.difference(ms1, ms2);
158    ASSERT.that(diff).has().item("a");
159    assertEquals(0, diff.count("b"));
160    assertEquals(1, diff.count("a"));
161    assertFalse(diff.contains("b"));
162    assertTrue(diff.contains("a"));
163  }
164
165  public void testDifferenceEmptyNonempty() {
166    Multiset<String> ms1 = HashMultiset.create();
167    Multiset<String> ms2 = HashMultiset.create(Arrays.asList("a", "b", "a"));
168    assertEquals(ms1, Multisets.difference(ms1, ms2));
169  }
170
171  public void testDifferenceNonemptyEmpty() {
172    Multiset<String> ms1 = HashMultiset.create(Arrays.asList("a", "b", "a"));
173    Multiset<String> ms2 = HashMultiset.create();
174    assertEquals(ms1, Multisets.difference(ms1, ms2));
175  }
176
177  public void testContainsOccurrencesEmpty() {
178    Multiset<String> superMultiset = HashMultiset.create(Arrays.asList("a", "b", "a"));
179    Multiset<String> subMultiset = HashMultiset.create();
180    assertTrue(Multisets.containsOccurrences(superMultiset, subMultiset));
181    assertFalse(Multisets.containsOccurrences(subMultiset, superMultiset));
182  }
183
184  public void testContainsOccurrences() {
185    Multiset<String> superMultiset = HashMultiset.create(Arrays.asList("a", "b", "a"));
186    Multiset<String> subMultiset = HashMultiset.create(Arrays.asList("a", "b"));
187    assertTrue(Multisets.containsOccurrences(superMultiset, subMultiset));
188    assertFalse(Multisets.containsOccurrences(subMultiset, superMultiset));
189    Multiset<String> diffMultiset = HashMultiset.create(Arrays.asList("a", "b", "c"));
190    assertFalse(Multisets.containsOccurrences(superMultiset, diffMultiset));
191    assertTrue(Multisets.containsOccurrences(diffMultiset, subMultiset));
192  }
193
194  public void testRetainEmptyOccurrences() {
195    Multiset<String> multiset =
196        HashMultiset.create(Arrays.asList("a", "b", "a"));
197    Multiset<String> toRetain = HashMultiset.create();
198    assertTrue(Multisets.retainOccurrences(multiset, toRetain));
199    assertTrue(multiset.isEmpty());
200  }
201
202  public void testRetainOccurrences() {
203    Multiset<String> multiset =
204        TreeMultiset.create(Arrays.asList("a", "b", "a", "c"));
205    Multiset<String> toRetain =
206        HashMultiset.create(Arrays.asList("a", "b", "b"));
207    assertTrue(Multisets.retainOccurrences(multiset, toRetain));
208    ASSERT.that(multiset).has().exactly("a", "b").inOrder();
209  }
210
211  public void testRemoveEmptyOccurrences() {
212    Multiset<String> multiset =
213        TreeMultiset.create(Arrays.asList("a", "b", "a"));
214    Multiset<String> toRemove = HashMultiset.create();
215    assertFalse(Multisets.removeOccurrences(multiset, toRemove));
216    ASSERT.that(multiset).has().exactly("a", "a", "b").inOrder();
217  }
218
219  public void testRemoveOccurrences() {
220    Multiset<String> multiset =
221        TreeMultiset.create(Arrays.asList("a", "b", "a", "c"));
222    Multiset<String> toRemove =
223        HashMultiset.create(Arrays.asList("a", "b", "b"));
224    assertTrue(Multisets.removeOccurrences(multiset, toRemove));
225    ASSERT.that(multiset).has().exactly("a", "c").inOrder();
226  }
227
228  @SuppressWarnings("deprecation")
229  public void testUnmodifiableMultisetShortCircuit() {
230    Multiset<String> mod = HashMultiset.create();
231    Multiset<String> unmod = Multisets.unmodifiableMultiset(mod);
232    assertNotSame(mod, unmod);
233    assertSame(unmod, Multisets.unmodifiableMultiset(unmod));
234    ImmutableMultiset<String> immutable = ImmutableMultiset.of("a", "a", "b", "a");
235    assertSame(immutable, Multisets.unmodifiableMultiset(immutable));
236    assertSame(immutable, Multisets.unmodifiableMultiset((Multiset<String>) immutable));
237  }
238
239  public void testHighestCountFirst() {
240    Multiset<String> multiset = HashMultiset.create(
241        Arrays.asList("a", "a", "a", "b", "c", "c"));
242    ImmutableMultiset<String> sortedMultiset =
243        Multisets.copyHighestCountFirst(multiset);
244
245    ASSERT.that(sortedMultiset.entrySet()).has().exactly(
246        Multisets.immutableEntry("a", 3), Multisets.immutableEntry("c", 2),
247        Multisets.immutableEntry("b", 1)).inOrder();
248
249    ASSERT.that(sortedMultiset).has().exactly(
250        "a",
251        "a",
252        "a",
253        "c",
254        "c",
255        "b").inOrder();
256
257    ASSERT.that(Multisets.copyHighestCountFirst(ImmutableMultiset.of())).isEmpty();
258  }
259
260  @GwtIncompatible("NullPointerTester")
261  public void testNullPointers() {
262    new NullPointerTester().testAllPublicStaticMethods(Multisets.class);
263  }
264}
265