1
2
3
4
5
6
7
8
9
10
11
12
13
14
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
71
72
73
74 @GwtIncompatible("suite")
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,
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
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
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
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
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
131
132
133
134
135
136
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
143 static <K, V> PopulatableMapAsMultimap<K, V> create() {
144 return new PopulatableMapAsMultimap<K, V>();
145 }
146
147 @SuppressWarnings("unchecked")
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
162 @Override protected Multimap<K, V> delegate() {
163 return unusableDelegate;
164 }
165
166 @Override public boolean put(K key, V value) {
167 map.put(key, value);
168 return true;
169 }
170
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
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
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
199 abstract Multimap<String, Integer> createMultimap();
200
201 @Override
202 @SuppressWarnings("unchecked")
203 public Entry<String, Integer>[] createArray(int length) {
204 return (Entry<String, Integer>[]) new Entry<?, ?>[length];
205 }
206
207 @Override
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>> {
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
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
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
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
318 public String[] createKeyArray(int length) {
319 return new String[length];
320 }
321
322 @Override
323 public String[] createValueArray(int length) {
324 return new String[length];
325 }
326
327 @Override
328 public SampleElements<String> sampleKeys() {
329 return new SampleElements<String>("one", "two", "three", "four", "five");
330 }
331
332 @Override
333 public SampleElements<String> sampleValues() {
334 return new SampleElements<String>("january", "february", "march", "april", "may");
335 }
336
337 @Override
338 public Collection<String> createCollection(Iterable<? extends String> values) {
339 return Lists.newArrayList(values);
340 }
341
342 @Override
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
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
363 abstract M transform(Multimap<String, String> multimap);
364
365 @SuppressWarnings("unchecked")
366 @Override
367 public Entry<String, String>[] createArray(int length) {
368 return new Entry[length];
369 }
370
371 @Override
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
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
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
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
479 public Entry<String, Integer>[] createArray(int length) {
480 return new Entry[length];
481 }
482
483 @Override
484 public Iterable<Entry<String, Integer>> order(List<Entry<String, Integer>> insertionOrder) {
485 return insertionOrder;
486 }
487
488 @Override
489 public String[] createKeyArray(int length) {
490 return new String[length];
491 }
492
493 @Override
494 public Integer[] createValueArray(int length) {
495 return new Integer[length];
496 }
497
498 @Override
499 public SampleElements<String> sampleKeys() {
500 return new SampleElements<String>("one", "two", "three", "four", "five");
501 }
502
503 @Override
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
514 abstract SetMultimap<String, Integer> filter(SetMultimap<String, Integer> multimap);
515
516 @Override
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
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
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
548 abstract ListMultimap<String, Integer> filter(ListMultimap<String, Integer> multimap);
549
550 @Override
551 public Collection<Integer> createCollection(Iterable<? extends Integer> values) {
552 return Lists.newArrayList(values);
553 }
554 }
555
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 }