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