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.Helpers.mapEntry; 21 import static com.google.common.collect.testing.features.CollectionFeature.ALLOWS_NULL_VALUES; 22 import static com.google.common.collect.testing.features.CollectionFeature.SUPPORTS_REMOVE; 23 import static com.google.common.collect.testing.google.AbstractMultisetSetCountTester.getSetCountDuplicateInitializingMethods; 24 import static com.google.common.collect.testing.google.MultisetCountTester.getCountDuplicateInitializingMethods; 25 import static com.google.common.collect.testing.google.MultisetIteratorTester.getIteratorDuplicateInitializingMethods; 26 import static com.google.common.collect.testing.google.MultisetRemoveTester.getRemoveDuplicateInitializingMethods; 27 import static java.lang.reflect.Proxy.newProxyInstance; 28 29 import com.google.common.annotations.GwtIncompatible; 30 import com.google.common.base.Ascii; 31 import com.google.common.base.Function; 32 import com.google.common.base.Predicate; 33 import com.google.common.base.Predicates; 34 import com.google.common.base.Supplier; 35 import com.google.common.collect.Maps.EntryTransformer; 36 import com.google.common.collect.testing.SampleElements; 37 import com.google.common.collect.testing.SetTestSuiteBuilder; 38 import com.google.common.collect.testing.TestCollectionGenerator; 39 import com.google.common.collect.testing.TestListGenerator; 40 import com.google.common.collect.testing.TestStringSetGenerator; 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.MapFeature; 45 import com.google.common.collect.testing.google.ListMultimapTestSuiteBuilder; 46 import com.google.common.collect.testing.google.MultimapFeature; 47 import com.google.common.collect.testing.google.MultimapTestSuiteBuilder; 48 import com.google.common.collect.testing.google.MultisetTestSuiteBuilder; 49 import com.google.common.collect.testing.google.SetMultimapTestSuiteBuilder; 50 import com.google.common.collect.testing.google.TestListMultimapGenerator; 51 import com.google.common.collect.testing.google.TestMultimapGenerator; 52 import com.google.common.collect.testing.google.TestSetMultimapGenerator; 53 import com.google.common.collect.testing.google.TestStringListMultimapGenerator; 54 import com.google.common.collect.testing.google.TestStringMultisetGenerator; 55 56 import junit.framework.Test; 57 import junit.framework.TestCase; 58 import junit.framework.TestSuite; 59 60 import java.lang.reflect.InvocationHandler; 61 import java.lang.reflect.Method; 62 import java.util.Collection; 63 import java.util.List; 64 import java.util.Map; 65 import java.util.Map.Entry; 66 import java.util.Set; 67 import java.util.TreeSet; 68 69 /** 70 * Run collection tests on wrappers from {@link Multimaps}. 71 * 72 * @author Jared Levy 73 */ 74 @GwtIncompatible("suite") // TODO(cpovirk): set up collect/gwt/suites version 75 public class MultimapsCollectionTest extends TestCase { 76 77 private static final Feature<?>[] FOR_MAP_FEATURES_ONE = { 78 CollectionSize.ONE, 79 ALLOWS_NULL_VALUES, 80 SUPPORTS_REMOVE, 81 CollectionFeature.SUPPORTS_ITERATOR_REMOVE 82 }; 83 84 private static final Feature<?>[] FOR_MAP_FEATURES_ANY = { 85 CollectionSize.ANY, 86 ALLOWS_NULL_VALUES, 87 SUPPORTS_REMOVE, 88 CollectionFeature.SUPPORTS_ITERATOR_REMOVE, 89 MultisetTestSuiteBuilder.NoRecurse.NO_ENTRY_SET, // Cannot create entries with count > 1 90 }; 91 92 static final Supplier<TreeSet<String>> STRING_TREESET_FACTORY = new Supplier<TreeSet<String>>() { 93 @Override 94 public TreeSet<String> get() { 95 return new TreeSet<String>(Ordering.natural().nullsLast()); 96 } 97 }; 98 populateMultimapForGet( Multimap<Integer, String> multimap, String[] elements)99 static void populateMultimapForGet( 100 Multimap<Integer, String> multimap, String[] elements) { 101 multimap.put(2, "foo"); 102 for (String element : elements) { 103 multimap.put(3, element); 104 } 105 } 106 populateMultimapForKeySet( Multimap<String, Integer> multimap, String[] elements)107 static void populateMultimapForKeySet( 108 Multimap<String, Integer> multimap, String[] elements) { 109 for (String element : elements) { 110 multimap.put(element, 2); 111 multimap.put(element, 3); 112 } 113 } 114 populateMultimapForValues( Multimap<Integer, String> multimap, String[] elements)115 static void populateMultimapForValues( 116 Multimap<Integer, String> multimap, String[] elements) { 117 for (int i = 0; i < elements.length; i++) { 118 multimap.put(i % 2, elements[i]); 119 } 120 } 121 populateMultimapForKeys( Multimap<String, Integer> multimap, String[] elements)122 static void populateMultimapForKeys( 123 Multimap<String, Integer> multimap, String[] elements) { 124 for (int i = 0; i < elements.length; i++) { 125 multimap.put(elements[i], i); 126 } 127 } 128 129 /** 130 * Implements {@code Multimap.put()} -- and no other methods -- for a {@code 131 * Map} by ignoring all but the latest value for each key. This class exists 132 * only so that we can use 133 * {@link MultimapsCollectionTest#populateMultimapForGet(Multimap, String[])} 134 * and similar methods to populate a map to be passed to 135 * {@link Multimaps#forMap(Map)}. All tests should run against the result of 136 * {@link #build()}. 137 */ 138 private static final class PopulatableMapAsMultimap<K, V> 139 extends ForwardingMultimap<K, V> { 140 final Map<K, V> map; 141 final SetMultimap<K, V> unusableDelegate; 142 create()143 static <K, V> PopulatableMapAsMultimap<K, V> create() { 144 return new PopulatableMapAsMultimap<K, V>(); 145 } 146 147 @SuppressWarnings("unchecked") // all methods throw immediately PopulatableMapAsMultimap()148 PopulatableMapAsMultimap() { 149 this.map = newHashMap(); 150 this.unusableDelegate = (SetMultimap<K, V>) newProxyInstance( 151 SetMultimap.class.getClassLoader(), 152 new Class<?>[] {SetMultimap.class}, 153 new InvocationHandler() { 154 @Override 155 public Object invoke(Object proxy, Method method, Object[] args) 156 throws Throwable { 157 throw new UnsupportedOperationException(); 158 } 159 }); 160 } 161 delegate()162 @Override protected Multimap<K, V> delegate() { 163 return unusableDelegate; 164 } 165 put(K key, V value)166 @Override public boolean put(K key, V value) { 167 map.put(key, value); 168 return true; 169 } 170 build()171 SetMultimap<K, V> build() { 172 return Multimaps.forMap(map); 173 } 174 } 175 176 abstract static class TestEntriesGenerator 177 implements TestCollectionGenerator<Entry<String, Integer>> { 178 @Override samples()179 public SampleElements<Entry<String, Integer>> samples() { 180 return new SampleElements<Entry<String, Integer>>( 181 Maps.immutableEntry("bar", 1), 182 Maps.immutableEntry("bar", 2), 183 Maps.immutableEntry("foo", 3), 184 Maps.immutableEntry("bar", 3), 185 Maps.immutableEntry("cat", 2)); 186 } 187 188 @Override create(Object... elements)189 public Collection<Entry<String, Integer>> create(Object... elements) { 190 Multimap<String, Integer> multimap = createMultimap(); 191 for (Object element : elements) { 192 @SuppressWarnings("unchecked") 193 Entry<String, Integer> entry = (Entry<String, Integer>) element; 194 multimap.put(entry.getKey(), entry.getValue()); 195 } 196 return multimap.entries(); 197 } 198 createMultimap()199 abstract Multimap<String, Integer> createMultimap(); 200 201 @Override 202 @SuppressWarnings("unchecked") createArray(int length)203 public Entry<String, Integer>[] createArray(int length) { 204 return (Entry<String, Integer>[]) new Entry<?, ?>[length]; 205 } 206 207 @Override order( List<Entry<String, Integer>> insertionOrder)208 public List<Entry<String, Integer>> order( 209 List<Entry<String, Integer>> insertionOrder) { 210 return insertionOrder; 211 } 212 } 213 214 public abstract static class TestEntriesListGenerator 215 extends TestEntriesGenerator 216 implements TestListGenerator<Entry<String, Integer>> { create(Object... elements)217 @Override public List<Entry<String, Integer>> create(Object... elements) { 218 return (List<Entry<String, Integer>>) super.create(elements); 219 } 220 } 221 222 private static final Predicate<Map.Entry<Integer, String>> FILTER_GET_PREDICATE 223 = new Predicate<Map.Entry<Integer, String>>() { 224 @Override public boolean apply(Entry<Integer, String> entry) { 225 return !"badvalue".equals(entry.getValue()) && 55556 != entry.getKey(); 226 } 227 }; 228 229 private static final Predicate<Map.Entry<String, Integer>> FILTER_KEYSET_PREDICATE 230 = new Predicate<Map.Entry<String, Integer>>() { 231 @Override public boolean apply(Entry<String, Integer> entry) { 232 return !"badkey".equals(entry.getKey()) && 55556 != entry.getValue(); 233 } 234 }; 235 suite()236 public static Test suite() { 237 TestSuite suite = new TestSuite(); 238 239 suite.addTest(transformSuite()); 240 suite.addTest(filterSuite()); 241 242 suite.addTest(ListMultimapTestSuiteBuilder.using(new TestStringListMultimapGenerator() { 243 @Override 244 protected ListMultimap<String, String> create(Entry<String, String>[] entries) { 245 ListMultimap<String, String> multimap = Multimaps.synchronizedListMultimap( 246 ArrayListMultimap.<String, String> create()); 247 for (Entry<String, String> entry : entries) { 248 multimap.put(entry.getKey(), entry.getValue()); 249 } 250 return multimap; 251 } 252 }) 253 .named("synchronized ArrayListMultimap") 254 .withFeatures( 255 MapFeature.ALLOWS_NULL_KEYS, 256 MapFeature.ALLOWS_NULL_VALUES, 257 MapFeature.ALLOWS_ANY_NULL_QUERIES, 258 MapFeature.GENERAL_PURPOSE, 259 MapFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION, 260 CollectionFeature.SUPPORTS_ITERATOR_REMOVE, 261 CollectionSize.ANY) 262 .createTestSuite()); 263 264 suite.addTest(SetTestSuiteBuilder.using( 265 new TestStringSetGenerator() { 266 @Override protected Set<String> create(String[] elements) { 267 PopulatableMapAsMultimap<Integer, String> multimap 268 = PopulatableMapAsMultimap.create(); 269 populateMultimapForGet(multimap, elements); 270 return multimap.build().get(3); 271 } 272 }) 273 .named("Multimaps.forMap.get") 274 .withFeatures(FOR_MAP_FEATURES_ONE) 275 .createTestSuite()); 276 277 suite.addTest(SetTestSuiteBuilder.using( 278 new TestStringSetGenerator() { 279 @Override protected Set<String> create(String[] elements) { 280 PopulatableMapAsMultimap<String, Integer> multimap 281 = PopulatableMapAsMultimap.create(); 282 populateMultimapForKeySet(multimap, elements); 283 return multimap.build().keySet(); 284 } 285 }) 286 .named("Multimaps.forMap.keySet") 287 .withFeatures(FOR_MAP_FEATURES_ANY) 288 .createTestSuite()); 289 290 // TODO: use collection testers on Multimaps.forMap.values 291 292 suite.addTest(MultisetTestSuiteBuilder.using( 293 new TestStringMultisetGenerator() { 294 @Override protected Multiset<String> create(String[] elements) { 295 PopulatableMapAsMultimap<String, Integer> multimap 296 = PopulatableMapAsMultimap.create(); 297 populateMultimapForKeys(multimap, elements); 298 return multimap.build().keys(); 299 } 300 }) 301 .named("Multimaps.forMap.keys") 302 .withFeatures(FOR_MAP_FEATURES_ANY) 303 .suppressing(getCountDuplicateInitializingMethods()) 304 .suppressing(getSetCountDuplicateInitializingMethods()) 305 .suppressing(getIteratorDuplicateInitializingMethods()) 306 .suppressing(getRemoveDuplicateInitializingMethods()) 307 .createTestSuite()); 308 309 // TODO: use collection testers on Multimaps.forMap.entries 310 311 return suite; 312 } 313 314 static abstract class TransformedMultimapGenerator<M extends Multimap<String, String>> 315 implements TestMultimapGenerator<String, String, M> { 316 317 @Override createKeyArray(int length)318 public String[] createKeyArray(int length) { 319 return new String[length]; 320 } 321 322 @Override createValueArray(int length)323 public String[] createValueArray(int length) { 324 return new String[length]; 325 } 326 327 @Override sampleKeys()328 public SampleElements<String> sampleKeys() { 329 return new SampleElements<String>("one", "two", "three", "four", "five"); 330 } 331 332 @Override sampleValues()333 public SampleElements<String> sampleValues() { 334 return new SampleElements<String>("january", "february", "march", "april", "may"); 335 } 336 337 @Override createCollection(Iterable<? extends String> values)338 public Collection<String> createCollection(Iterable<? extends String> values) { 339 return Lists.newArrayList(values); 340 } 341 342 @Override samples()343 public SampleElements<Entry<String, String>> samples() { 344 return new SampleElements<Entry<String, String>>( 345 mapEntry("one", "january"), 346 mapEntry("two", "february"), 347 mapEntry("three", "march"), 348 mapEntry("four", "april"), 349 mapEntry("five", "may")); 350 } 351 352 @Override create(Object... elements)353 public M create(Object... elements) { 354 Multimap<String, String> multimap = ArrayListMultimap.create(); 355 for (Object o : elements) { 356 @SuppressWarnings("unchecked") 357 Entry<String, String> entry = (Entry<String, String>) o; 358 multimap.put(entry.getKey(), Ascii.toUpperCase(entry.getValue())); 359 } 360 return transform(multimap); 361 } 362 transform(Multimap<String, String> multimap)363 abstract M transform(Multimap<String, String> multimap); 364 365 @SuppressWarnings("unchecked") 366 @Override createArray(int length)367 public Entry<String, String>[] createArray(int length) { 368 return new Entry[length]; 369 } 370 371 @Override order(List<Entry<String, String>> insertionOrder)372 public Iterable<Entry<String, String>> order(List<Entry<String, String>> insertionOrder) { 373 return insertionOrder; 374 } 375 376 static final Function<String, String> FUNCTION = new Function<String, String>() { 377 @Override 378 public String apply(String value) { 379 return Ascii.toLowerCase(value); 380 } 381 }; 382 383 static final EntryTransformer<String, String, String> ENTRY_TRANSFORMER = 384 new EntryTransformer<String, String, String>() { 385 @Override 386 public String transformEntry(String key, String value) { 387 return Ascii.toLowerCase(value); 388 } 389 }; 390 } 391 392 static abstract class TransformedListMultimapGenerator 393 extends TransformedMultimapGenerator<ListMultimap<String, String>> 394 implements TestListMultimapGenerator<String, String> { 395 } 396 transformSuite()397 private static Test transformSuite() { 398 TestSuite suite = new TestSuite("Multimaps.transform*"); 399 suite.addTest(MultimapTestSuiteBuilder.using( 400 new TransformedMultimapGenerator<Multimap<String,String>>() { 401 @Override 402 Multimap<String, String> transform(Multimap<String, String> multimap) { 403 return Multimaps.transformValues(multimap, FUNCTION); 404 } 405 }) 406 .named("Multimaps.transformValues[Multimap]") 407 .withFeatures( 408 CollectionSize.ANY, 409 MapFeature.SUPPORTS_REMOVE, 410 CollectionFeature.SUPPORTS_ITERATOR_REMOVE, 411 MapFeature.ALLOWS_NULL_KEYS, 412 MapFeature.ALLOWS_ANY_NULL_QUERIES) 413 .createTestSuite()); 414 suite.addTest(MultimapTestSuiteBuilder.using( 415 new TransformedMultimapGenerator<Multimap<String,String>>() { 416 @Override 417 Multimap<String, String> transform(Multimap<String, String> multimap) { 418 return Multimaps.transformEntries(multimap, ENTRY_TRANSFORMER); 419 } 420 }) 421 .named("Multimaps.transformEntries[Multimap]") 422 .withFeatures( 423 CollectionSize.ANY, 424 MapFeature.SUPPORTS_REMOVE, 425 CollectionFeature.SUPPORTS_ITERATOR_REMOVE, 426 MapFeature.ALLOWS_NULL_KEYS, 427 MapFeature.ALLOWS_ANY_NULL_QUERIES) 428 .createTestSuite()); 429 suite.addTest(ListMultimapTestSuiteBuilder.using(new TransformedListMultimapGenerator() { 430 @Override 431 ListMultimap<String, String> transform(Multimap<String, String> multimap) { 432 return Multimaps.transformValues((ListMultimap<String, String>) multimap, FUNCTION); 433 } 434 }) 435 .named("Multimaps.transformValues[ListMultimap]") 436 .withFeatures( 437 CollectionSize.ANY, 438 MapFeature.SUPPORTS_REMOVE, 439 CollectionFeature.SUPPORTS_ITERATOR_REMOVE, 440 MapFeature.ALLOWS_NULL_KEYS, 441 MapFeature.ALLOWS_ANY_NULL_QUERIES) 442 .createTestSuite()); 443 suite.addTest(ListMultimapTestSuiteBuilder.using(new TransformedListMultimapGenerator() { 444 @Override 445 ListMultimap<String, String> transform(Multimap<String, String> multimap) { 446 return Multimaps.transformEntries( 447 (ListMultimap<String, String>) multimap, ENTRY_TRANSFORMER); 448 } 449 }) 450 .named("Multimaps.transformEntries[ListMultimap]") 451 .withFeatures( 452 CollectionSize.ANY, 453 MapFeature.SUPPORTS_REMOVE, 454 CollectionFeature.SUPPORTS_ITERATOR_REMOVE, 455 MapFeature.ALLOWS_NULL_KEYS, 456 MapFeature.ALLOWS_ANY_NULL_QUERIES) 457 .createTestSuite()); 458 459 // TODO: use collection testers on Multimaps.forMap.entries 460 461 return suite; 462 } 463 464 static abstract class TestFilteredMultimapGenerator<M extends Multimap<String, Integer>> 465 implements TestMultimapGenerator<String, Integer, M> { 466 467 @Override samples()468 public SampleElements<Entry<String, Integer>> samples() { 469 return new SampleElements<Entry<String, Integer>>( 470 mapEntry("one", 114), 471 mapEntry("two", 37), 472 mapEntry("three", 42), 473 mapEntry("four", 19), 474 mapEntry("five", 82)); 475 } 476 477 @SuppressWarnings("unchecked") 478 @Override createArray(int length)479 public Entry<String, Integer>[] createArray(int length) { 480 return new Entry[length]; 481 } 482 483 @Override order(List<Entry<String, Integer>> insertionOrder)484 public Iterable<Entry<String, Integer>> order(List<Entry<String, Integer>> insertionOrder) { 485 return insertionOrder; 486 } 487 488 @Override createKeyArray(int length)489 public String[] createKeyArray(int length) { 490 return new String[length]; 491 } 492 493 @Override createValueArray(int length)494 public Integer[] createValueArray(int length) { 495 return new Integer[length]; 496 } 497 498 @Override sampleKeys()499 public SampleElements<String> sampleKeys() { 500 return new SampleElements<String>("one", "two", "three", "four", "five"); 501 } 502 503 @Override sampleValues()504 public SampleElements<Integer> sampleValues() { 505 return new SampleElements<Integer>(114, 37, 42, 19, 82); 506 } 507 } 508 509 static abstract class FilteredSetMultimapGenerator 510 extends TestFilteredMultimapGenerator<SetMultimap<String, Integer>> 511 implements TestSetMultimapGenerator<String, Integer> { 512 513 filter(SetMultimap<String, Integer> multimap)514 abstract SetMultimap<String, Integer> filter(SetMultimap<String, Integer> multimap); 515 516 @Override create(Object... elements)517 public SetMultimap<String, Integer> create(Object... elements) { 518 SetMultimap<String, Integer> multimap = LinkedHashMultimap.create(); 519 for (Object o : elements) { 520 @SuppressWarnings("unchecked") 521 Entry<String, Integer> entry = (Entry<String, Integer>) o; 522 multimap.put(entry.getKey(), entry.getValue()); 523 } 524 return filter(multimap); 525 } 526 527 @Override createCollection(Iterable<? extends Integer> values)528 public Collection<Integer> createCollection(Iterable<? extends Integer> values) { 529 return Sets.newLinkedHashSet(values); 530 } 531 } 532 533 static abstract class FilteredListMultimapGenerator 534 extends TestFilteredMultimapGenerator<ListMultimap<String, Integer>> 535 implements TestListMultimapGenerator<String, Integer> { 536 537 @Override create(Object... elements)538 public ListMultimap<String, Integer> create(Object... elements) { 539 ListMultimap<String, Integer> multimap = LinkedListMultimap.create(); 540 for (Object o : elements) { 541 @SuppressWarnings("unchecked") 542 Entry<String, Integer> entry = (Entry<String, Integer>) o; 543 multimap.put(entry.getKey(), entry.getValue()); 544 } 545 return filter(multimap); 546 } 547 filter(ListMultimap<String, Integer> multimap)548 abstract ListMultimap<String, Integer> filter(ListMultimap<String, Integer> multimap); 549 550 @Override createCollection(Iterable<? extends Integer> values)551 public Collection<Integer> createCollection(Iterable<? extends Integer> values) { 552 return Lists.newArrayList(values); 553 } 554 } 555 filterSuite()556 private static Test filterSuite() { 557 TestSuite suite = new TestSuite("Multimaps.filter*"); 558 suite.addTest(SetMultimapTestSuiteBuilder.using(new FilteredSetMultimapGenerator() { 559 @Override 560 SetMultimap<String, Integer> filter(SetMultimap<String, Integer> multimap) { 561 multimap.put("foo", 17); 562 multimap.put("bar", 32); 563 multimap.put("foo", 16); 564 return Multimaps.filterKeys(multimap, 565 Predicates.not(Predicates.in(ImmutableSet.of("foo", "bar")))); 566 } 567 }) 568 .named("Multimaps.filterKeys[SetMultimap, Predicate]") 569 .withFeatures( 570 CollectionSize.ANY, 571 MultimapFeature.VALUE_COLLECTIONS_SUPPORT_ITERATOR_REMOVE, 572 MapFeature.GENERAL_PURPOSE, 573 MapFeature.ALLOWS_NULL_KEYS, 574 MapFeature.ALLOWS_NULL_VALUES, 575 MapFeature.ALLOWS_ANY_NULL_QUERIES) 576 .createTestSuite()); 577 578 suite.addTest(ListMultimapTestSuiteBuilder.using(new FilteredListMultimapGenerator() { 579 @Override 580 ListMultimap<String, Integer> filter(ListMultimap<String, Integer> multimap) { 581 multimap.put("foo", 17); 582 multimap.put("bar", 32); 583 multimap.put("foo", 16); 584 return Multimaps.filterKeys(multimap, 585 Predicates.not(Predicates.in(ImmutableSet.of("foo", "bar")))); 586 } 587 }) 588 .named("Multimaps.filterKeys[ListMultimap, Predicate]") 589 .withFeatures( 590 CollectionSize.ANY, 591 MultimapFeature.VALUE_COLLECTIONS_SUPPORT_ITERATOR_REMOVE, 592 MapFeature.GENERAL_PURPOSE, 593 MapFeature.ALLOWS_NULL_KEYS, 594 MapFeature.ALLOWS_NULL_VALUES, 595 MapFeature.ALLOWS_ANY_NULL_QUERIES) 596 .createTestSuite()); 597 suite.addTest(ListMultimapTestSuiteBuilder.using(new FilteredListMultimapGenerator() { 598 @Override 599 ListMultimap<String, Integer> filter(ListMultimap<String, Integer> multimap) { 600 multimap.put("foo", 17); 601 multimap.put("bar", 32); 602 multimap.put("foo", 16); 603 multimap = Multimaps.filterKeys(multimap, Predicates.not(Predicates.equalTo("foo"))); 604 return Multimaps.filterKeys(multimap, Predicates.not(Predicates.equalTo("bar"))); 605 } 606 }) 607 .named("Multimaps.filterKeys[Multimaps.filterKeys[ListMultimap], Predicate]") 608 .withFeatures( 609 CollectionSize.ANY, 610 MultimapFeature.VALUE_COLLECTIONS_SUPPORT_ITERATOR_REMOVE, 611 MapFeature.GENERAL_PURPOSE, 612 MapFeature.ALLOWS_NULL_KEYS, 613 MapFeature.ALLOWS_NULL_VALUES, 614 MapFeature.ALLOWS_ANY_NULL_QUERIES) 615 .createTestSuite()); 616 suite.addTest(SetMultimapTestSuiteBuilder.using(new FilteredSetMultimapGenerator() { 617 @Override 618 SetMultimap<String, Integer> filter(SetMultimap<String, Integer> multimap) { 619 multimap.put("one", 314); 620 multimap.put("two", 159); 621 multimap.put("one", 265); 622 return Multimaps.filterValues(multimap, 623 Predicates.not(Predicates.in(ImmutableSet.of(314, 159, 265)))); 624 } 625 }) 626 .named("Multimaps.filterValues[SetMultimap, Predicate]") 627 .withFeatures( 628 CollectionSize.ANY, 629 MapFeature.GENERAL_PURPOSE, 630 MapFeature.ALLOWS_NULL_KEYS, 631 MapFeature.ALLOWS_NULL_VALUES, 632 MapFeature.ALLOWS_ANY_NULL_QUERIES) 633 .createTestSuite()); 634 suite.addTest(SetMultimapTestSuiteBuilder.using(new FilteredSetMultimapGenerator() { 635 @Override 636 SetMultimap<String, Integer> filter(SetMultimap<String, Integer> multimap) { 637 ImmutableSetMultimap<String, Integer> badEntries = 638 ImmutableSetMultimap.of("foo", 314, "one", 159, "two", 265, "bar", 358); 639 multimap.putAll(badEntries); 640 return Multimaps.filterEntries(multimap, 641 Predicates.not(Predicates.in(badEntries.entries()))); 642 } 643 }) 644 .named("Multimaps.filterEntries[SetMultimap, Predicate]") 645 .withFeatures( 646 CollectionSize.ANY, 647 MapFeature.GENERAL_PURPOSE, 648 MapFeature.ALLOWS_NULL_KEYS, 649 MapFeature.ALLOWS_NULL_VALUES, 650 MapFeature.ALLOWS_ANY_NULL_QUERIES) 651 .createTestSuite()); 652 suite.addTest(SetMultimapTestSuiteBuilder.using(new FilteredSetMultimapGenerator() { 653 @Override 654 SetMultimap<String, Integer> filter(SetMultimap<String, Integer> multimap) { 655 ImmutableSetMultimap<String, Integer> badEntries = 656 ImmutableSetMultimap.of("foo", 314, "one", 159, "two", 265, "bar", 358); 657 multimap.putAll(badEntries); 658 multimap = Multimaps.filterKeys(multimap, 659 Predicates.not(Predicates.in(ImmutableSet.of("foo", "bar")))); 660 return Multimaps.filterEntries(multimap, 661 Predicates.not(Predicates.in(badEntries.entries()))); 662 } 663 }) 664 .named("Multimaps.filterEntries[Multimaps.filterKeys[SetMultimap]]") 665 .withFeatures( 666 CollectionSize.ANY, 667 MapFeature.GENERAL_PURPOSE, 668 MapFeature.ALLOWS_NULL_KEYS, 669 MapFeature.ALLOWS_NULL_VALUES, 670 MapFeature.ALLOWS_ANY_NULL_QUERIES) 671 .createTestSuite()); 672 suite.addTest(SetMultimapTestSuiteBuilder.using(new FilteredSetMultimapGenerator() { 673 @Override 674 SetMultimap<String, Integer> filter(SetMultimap<String, Integer> multimap) { 675 ImmutableSetMultimap<String, Integer> badEntries = 676 ImmutableSetMultimap.of("foo", 314, "one", 159, "two", 265, "bar", 358); 677 multimap.putAll(badEntries); 678 multimap = Multimaps.filterEntries(multimap, 679 Predicates.not(Predicates.in(ImmutableMap.of("one", 159, "two", 265).entrySet()))); 680 return Multimaps.filterKeys(multimap, 681 Predicates.not(Predicates.in(ImmutableSet.of("foo", "bar")))); 682 } 683 }) 684 .named("Multimaps.filterKeys[Multimaps.filterEntries[SetMultimap]]") 685 .withFeatures( 686 CollectionSize.ANY, 687 MapFeature.GENERAL_PURPOSE, 688 MapFeature.ALLOWS_NULL_KEYS, 689 MapFeature.ALLOWS_NULL_VALUES, 690 MapFeature.ALLOWS_ANY_NULL_QUERIES) 691 .createTestSuite()); 692 suite.addTest(SetMultimapTestSuiteBuilder.using(new FilteredSetMultimapGenerator() { 693 @Override 694 SetMultimap<String, Integer> filter(SetMultimap<String, Integer> multimap) { 695 ImmutableSetMultimap<String, Integer> badEntries = 696 ImmutableSetMultimap.of("foo", 314, "bar", 358); 697 multimap.putAll(badEntries); 698 multimap = Multimaps.filterKeys(multimap, Predicates.not(Predicates.equalTo("foo"))); 699 multimap = Multimaps.filterKeys(multimap, Predicates.not(Predicates.equalTo("bar"))); 700 return multimap; 701 } 702 }) 703 .named("Multimaps.filterKeys[Multimaps.filterKeys[SetMultimap]]") 704 .withFeatures( 705 CollectionSize.ANY, 706 MultimapFeature.VALUE_COLLECTIONS_SUPPORT_ITERATOR_REMOVE, 707 MapFeature.GENERAL_PURPOSE, 708 MapFeature.ALLOWS_NULL_KEYS, 709 MapFeature.ALLOWS_NULL_VALUES, 710 MapFeature.ALLOWS_ANY_NULL_QUERIES) 711 .createTestSuite()); 712 return suite; 713 } 714 } 715