• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.collect.BoundType.CLOSED;
20 import static com.google.common.truth.Truth.assertThat;
21 import static java.util.Collections.sort;
22 
23 import com.google.common.annotations.GwtCompatible;
24 import com.google.common.annotations.GwtIncompatible;
25 import com.google.common.collect.testing.Helpers.NullsBeforeB;
26 import com.google.common.collect.testing.NavigableSetTestSuiteBuilder;
27 import com.google.common.collect.testing.TestStringSetGenerator;
28 import com.google.common.collect.testing.features.CollectionFeature;
29 import com.google.common.collect.testing.features.CollectionSize;
30 import com.google.common.collect.testing.google.MultisetFeature;
31 import com.google.common.collect.testing.google.SortedMultisetTestSuiteBuilder;
32 import com.google.common.collect.testing.google.TestStringMultisetGenerator;
33 import java.lang.reflect.Method;
34 import java.util.Arrays;
35 import java.util.Collections;
36 import java.util.Comparator;
37 import java.util.List;
38 import java.util.Set;
39 import java.util.SortedSet;
40 import junit.framework.Test;
41 import junit.framework.TestCase;
42 import junit.framework.TestSuite;
43 
44 /**
45  * Unit test for {@link TreeMultiset}.
46  *
47  * @author Neal Kanodia
48  */
49 @GwtCompatible(emulated = true)
50 public class TreeMultisetTest extends TestCase {
51 
52   @GwtIncompatible // suite
suite()53   public static Test suite() {
54     TestSuite suite = new TestSuite();
55     suite.addTest(
56         SortedMultisetTestSuiteBuilder.using(
57                 new TestStringMultisetGenerator() {
58                   @Override
59                   protected Multiset<String> create(String[] elements) {
60                     return TreeMultiset.create(Arrays.asList(elements));
61                   }
62 
63                   @Override
64                   public List<String> order(List<String> insertionOrder) {
65                     return Ordering.natural().sortedCopy(insertionOrder);
66                   }
67                 })
68             .withFeatures(
69                 CollectionSize.ANY,
70                 CollectionFeature.KNOWN_ORDER,
71                 CollectionFeature.GENERAL_PURPOSE,
72                 CollectionFeature.SERIALIZABLE,
73                 CollectionFeature.ALLOWS_NULL_QUERIES,
74                 MultisetFeature.ENTRIES_ARE_VIEWS)
75             .named("TreeMultiset, Ordering.natural")
76             .createTestSuite());
77     suite.addTest(
78         SortedMultisetTestSuiteBuilder.using(
79                 new TestStringMultisetGenerator() {
80                   @Override
81                   protected Multiset<String> create(String[] elements) {
82                     Multiset<String> result = TreeMultiset.create(NullsBeforeB.INSTANCE);
83                     Collections.addAll(result, elements);
84                     return result;
85                   }
86 
87                   @Override
88                   public List<String> order(List<String> insertionOrder) {
89                     sort(insertionOrder, NullsBeforeB.INSTANCE);
90                     return insertionOrder;
91                   }
92                 })
93             .withFeatures(
94                 CollectionSize.ANY,
95                 CollectionFeature.KNOWN_ORDER,
96                 CollectionFeature.GENERAL_PURPOSE,
97                 CollectionFeature.SERIALIZABLE,
98                 CollectionFeature.ALLOWS_NULL_VALUES,
99                 MultisetFeature.ENTRIES_ARE_VIEWS)
100             .named("TreeMultiset, NullsBeforeB")
101             .createTestSuite());
102     suite.addTest(
103         NavigableSetTestSuiteBuilder.using(
104                 new TestStringSetGenerator() {
105                   @Override
106                   protected Set<String> create(String[] elements) {
107                     return TreeMultiset.create(Arrays.asList(elements)).elementSet();
108                   }
109 
110                   @Override
111                   public List<String> order(List<String> insertionOrder) {
112                     return Lists.newArrayList(Sets.newTreeSet(insertionOrder));
113                   }
114                 })
115             .named("TreeMultiset[Ordering.natural].elementSet")
116             .withFeatures(
117                 CollectionSize.ANY,
118                 CollectionFeature.REMOVE_OPERATIONS,
119                 CollectionFeature.ALLOWS_NULL_QUERIES)
120             .createTestSuite());
121     suite.addTestSuite(TreeMultisetTest.class);
122     return suite;
123   }
124 
testCreate()125   public void testCreate() {
126     TreeMultiset<String> multiset = TreeMultiset.create();
127     multiset.add("foo", 2);
128     multiset.add("bar");
129     assertEquals(3, multiset.size());
130     assertEquals(2, multiset.count("foo"));
131     assertEquals(Ordering.natural(), multiset.comparator());
132     assertEquals("[bar, foo x 2]", multiset.toString());
133   }
134 
testCreateWithComparator()135   public void testCreateWithComparator() {
136     Multiset<String> multiset = TreeMultiset.create(Collections.reverseOrder());
137     multiset.add("foo", 2);
138     multiset.add("bar");
139     assertEquals(3, multiset.size());
140     assertEquals(2, multiset.count("foo"));
141     assertEquals("[foo x 2, bar]", multiset.toString());
142   }
143 
testCreateFromIterable()144   public void testCreateFromIterable() {
145     Multiset<String> multiset = TreeMultiset.create(Arrays.asList("foo", "bar", "foo"));
146     assertEquals(3, multiset.size());
147     assertEquals(2, multiset.count("foo"));
148     assertEquals("[bar, foo x 2]", multiset.toString());
149   }
150 
testToString()151   public void testToString() {
152     Multiset<String> ms = TreeMultiset.create();
153     ms.add("a", 3);
154     ms.add("c", 1);
155     ms.add("b", 2);
156 
157     assertEquals("[a x 3, b x 2, c]", ms.toString());
158   }
159 
testElementSetSortedSetMethods()160   public void testElementSetSortedSetMethods() {
161     TreeMultiset<String> ms = TreeMultiset.create();
162     ms.add("c", 1);
163     ms.add("a", 3);
164     ms.add("b", 2);
165     SortedSet<String> elementSet = ms.elementSet();
166 
167     assertEquals("a", elementSet.first());
168     assertEquals("c", elementSet.last());
169     assertEquals(Ordering.natural(), elementSet.comparator());
170 
171     assertThat(elementSet.headSet("b")).containsExactly("a");
172     assertThat(elementSet.tailSet("b")).containsExactly("b", "c").inOrder();
173     assertThat(elementSet.subSet("a", "c")).containsExactly("a", "b").inOrder();
174   }
175 
testElementSetSubsetRemove()176   public void testElementSetSubsetRemove() {
177     TreeMultiset<String> ms = TreeMultiset.create();
178     ms.add("a", 1);
179     ms.add("b", 3);
180     ms.add("c", 2);
181     ms.add("d", 1);
182     ms.add("e", 3);
183     ms.add("f", 2);
184 
185     SortedSet<String> elementSet = ms.elementSet();
186     assertThat(elementSet).containsExactly("a", "b", "c", "d", "e", "f").inOrder();
187     SortedSet<String> subset = elementSet.subSet("b", "f");
188     assertThat(subset).containsExactly("b", "c", "d", "e").inOrder();
189 
190     assertTrue(subset.remove("c"));
191     assertThat(elementSet).containsExactly("a", "b", "d", "e", "f").inOrder();
192     assertThat(subset).containsExactly("b", "d", "e").inOrder();
193     assertEquals(10, ms.size());
194 
195     assertFalse(subset.remove("a"));
196     assertThat(elementSet).containsExactly("a", "b", "d", "e", "f").inOrder();
197     assertThat(subset).containsExactly("b", "d", "e").inOrder();
198     assertEquals(10, ms.size());
199   }
200 
testElementSetSubsetRemoveAll()201   public void testElementSetSubsetRemoveAll() {
202     TreeMultiset<String> ms = TreeMultiset.create();
203     ms.add("a", 1);
204     ms.add("b", 3);
205     ms.add("c", 2);
206     ms.add("d", 1);
207     ms.add("e", 3);
208     ms.add("f", 2);
209 
210     SortedSet<String> elementSet = ms.elementSet();
211     assertThat(elementSet).containsExactly("a", "b", "c", "d", "e", "f").inOrder();
212     SortedSet<String> subset = elementSet.subSet("b", "f");
213     assertThat(subset).containsExactly("b", "c", "d", "e").inOrder();
214 
215     assertTrue(subset.removeAll(Arrays.asList("a", "c")));
216     assertThat(elementSet).containsExactly("a", "b", "d", "e", "f").inOrder();
217     assertThat(subset).containsExactly("b", "d", "e").inOrder();
218     assertEquals(10, ms.size());
219   }
220 
testElementSetSubsetRetainAll()221   public void testElementSetSubsetRetainAll() {
222     TreeMultiset<String> ms = TreeMultiset.create();
223     ms.add("a", 1);
224     ms.add("b", 3);
225     ms.add("c", 2);
226     ms.add("d", 1);
227     ms.add("e", 3);
228     ms.add("f", 2);
229 
230     SortedSet<String> elementSet = ms.elementSet();
231     assertThat(elementSet).containsExactly("a", "b", "c", "d", "e", "f").inOrder();
232     SortedSet<String> subset = elementSet.subSet("b", "f");
233     assertThat(subset).containsExactly("b", "c", "d", "e").inOrder();
234 
235     assertTrue(subset.retainAll(Arrays.asList("a", "c")));
236     assertThat(elementSet).containsExactly("a", "c", "f").inOrder();
237     assertThat(subset).containsExactly("c");
238     assertEquals(5, ms.size());
239   }
240 
testElementSetSubsetClear()241   public void testElementSetSubsetClear() {
242     TreeMultiset<String> ms = TreeMultiset.create();
243     ms.add("a", 1);
244     ms.add("b", 3);
245     ms.add("c", 2);
246     ms.add("d", 1);
247     ms.add("e", 3);
248     ms.add("f", 2);
249 
250     SortedSet<String> elementSet = ms.elementSet();
251     assertThat(elementSet).containsExactly("a", "b", "c", "d", "e", "f").inOrder();
252     SortedSet<String> subset = elementSet.subSet("b", "f");
253     assertThat(subset).containsExactly("b", "c", "d", "e").inOrder();
254 
255     subset.clear();
256     assertThat(elementSet).containsExactly("a", "f").inOrder();
257     assertThat(subset).isEmpty();
258     assertEquals(3, ms.size());
259   }
260 
testCustomComparator()261   public void testCustomComparator() throws Exception {
262     Comparator<String> comparator =
263         new Comparator<String>() {
264           @Override
265           public int compare(String o1, String o2) {
266             return o2.compareTo(o1);
267           }
268         };
269     TreeMultiset<String> ms = TreeMultiset.create(comparator);
270 
271     ms.add("b");
272     ms.add("c");
273     ms.add("a");
274     ms.add("b");
275     ms.add("d");
276 
277     assertThat(ms).containsExactly("d", "c", "b", "b", "a").inOrder();
278 
279     SortedSet<String> elementSet = ms.elementSet();
280     assertEquals("d", elementSet.first());
281     assertEquals("a", elementSet.last());
282     assertEquals(comparator, elementSet.comparator());
283   }
284 
testNullAcceptingComparator()285   public void testNullAcceptingComparator() throws Exception {
286     Comparator<String> comparator = Ordering.<String>natural().nullsFirst();
287     TreeMultiset<String> ms = TreeMultiset.create(comparator);
288 
289     ms.add("b");
290     ms.add(null);
291     ms.add("a");
292     ms.add("b");
293     ms.add(null, 2);
294 
295     assertThat(ms).containsExactly(null, null, null, "a", "b", "b").inOrder();
296     assertEquals(3, ms.count(null));
297 
298     SortedSet<String> elementSet = ms.elementSet();
299     assertEquals(null, elementSet.first());
300     assertEquals("b", elementSet.last());
301     assertEquals(comparator, elementSet.comparator());
302   }
303 
304   private static final Comparator<String> DEGENERATE_COMPARATOR =
305       new Comparator<String>() {
306         @Override
307         public int compare(String o1, String o2) {
308           return o1.length() - o2.length();
309         }
310       };
311 
312   /** Test a TreeMultiset with a comparator that can return 0 when comparing unequal values. */
testDegenerateComparator()313   public void testDegenerateComparator() throws Exception {
314     TreeMultiset<String> ms = TreeMultiset.create(DEGENERATE_COMPARATOR);
315 
316     ms.add("foo");
317     ms.add("a");
318     ms.add("bar");
319     ms.add("b");
320     ms.add("c");
321 
322     assertEquals(2, ms.count("bar"));
323     assertEquals(3, ms.count("b"));
324 
325     Multiset<String> ms2 = TreeMultiset.create(DEGENERATE_COMPARATOR);
326 
327     ms2.add("cat", 2);
328     ms2.add("x", 3);
329 
330     assertEquals(ms, ms2);
331     assertEquals(ms2, ms);
332 
333     SortedSet<String> elementSet = ms.elementSet();
334     assertEquals("a", elementSet.first());
335     assertEquals("foo", elementSet.last());
336     assertEquals(DEGENERATE_COMPARATOR, elementSet.comparator());
337   }
338 
testSubMultisetSize()339   public void testSubMultisetSize() {
340     TreeMultiset<String> ms = TreeMultiset.create();
341     ms.add("a", Integer.MAX_VALUE);
342     ms.add("b", Integer.MAX_VALUE);
343     ms.add("c", 3);
344 
345     assertEquals(Integer.MAX_VALUE, ms.count("a"));
346     assertEquals(Integer.MAX_VALUE, ms.count("b"));
347     assertEquals(3, ms.count("c"));
348 
349     assertEquals(Integer.MAX_VALUE, ms.headMultiset("c", CLOSED).size());
350     assertEquals(Integer.MAX_VALUE, ms.headMultiset("b", CLOSED).size());
351     assertEquals(Integer.MAX_VALUE, ms.headMultiset("a", CLOSED).size());
352 
353     assertEquals(3, ms.tailMultiset("c", CLOSED).size());
354     assertEquals(Integer.MAX_VALUE, ms.tailMultiset("b", CLOSED).size());
355     assertEquals(Integer.MAX_VALUE, ms.tailMultiset("a", CLOSED).size());
356   }
357 
358   @GwtIncompatible // reflection
359   @AndroidIncompatible // Reflection bug, or actual binary compatibility problem?
testElementSetBridgeMethods()360   public void testElementSetBridgeMethods() {
361     for (Method m : TreeMultiset.class.getMethods()) {
362       if (m.getName().equals("elementSet") && m.getReturnType().equals(SortedSet.class)) {
363         return;
364       }
365     }
366     fail("No bridge method found");
367   }
368 }
369