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 17 package com.google.common.collect; 18 19 import static com.google.common.collect.Maps.newHashMap; 20 import static com.google.common.collect.testing.features.CollectionFeature.ALLOWS_NULL_VALUES; 21 import static com.google.common.collect.testing.features.CollectionFeature.REMOVE_OPERATIONS; 22 import static com.google.common.collect.testing.google.AbstractMultisetSetCountTester.getSetCountDuplicateInitializingMethods; 23 import static com.google.common.collect.testing.google.MultisetIteratorTester.getIteratorDuplicateInitializingMethods; 24 import static com.google.common.collect.testing.google.MultisetReadsTester.getReadsDuplicateInitializingMethods; 25 import static java.lang.reflect.Proxy.newProxyInstance; 26 27 import com.google.common.annotations.GwtIncompatible; 28 import com.google.common.base.Functions; 29 import com.google.common.base.Predicate; 30 import com.google.common.base.Supplier; 31 import com.google.common.collect.testing.CollectionTestSuiteBuilder; 32 import com.google.common.collect.testing.ListTestSuiteBuilder; 33 import com.google.common.collect.testing.SampleElements; 34 import com.google.common.collect.testing.SetTestSuiteBuilder; 35 import com.google.common.collect.testing.TestCollectionGenerator; 36 import com.google.common.collect.testing.TestListGenerator; 37 import com.google.common.collect.testing.TestStringCollectionGenerator; 38 import com.google.common.collect.testing.TestStringListGenerator; 39 import com.google.common.collect.testing.TestStringSetGenerator; 40 import com.google.common.collect.testing.TestStringSortedSetGenerator; 41 import com.google.common.collect.testing.features.CollectionFeature; 42 import com.google.common.collect.testing.features.CollectionSize; 43 import com.google.common.collect.testing.features.Feature; 44 import com.google.common.collect.testing.features.ListFeature; 45 import com.google.common.collect.testing.google.MultisetTestSuiteBuilder; 46 import com.google.common.collect.testing.google.MultisetWritesTester; 47 import com.google.common.collect.testing.google.TestStringMultisetGenerator; 48 import com.google.common.collect.testing.testers.CollectionIteratorTester; 49 50 import junit.framework.Test; 51 import junit.framework.TestCase; 52 import junit.framework.TestSuite; 53 54 import java.lang.reflect.InvocationHandler; 55 import java.lang.reflect.Method; 56 import java.util.Collection; 57 import java.util.Collections; 58 import java.util.List; 59 import java.util.Map; 60 import java.util.Map.Entry; 61 import java.util.Set; 62 import java.util.SortedSet; 63 import java.util.TreeSet; 64 65 /** 66 * Run collection tests on {@link Multimap} implementations. 67 * 68 * @author Jared Levy 69 */ 70 @GwtIncompatible("suite") // TODO(cpovirk): set up collect/gwt/suites version 71 public class MultimapCollectionTest extends TestCase { 72 73 private static final Feature<?>[] COLLECTION_FEATURES = { 74 CollectionSize.ANY, 75 CollectionFeature.ALLOWS_NULL_VALUES, 76 CollectionFeature.GENERAL_PURPOSE 77 }; 78 79 static final Feature<?>[] COLLECTION_FEATURES_ORDER = { 80 CollectionSize.ANY, 81 CollectionFeature.ALLOWS_NULL_VALUES, 82 CollectionFeature.KNOWN_ORDER, 83 CollectionFeature.GENERAL_PURPOSE 84 }; 85 static final Feature<?>[] COLLECTION_FEATURES_REMOVE = { 86 CollectionSize.ANY, 87 CollectionFeature.ALLOWS_NULL_VALUES, 88 CollectionFeature.REMOVE_OPERATIONS 89 }; 90 91 static final Feature<?>[] COLLECTION_FEATURES_REMOVE_ORDER = { 92 CollectionSize.ANY, 93 CollectionFeature.ALLOWS_NULL_VALUES, 94 CollectionFeature.KNOWN_ORDER, 95 CollectionFeature.REMOVE_OPERATIONS 96 }; 97 98 private static final Feature<?>[] LIST_FEATURES = { 99 CollectionSize.ANY, 100 CollectionFeature.ALLOWS_NULL_VALUES, 101 ListFeature.GENERAL_PURPOSE 102 }; 103 104 private static final Feature<?>[] LIST_FEATURES_REMOVE_SET = { 105 CollectionSize.ANY, 106 CollectionFeature.ALLOWS_NULL_VALUES, 107 ListFeature.REMOVE_OPERATIONS, 108 ListFeature.SUPPORTS_SET 109 }; 110 111 private static final Feature<?>[] FOR_MAP_FEATURES_ONE = { 112 CollectionSize.ONE, 113 ALLOWS_NULL_VALUES, 114 REMOVE_OPERATIONS, 115 }; 116 117 private static final Feature<?>[] FOR_MAP_FEATURES_ANY = { 118 CollectionSize.ANY, 119 ALLOWS_NULL_VALUES, 120 REMOVE_OPERATIONS, 121 }; 122 123 static final Supplier<TreeSet<String>> STRING_TREESET_FACTORY 124 = new Supplier<TreeSet<String>>() { 125 @Override 126 public TreeSet<String> get() { 127 return new TreeSet<String>(Ordering.natural().nullsLast()); 128 } 129 }; 130 131 static void populateMultimapForGet( 132 Multimap<Integer, String> multimap, String[] elements) { 133 multimap.put(2, "foo"); 134 for (String element : elements) { 135 multimap.put(3, element); 136 } 137 } 138 139 static void populateMultimapForKeySet( 140 Multimap<String, Integer> multimap, String[] elements) { 141 for (String element : elements) { 142 multimap.put(element, 2); 143 multimap.put(element, 3); 144 } 145 } 146 147 static void populateMultimapForValues( 148 Multimap<Integer, String> multimap, String[] elements) { 149 for (int i = 0; i < elements.length; i++) { 150 multimap.put(i % 2, elements[i]); 151 } 152 } 153 154 static void populateMultimapForKeys( 155 Multimap<String, Integer> multimap, String[] elements) { 156 for (int i = 0; i < elements.length; i++) { 157 multimap.put(elements[i], i); 158 } 159 } 160 161 /** 162 * Implements {@code Multimap.put()} -- and no other methods -- for a {@code 163 * Map} by ignoring all but the latest value for each key. This class exists 164 * only so that we can use 165 * {@link MultimapCollectionTest#populateMultimapForGet(Multimap, String[])} 166 * and similar methods to populate a map to be passed to 167 * {@link Multimaps#forMap(Map)}. All tests should run against the result of 168 * {@link #build()}. 169 */ 170 private static final class PopulatableMapAsMultimap<K, V> 171 extends ForwardingMultimap<K, V> { 172 final Map<K, V> map; 173 final SetMultimap<K, V> unusableDelegate; 174 175 static <K, V> PopulatableMapAsMultimap<K, V> create() { 176 return new PopulatableMapAsMultimap<K, V>(); 177 } 178 179 @SuppressWarnings("unchecked") // all methods throw immediately 180 PopulatableMapAsMultimap() { 181 this.map = newHashMap(); 182 this.unusableDelegate = (SetMultimap<K, V>) newProxyInstance( 183 SetMultimap.class.getClassLoader(), 184 new Class<?>[] {SetMultimap.class}, 185 new InvocationHandler() { 186 @Override 187 public Object invoke(Object proxy, Method method, Object[] args) 188 throws Throwable { 189 throw new UnsupportedOperationException(); 190 } 191 }); 192 } 193 194 @Override protected Multimap<K, V> delegate() { 195 return unusableDelegate; 196 } 197 198 @Override public boolean put(K key, V value) { 199 map.put(key, value); 200 return true; 201 } 202 203 SetMultimap<K, V> build() { 204 return Multimaps.forMap(map); 205 } 206 } 207 208 static abstract class TestEntriesGenerator 209 implements TestCollectionGenerator<Entry<String, Integer>> { 210 @Override 211 public SampleElements<Entry<String, Integer>> samples() { 212 return new SampleElements<Entry<String, Integer>>( 213 Maps.immutableEntry("bar", 1), 214 Maps.immutableEntry("bar", 2), 215 Maps.immutableEntry("foo", 3), 216 Maps.immutableEntry("bar", 3), 217 Maps.immutableEntry("cat", 2)); 218 } 219 220 @Override 221 public Collection<Entry<String, Integer>> create(Object... elements) { 222 Multimap<String, Integer> multimap = createMultimap(); 223 for (Object element : elements) { 224 @SuppressWarnings("unchecked") 225 Entry<String, Integer> entry = (Entry<String, Integer>) element; 226 multimap.put(entry.getKey(), entry.getValue()); 227 } 228 return multimap.entries(); 229 } 230 231 abstract Multimap<String, Integer> createMultimap(); 232 233 @Override 234 @SuppressWarnings("unchecked") 235 public Entry<String, Integer>[] createArray(int length) { 236 return (Entry<String, Integer>[]) new Entry<?, ?>[length]; 237 } 238 239 @Override 240 public List<Entry<String, Integer>> order( 241 List<Entry<String, Integer>> insertionOrder) { 242 return insertionOrder; 243 } 244 } 245 246 public static abstract class TestEntriesListGenerator 247 extends TestEntriesGenerator 248 implements TestListGenerator<Entry<String, Integer>> { 249 @Override public List<Entry<String, Integer>> create(Object... elements) { 250 return (List<Entry<String, Integer>>) super.create(elements); 251 } 252 } 253 254 private static abstract class TestEntrySetGenerator 255 extends TestEntriesGenerator { 256 @Override abstract SetMultimap<String, Integer> createMultimap(); 257 258 @Override public Set<Entry<String, Integer>> create(Object... elements) { 259 return (Set<Entry<String, Integer>>) super.create(elements); 260 } 261 } 262 263 private static final Predicate<Map.Entry<Integer, String>> FILTER_GET_PREDICATE 264 = new Predicate<Map.Entry<Integer, String>>() { 265 @Override public boolean apply(Entry<Integer, String> entry) { 266 return !"badvalue".equals(entry.getValue()) && 55556 != entry.getKey(); 267 } 268 }; 269 270 private static final Predicate<Map.Entry<String, Integer>> FILTER_KEYSET_PREDICATE 271 = new Predicate<Map.Entry<String, Integer>>() { 272 @Override public boolean apply(Entry<String, Integer> entry) { 273 return !"badkey".equals(entry.getKey()) && 55556 != entry.getValue(); 274 } 275 }; 276 277 public static Test suite() { 278 TestSuite suite = new TestSuite(); 279 280 suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() { 281 @Override protected Set<String> create(String[] elements) { 282 SetMultimap<Integer, String> multimap = HashMultimap.create(); 283 populateMultimapForGet(multimap, elements); 284 return multimap.get(3); 285 } 286 }) 287 .named("HashMultimap.get") 288 .withFeatures(COLLECTION_FEATURES) 289 .createTestSuite()); 290 291 suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() { 292 @Override protected Set<String> create(String[] elements) { 293 SetMultimap<Integer, String> multimap 294 = LinkedHashMultimap.create(); 295 populateMultimapForGet(multimap, elements); 296 return multimap.get(3); 297 } 298 }) 299 .named("LinkedHashMultimap.get") 300 .withFeatures(COLLECTION_FEATURES_ORDER) 301 .createTestSuite()); 302 303 suite.addTest(SetTestSuiteBuilder.using( 304 new TestStringSortedSetGenerator() { 305 @Override protected SortedSet<String> create(String[] elements) { 306 SortedSetMultimap<Integer, String> multimap = 307 TreeMultimap.create(Ordering.natural().nullsFirst(), 308 Ordering.natural().nullsLast()); 309 populateMultimapForGet(multimap, elements); 310 return multimap.get(3); 311 } 312 }) 313 .named("TreeMultimap.get") 314 .withFeatures(COLLECTION_FEATURES_ORDER) 315 .createTestSuite()); 316 317 suite.addTest(ListTestSuiteBuilder.using(new TestStringListGenerator() { 318 @Override protected List<String> create(String[] elements) { 319 ListMultimap<Integer, String> multimap 320 = ArrayListMultimap.create(); 321 populateMultimapForGet(multimap, elements); 322 return multimap.get(3); 323 } 324 }) 325 .named("ArrayListMultimap.get") 326 .withFeatures(LIST_FEATURES) 327 .createTestSuite()); 328 329 suite.addTest(ListTestSuiteBuilder.using(new TestStringListGenerator() { 330 @Override protected List<String> create(String[] elements) { 331 ListMultimap<Integer, String> multimap 332 = Multimaps.synchronizedListMultimap( 333 ArrayListMultimap.<Integer, String>create()); 334 populateMultimapForGet(multimap, elements); 335 return multimap.get(3); 336 } 337 }) 338 .named("synchronized ArrayListMultimap.get") 339 .withFeatures(LIST_FEATURES) 340 .createTestSuite()); 341 342 suite.addTest(ListTestSuiteBuilder.using(new TestStringListGenerator() { 343 @Override protected List<String> create(String[] elements) { 344 ListMultimap<Integer, String> multimap 345 = LinkedListMultimap.create(); 346 populateMultimapForGet(multimap, elements); 347 return multimap.get(3); 348 } 349 }) 350 .named("LinkedListMultimap.get") 351 .withFeatures(LIST_FEATURES) 352 .createTestSuite()); 353 354 suite.addTest(ListTestSuiteBuilder.using(new TestStringListGenerator() { 355 @Override protected List<String> create(String[] elements) { 356 ImmutableListMultimap.Builder<Integer, String> builder 357 = ImmutableListMultimap.builder(); 358 ListMultimap<Integer, String> multimap 359 = builder.put(2, "foo") 360 .putAll(3, elements) 361 .build(); 362 return multimap.get(3); 363 } 364 }) 365 .named("ImmutableListMultimap.get") 366 .withFeatures(CollectionSize.ANY) 367 .createTestSuite()); 368 369 suite.addTest(SetTestSuiteBuilder.using( 370 new TestStringSetGenerator() { 371 @Override protected Set<String> create(String[] elements) { 372 PopulatableMapAsMultimap<Integer, String> multimap 373 = PopulatableMapAsMultimap.create(); 374 populateMultimapForGet(multimap, elements); 375 return multimap.build().get(3); 376 } 377 }) 378 .named("Multimaps.forMap.get") 379 .withFeatures(FOR_MAP_FEATURES_ONE) 380 .createTestSuite()); 381 382 suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() { 383 @Override protected Set<String> create(String[] elements) { 384 SetMultimap<Integer, String> multimap 385 = LinkedHashMultimap.create(); 386 populateMultimapForGet(multimap, elements); 387 multimap.put(3, "badvalue"); 388 multimap.put(55556, "foo"); 389 return (Set<String>) Multimaps.filterEntries(multimap, FILTER_GET_PREDICATE).get(3); 390 } 391 }) 392 .named("Multimaps.filterEntries.get") 393 .withFeatures(COLLECTION_FEATURES_ORDER) 394 .suppressing(CollectionIteratorTester.getIteratorKnownOrderRemoveSupportedMethod()) 395 .createTestSuite()); 396 397 suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() { 398 @Override protected Set<String> create(String[] elements) { 399 Multimap<String, Integer> multimap = HashMultimap.create(); 400 populateMultimapForKeySet(multimap, elements); 401 return multimap.keySet(); 402 } 403 }) 404 .named("HashMultimap.keySet") 405 .withFeatures(COLLECTION_FEATURES_REMOVE) 406 .createTestSuite()); 407 408 suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() { 409 @Override protected Set<String> create(String[] elements) { 410 Multimap<String, Integer> multimap 411 = LinkedHashMultimap.create(); 412 populateMultimapForKeySet(multimap, elements); 413 return multimap.keySet(); 414 } 415 }) 416 .named("LinkedHashMultimap.keySet") 417 .withFeatures(COLLECTION_FEATURES_REMOVE_ORDER) 418 .createTestSuite()); 419 420 suite.addTest(SetTestSuiteBuilder.using( 421 new TestStringSortedSetGenerator() { 422 @Override protected SortedSet<String> create(String[] elements) { 423 TreeMultimap<String, Integer> multimap = 424 TreeMultimap.create(Ordering.natural().nullsFirst(), 425 Ordering.natural().nullsLast()); 426 populateMultimapForKeySet(multimap, elements); 427 return multimap.keySet(); 428 } 429 }) 430 .named("TreeMultimap.keySet") 431 .withFeatures(COLLECTION_FEATURES_REMOVE_ORDER) 432 .createTestSuite()); 433 434 suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() { 435 @Override protected Set<String> create(String[] elements) { 436 Multimap<String, Integer> multimap 437 = ArrayListMultimap.create(); 438 populateMultimapForKeySet(multimap, elements); 439 return multimap.keySet(); 440 } 441 }) 442 .named("ArrayListMultimap.keySet") 443 .withFeatures(COLLECTION_FEATURES_REMOVE) 444 .createTestSuite()); 445 446 suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() { 447 @Override protected Set<String> create(String[] elements) { 448 Multimap<String, Integer> multimap 449 = LinkedListMultimap.create(); 450 populateMultimapForKeySet(multimap, elements); 451 return multimap.keySet(); 452 } 453 }) 454 .named("LinkedListMultimap.keySet") 455 .withFeatures(COLLECTION_FEATURES_REMOVE_ORDER) 456 .createTestSuite()); 457 458 suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() { 459 @Override protected Set<String> create(String[] elements) { 460 ImmutableListMultimap.Builder<String, Integer> builder 461 = ImmutableListMultimap.builder(); 462 for (String element : elements) { 463 builder.put(element, 2); 464 builder.put(element, 3); 465 } 466 Multimap<String, Integer> multimap = builder.build(); 467 return multimap.keySet(); 468 } 469 }) 470 .named("ImmutableListMultimap.keySet") 471 .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER) 472 .createTestSuite()); 473 474 suite.addTest(SetTestSuiteBuilder.using( 475 new TestStringSetGenerator() { 476 @Override protected Set<String> create(String[] elements) { 477 PopulatableMapAsMultimap<String, Integer> multimap 478 = PopulatableMapAsMultimap.create(); 479 populateMultimapForKeySet(multimap, elements); 480 return multimap.build().keySet(); 481 } 482 }) 483 .named("Multimaps.forMap.keySet") 484 .withFeatures(FOR_MAP_FEATURES_ANY) 485 .createTestSuite()); 486 487 suite.addTest(SetTestSuiteBuilder.using( 488 new TestStringSetGenerator() { 489 @Override protected Set<String> create(String[] elements) { 490 SetMultimap<String, Integer> multimap = LinkedHashMultimap.create(); 491 populateMultimapForKeySet(multimap, elements); 492 multimap.put("badkey", 3); 493 multimap.put("a", 55556); 494 return Multimaps.filterEntries(multimap, FILTER_KEYSET_PREDICATE).keySet(); 495 } 496 }) 497 .named("Multimaps.filterEntries.keySet") 498 .withFeatures(COLLECTION_FEATURES_REMOVE_ORDER) 499 .suppressing(CollectionIteratorTester.getIteratorKnownOrderRemoveSupportedMethod()) 500 .createTestSuite()); 501 502 suite.addTest(CollectionTestSuiteBuilder.using( 503 new TestStringCollectionGenerator() { 504 @Override public Collection<String> create(String[] elements) { 505 Multimap<Integer, String> multimap = HashMultimap.create(); 506 populateMultimapForValues(multimap, elements); 507 return multimap.values(); 508 } 509 }) 510 .named("HashMultimap.values") 511 .withFeatures(COLLECTION_FEATURES_REMOVE) 512 .createTestSuite()); 513 514 suite.addTest(CollectionTestSuiteBuilder.using( 515 new TestStringCollectionGenerator() { 516 @Override public Collection<String> create(String[] elements) { 517 Multimap<Integer, String> multimap 518 = LinkedHashMultimap.create(); 519 populateMultimapForValues(multimap, elements); 520 return multimap.values(); 521 } 522 }) 523 .named("LinkedHashMultimap.values") 524 .withFeatures(COLLECTION_FEATURES_REMOVE_ORDER) 525 .createTestSuite()); 526 527 suite.addTest(CollectionTestSuiteBuilder.using( 528 new TestStringCollectionGenerator() { 529 @Override public Collection<String> create(String[] elements) { 530 Multimap<Integer, String> multimap 531 = TreeMultimap.create(Ordering.natural().nullsFirst(), 532 Ordering.natural().nullsLast()); 533 populateMultimapForValues(multimap, elements); 534 return multimap.values(); 535 } 536 }) 537 .named("TreeMultimap.values") 538 .withFeatures(COLLECTION_FEATURES_REMOVE) 539 .createTestSuite()); 540 541 suite.addTest(CollectionTestSuiteBuilder.using( 542 new TestStringCollectionGenerator() { 543 @Override public Collection<String> create(String[] elements) { 544 Multimap<Integer, String> multimap 545 = ArrayListMultimap.create(); 546 populateMultimapForValues(multimap, elements); 547 return multimap.values(); 548 } 549 }) 550 .named("ArrayListMultimap.values") 551 .withFeatures(COLLECTION_FEATURES_REMOVE) 552 .createTestSuite()); 553 554 suite.addTest(ListTestSuiteBuilder.using( 555 new TestStringListGenerator() { 556 @Override public List<String> create(String[] elements) { 557 LinkedListMultimap<Integer, String> multimap 558 = LinkedListMultimap.create(); 559 populateMultimapForValues(multimap, elements); 560 return multimap.values(); 561 } 562 }) 563 .named("LinkedListMultimap.values") 564 .withFeatures(LIST_FEATURES_REMOVE_SET) 565 .createTestSuite()); 566 567 suite.addTest(CollectionTestSuiteBuilder.using( 568 new TestStringCollectionGenerator() { 569 @Override public Collection<String> create(String[] elements) { 570 ImmutableListMultimap.Builder<Integer, String> builder 571 = ImmutableListMultimap.builder(); 572 for (int i = 0; i < elements.length; i++) { 573 builder.put(i % 2, elements[i]); 574 } 575 return builder.build().values(); 576 } 577 }) 578 .named("ImmutableListMultimap.values") 579 .withFeatures(CollectionSize.ANY) 580 .createTestSuite()); 581 582 suite.addTest(CollectionTestSuiteBuilder.using( 583 new TestStringCollectionGenerator() { 584 @Override public Collection<String> create(String[] elements) { 585 Multimap<Integer, String> multimap 586 = LinkedHashMultimap.create(); 587 populateMultimapForValues(multimap, elements); 588 multimap.put(3, "badvalue"); 589 multimap.put(55556, "foo"); 590 return Multimaps.filterEntries(multimap, FILTER_GET_PREDICATE).values(); 591 } 592 }) 593 .named("Multimaps.filterEntries.values") 594 .withFeatures(COLLECTION_FEATURES_REMOVE_ORDER) 595 .suppressing(CollectionIteratorTester.getIteratorKnownOrderRemoveSupportedMethod()) 596 .createTestSuite()); 597 598 // TODO: use collection testers on Multimaps.forMap.values 599 600 suite.addTest(MultisetTestSuiteBuilder.using( 601 new TestStringMultisetGenerator() { 602 @Override protected Multiset<String> create(String[] elements) { 603 Multimap<String, Integer> multimap = HashMultimap.create(); 604 populateMultimapForKeys(multimap, elements); 605 return multimap.keys(); 606 } 607 }) 608 .named("HashMultimap.keys") 609 .withFeatures(COLLECTION_FEATURES_REMOVE) 610 .createTestSuite()); 611 612 suite.addTest(MultisetTestSuiteBuilder.using( 613 new TestStringMultisetGenerator() { 614 @Override protected Multiset<String> create(String[] elements) { 615 Multimap<String, Integer> multimap 616 = LinkedHashMultimap.create(); 617 populateMultimapForKeys(multimap, elements); 618 return multimap.keys(); 619 } 620 }) 621 .named("LinkedHashMultimap.keys") 622 .withFeatures(COLLECTION_FEATURES_REMOVE_ORDER) 623 .createTestSuite()); 624 625 suite.addTest(MultisetTestSuiteBuilder.using( 626 new TestStringMultisetGenerator() { 627 @Override protected Multiset<String> create(String[] elements) { 628 Multimap<String, Integer> multimap 629 = TreeMultimap.create(Ordering.natural().nullsFirst(), 630 Ordering.natural().nullsLast()); 631 populateMultimapForKeys(multimap, elements); 632 return multimap.keys(); 633 } 634 635 @Override public List<String> order(List<String> insertionOrder) { 636 Collections.sort(insertionOrder, Ordering.natural().nullsFirst()); 637 return insertionOrder; 638 } 639 }) 640 .named("TreeMultimap.keys") 641 .withFeatures(COLLECTION_FEATURES_REMOVE_ORDER) 642 .createTestSuite()); 643 644 suite.addTest(MultisetTestSuiteBuilder.using( 645 new TestStringMultisetGenerator() { 646 @Override protected Multiset<String> create(String[] elements) { 647 Multimap<String, Integer> multimap 648 = ArrayListMultimap.create(); 649 populateMultimapForKeys(multimap, elements); 650 return multimap.keys(); 651 } 652 }) 653 .named("ArrayListMultimap.keys") 654 .withFeatures(COLLECTION_FEATURES_REMOVE) 655 .createTestSuite()); 656 657 suite.addTest(MultisetTestSuiteBuilder.using( 658 new TestStringMultisetGenerator() { 659 @Override protected Multiset<String> create(String[] elements) { 660 Multimap<String, Integer> multimap 661 = Multimaps.synchronizedListMultimap( 662 ArrayListMultimap.<String, Integer>create()); 663 populateMultimapForKeys(multimap, elements); 664 return multimap.keys(); 665 } 666 }) 667 .named("synchronized ArrayListMultimap.keys") 668 .withFeatures(COLLECTION_FEATURES_REMOVE) 669 .createTestSuite()); 670 671 suite.addTest(MultisetTestSuiteBuilder.using( 672 new TestStringMultisetGenerator() { 673 @Override protected Multiset<String> create(String[] elements) { 674 Multimap<String, Integer> multimap 675 = LinkedListMultimap.create(); 676 populateMultimapForKeys(multimap, elements); 677 return multimap.keys(); 678 } 679 }) 680 .named("LinkedListMultimap.keys") 681 .withFeatures(COLLECTION_FEATURES_REMOVE_ORDER) 682 .createTestSuite()); 683 684 suite.addTest(MultisetTestSuiteBuilder.using( 685 new TestStringMultisetGenerator() { 686 @Override protected Multiset<String> create(String[] elements) { 687 ImmutableListMultimap.Builder<String, Integer> builder 688 = ImmutableListMultimap.builder(); 689 for (int i = 0; i < elements.length; i++) { 690 builder.put(elements[i], i); 691 } 692 Multimap<String, Integer> multimap = builder.build(); 693 return multimap.keys(); 694 } 695 }) 696 .named("ImmutableListMultimap.keys") 697 .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER) 698 .createTestSuite()); 699 700 suite.addTest(MultisetTestSuiteBuilder.using( 701 new TestStringMultisetGenerator() { 702 @Override protected Multiset<String> create(String[] elements) { 703 PopulatableMapAsMultimap<String, Integer> multimap 704 = PopulatableMapAsMultimap.create(); 705 populateMultimapForKeys(multimap, elements); 706 return multimap.build().keys(); 707 } 708 }) 709 .named("Multimaps.forMap.keys") 710 .withFeatures(FOR_MAP_FEATURES_ANY) 711 .suppressing(getReadsDuplicateInitializingMethods()) 712 .suppressing(getSetCountDuplicateInitializingMethods()) 713 .suppressing(getIteratorDuplicateInitializingMethods()) 714 .createTestSuite()); 715 716 suite.addTest(MultisetTestSuiteBuilder.using( 717 new TestStringMultisetGenerator() { 718 @Override protected Multiset<String> create(String[] elements) { 719 SetMultimap<String, Integer> multimap = LinkedHashMultimap.create(); 720 populateMultimapForKeys(multimap, elements); 721 multimap.put("badkey", 3); 722 multimap.put("a", 55556); 723 return Multimaps.filterEntries(multimap, FILTER_KEYSET_PREDICATE).keys(); 724 } 725 }) 726 .named("Multimaps.filterEntries.keys") 727 .withFeatures(COLLECTION_FEATURES_REMOVE_ORDER) 728 .suppressing(CollectionIteratorTester.getIteratorKnownOrderRemoveSupportedMethod()) 729 .suppressing(MultisetWritesTester.getEntrySetIteratorMethod()) 730 .suppressing(getIteratorDuplicateInitializingMethods()) 731 .createTestSuite()); 732 733 suite.addTest(CollectionTestSuiteBuilder.using( 734 new TestEntrySetGenerator() { 735 @Override SetMultimap<String, Integer> createMultimap() { 736 return HashMultimap.create(); 737 } 738 }) 739 .named("HashMultimap.entries") 740 .withFeatures(CollectionSize.ANY, CollectionFeature.REMOVE_OPERATIONS) 741 .createTestSuite()); 742 743 suite.addTest(CollectionTestSuiteBuilder.using( 744 new TestEntrySetGenerator() { 745 @Override SetMultimap<String, Integer> createMultimap() { 746 return LinkedHashMultimap.create(); 747 } 748 }) 749 .named("LinkedHashMultimap.entries") 750 .withFeatures(CollectionSize.ANY, CollectionFeature.REMOVE_OPERATIONS, 751 CollectionFeature.KNOWN_ORDER) 752 .createTestSuite()); 753 754 suite.addTest(CollectionTestSuiteBuilder.using( 755 new TestEntrySetGenerator() { 756 @Override SetMultimap<String, Integer> createMultimap() { 757 return TreeMultimap.create(Ordering.natural().nullsFirst(), 758 Ordering.natural().nullsLast()); 759 } 760 }) 761 .named("TreeMultimap.entries") 762 .withFeatures(CollectionSize.ANY, CollectionFeature.REMOVE_OPERATIONS, 763 CollectionFeature.KNOWN_ORDER) 764 .createTestSuite()); 765 766 suite.addTest(CollectionTestSuiteBuilder.using( 767 new TestEntriesGenerator() { 768 @Override Multimap<String, Integer> createMultimap() { 769 return ArrayListMultimap.create(); 770 } 771 }) 772 .named("ArrayListMultimap.entries") 773 .withFeatures(CollectionSize.ANY, CollectionFeature.REMOVE_OPERATIONS) 774 .createTestSuite()); 775 776 suite.addTest(CollectionTestSuiteBuilder.using( 777 new TestEntriesGenerator() { 778 @Override Multimap<String, Integer> createMultimap() { 779 return Multimaps.synchronizedListMultimap( 780 ArrayListMultimap.<String, Integer>create()); 781 } 782 }) 783 .named("synchronized ArrayListMultimap.entries") 784 .withFeatures(CollectionSize.ANY, CollectionFeature.REMOVE_OPERATIONS) 785 .createTestSuite()); 786 787 suite.addTest(ListTestSuiteBuilder.using( 788 new TestEntriesListGenerator() { 789 @Override Multimap<String, Integer> createMultimap() { 790 return LinkedListMultimap.create(); 791 } 792 }) 793 .named("LinkedListMultimap.entries") 794 .withFeatures(CollectionSize.ANY, ListFeature.REMOVE_OPERATIONS, 795 CollectionFeature.KNOWN_ORDER) 796 .createTestSuite()); 797 798 suite.addTest(CollectionTestSuiteBuilder.using( 799 new TestEntriesGenerator() { 800 @Override Multimap<String, Integer> createMultimap() { 801 return ImmutableListMultimap.of(); 802 } 803 804 @Override public Collection<Entry<String, Integer>> create( 805 Object... elements) { 806 ImmutableListMultimap.Builder<String, Integer> builder 807 = ImmutableListMultimap.builder(); 808 for (Object element : elements) { 809 @SuppressWarnings("unchecked") 810 Entry<String, Integer> entry = (Entry<String, Integer>) element; 811 builder.put(entry.getKey(), entry.getValue()); 812 } 813 return builder.build().entries(); 814 } 815 }) 816 .named("ImmutableListMultimap.entries") 817 .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER) 818 .createTestSuite()); 819 820 suite.addTest(CollectionTestSuiteBuilder.using( 821 new TestEntriesGenerator() { 822 @Override Multimap<String, Integer> createMultimap() { 823 Multimap<String, Integer> multimap = LinkedHashMultimap.create(); 824 multimap.put("badkey", 3); 825 multimap.put("a", 55556); 826 return Multimaps.filterEntries(multimap, FILTER_KEYSET_PREDICATE); 827 } 828 }) 829 .named("Multimap.filterEntries.entries") 830 .withFeatures(CollectionSize.ANY, CollectionFeature.REMOVE_OPERATIONS, 831 CollectionFeature.KNOWN_ORDER) 832 .suppressing(CollectionIteratorTester.getIteratorKnownOrderRemoveSupportedMethod()) 833 .createTestSuite()); 834 835 suite.addTest(ListTestSuiteBuilder.using(new TestStringListGenerator() { 836 @Override protected List<String> create(String[] elements) { 837 ListMultimap<Integer, String> multimap = ArrayListMultimap.create(); 838 populateMultimapForGet(multimap, elements); 839 return Multimaps.transformValues( 840 multimap, Functions.<String> identity()).get(3); 841 } 842 }).named("Multimaps.transformValues[ListMultimap].get").withFeatures( 843 CollectionSize.ANY, CollectionFeature.ALLOWS_NULL_VALUES, 844 CollectionFeature.REMOVE_OPERATIONS, 845 ListFeature.SUPPORTS_REMOVE_WITH_INDEX).createTestSuite()); 846 847 suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() { 848 @Override protected Set<String> create(String[] elements) { 849 ListMultimap<String, Integer> multimap = ArrayListMultimap.create(); 850 populateMultimapForKeySet(multimap, elements); 851 return Multimaps.transformValues( 852 multimap, Functions.<Integer> identity()).keySet(); 853 } 854 }).named("Multimaps.transformValues[ListMultimap].keySet").withFeatures( 855 CollectionSize.ANY, CollectionFeature.ALLOWS_NULL_VALUES, 856 CollectionFeature.REMOVE_OPERATIONS).createTestSuite()); 857 858 suite.addTest(MultisetTestSuiteBuilder.using( 859 new TestStringMultisetGenerator() { 860 @Override protected Multiset<String> create(String[] elements) { 861 ListMultimap<String, Integer> multimap 862 = ArrayListMultimap.create(); 863 populateMultimapForKeys(multimap, elements); 864 return Multimaps.transformValues( 865 multimap, Functions.<Integer> identity()).keys(); 866 } 867 }) 868 .named("Multimaps.transform[ListMultimap].keys") 869 .withFeatures(COLLECTION_FEATURES_REMOVE) 870 .createTestSuite()); 871 872 suite.addTest( 873 CollectionTestSuiteBuilder.using(new TestStringCollectionGenerator() { 874 @Override public Collection<String> create(String[] elements) { 875 ListMultimap<Integer, String> multimap = ArrayListMultimap.create(); 876 populateMultimapForValues(multimap, elements); 877 return Multimaps.transformValues( 878 multimap, Functions.<String> identity()).values(); 879 } 880 }).named("Multimaps.transformValues[ListMultimap].values").withFeatures( 881 COLLECTION_FEATURES_REMOVE).createTestSuite()); 882 883 suite.addTest(CollectionTestSuiteBuilder.using(new TestEntriesGenerator() { 884 @Override public Collection<Entry<String, Integer>> create( 885 Object... elements) { 886 ListMultimap<String, Integer> multimap = ArrayListMultimap.create(); 887 for (Object element : elements) { 888 @SuppressWarnings("unchecked") 889 Entry<String, Integer> entry = (Entry<String, Integer>) element; 890 multimap.put(entry.getKey(), entry.getValue()); 891 } 892 return Multimaps.transformValues( 893 multimap, Functions.<Integer> identity()).entries(); 894 } 895 896 @Override Multimap<String, Integer> createMultimap() { 897 return Multimaps.transformValues( 898 ArrayListMultimap.<String, Integer> create(), 899 Functions.<Integer> identity()); 900 } 901 }).named("Multimaps.transformValues[ListMultimap].entries") 902 .withFeatures(CollectionSize.ANY, CollectionFeature.REMOVE_OPERATIONS) 903 .createTestSuite()); 904 905 suite.addTest( 906 CollectionTestSuiteBuilder.using(new TestStringCollectionGenerator() { 907 @Override protected Collection<String> create(String[] elements) { 908 Multimap<Integer, String> multimap = ArrayListMultimap.create(); 909 populateMultimapForGet(multimap, elements); 910 return Multimaps.transformValues( 911 multimap, Functions.<String> identity()).get(3); 912 } 913 }).named("Multimaps.transformValues[Multimap].get").withFeatures( 914 CollectionSize.ANY, CollectionFeature.ALLOWS_NULL_VALUES, 915 CollectionFeature.REMOVE_OPERATIONS).createTestSuite()); 916 917 suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() { 918 @Override protected Set<String> create(String[] elements) { 919 Multimap<String, Integer> multimap = ArrayListMultimap.create(); 920 populateMultimapForKeySet(multimap, elements); 921 return Multimaps.transformValues( 922 multimap, Functions.<Integer> identity()).keySet(); 923 } 924 }).named("Multimaps.transformValues[Multimap].keySet").withFeatures( 925 COLLECTION_FEATURES_REMOVE).createTestSuite()); 926 927 suite.addTest(MultisetTestSuiteBuilder.using( 928 new TestStringMultisetGenerator() { 929 @Override protected Multiset<String> create(String[] elements) { 930 Multimap<String, Integer> multimap 931 = ArrayListMultimap.create(); 932 populateMultimapForKeys(multimap, elements); 933 return Multimaps.transformValues( 934 multimap, Functions.<Integer> identity()).keys(); 935 } 936 }) 937 .named("Multimaps.transformValues[Multimap].keys") 938 .withFeatures(COLLECTION_FEATURES_REMOVE) 939 .createTestSuite()); 940 941 suite.addTest( 942 CollectionTestSuiteBuilder.using(new TestStringCollectionGenerator() { 943 @Override public Collection<String> create(String[] elements) { 944 Multimap<Integer, String> multimap = ArrayListMultimap.create(); 945 populateMultimapForValues(multimap, elements); 946 return Multimaps.transformValues( 947 multimap, Functions.<String> identity()).values(); 948 } 949 }).named("Multimaps.transformValues[Multimap].values").withFeatures( 950 COLLECTION_FEATURES_REMOVE).createTestSuite()); 951 952 suite.addTest(CollectionTestSuiteBuilder.using(new TestEntriesGenerator() { 953 @Override public Collection<Entry<String, Integer>> create( 954 Object... elements) { 955 Multimap<String, Integer> multimap = ArrayListMultimap.create(); 956 for (Object element : elements) { 957 @SuppressWarnings("unchecked") 958 Entry<String, Integer> entry = (Entry<String, Integer>) element; 959 multimap.put(entry.getKey(), entry.getValue()); 960 } 961 return Multimaps.transformValues( 962 multimap, Functions.<Integer> identity()).entries(); 963 } 964 @Override Multimap<String, Integer> createMultimap() { 965 return Multimaps.transformValues( 966 (Multimap<String, Integer>) 967 ArrayListMultimap.<String, Integer> create(), 968 Functions.<Integer> identity()); 969 } 970 }).named("Multimaps.transformValues[Multimap].entries") 971 .withFeatures(CollectionSize.ANY, CollectionFeature.REMOVE_OPERATIONS) 972 .createTestSuite()); 973 974 // TODO: use collection testers on Multimaps.forMap.entries 975 976 return suite; 977 } 978 } 979