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