/* * Copyright (C) 2008 The Guava Authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.google.common.collect; import static com.google.common.collect.Maps.newHashMap; import static com.google.common.collect.testing.features.CollectionFeature.ALLOWS_NULL_VALUES; import static com.google.common.collect.testing.features.CollectionFeature.REMOVE_OPERATIONS; import static com.google.common.collect.testing.google.AbstractMultisetSetCountTester.getSetCountDuplicateInitializingMethods; import static com.google.common.collect.testing.google.MultisetIteratorTester.getIteratorDuplicateInitializingMethods; import static com.google.common.collect.testing.google.MultisetReadsTester.getReadsDuplicateInitializingMethods; import static java.lang.reflect.Proxy.newProxyInstance; import com.google.common.annotations.GwtIncompatible; import com.google.common.base.Functions; import com.google.common.base.Predicate; import com.google.common.base.Supplier; import com.google.common.collect.testing.CollectionTestSuiteBuilder; import com.google.common.collect.testing.ListTestSuiteBuilder; import com.google.common.collect.testing.SampleElements; import com.google.common.collect.testing.SetTestSuiteBuilder; import com.google.common.collect.testing.TestCollectionGenerator; import com.google.common.collect.testing.TestListGenerator; import com.google.common.collect.testing.TestStringCollectionGenerator; import com.google.common.collect.testing.TestStringListGenerator; import com.google.common.collect.testing.TestStringSetGenerator; import com.google.common.collect.testing.TestStringSortedSetGenerator; import com.google.common.collect.testing.features.CollectionFeature; import com.google.common.collect.testing.features.CollectionSize; import com.google.common.collect.testing.features.Feature; import com.google.common.collect.testing.features.ListFeature; import com.google.common.collect.testing.google.MultisetTestSuiteBuilder; import com.google.common.collect.testing.google.MultisetWritesTester; import com.google.common.collect.testing.google.TestStringMultisetGenerator; import com.google.common.collect.testing.testers.CollectionIteratorTester; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; /** * Run collection tests on {@link Multimap} implementations. * * @author Jared Levy */ @GwtIncompatible("suite") // TODO(cpovirk): set up collect/gwt/suites version public class MultimapCollectionTest extends TestCase { private static final Feature<?>[] COLLECTION_FEATURES = { CollectionSize.ANY, CollectionFeature.ALLOWS_NULL_VALUES, CollectionFeature.GENERAL_PURPOSE }; static final Feature<?>[] COLLECTION_FEATURES_ORDER = { CollectionSize.ANY, CollectionFeature.ALLOWS_NULL_VALUES, CollectionFeature.KNOWN_ORDER, CollectionFeature.GENERAL_PURPOSE }; static final Feature<?>[] COLLECTION_FEATURES_REMOVE = { CollectionSize.ANY, CollectionFeature.ALLOWS_NULL_VALUES, CollectionFeature.REMOVE_OPERATIONS }; static final Feature<?>[] COLLECTION_FEATURES_REMOVE_ORDER = { CollectionSize.ANY, CollectionFeature.ALLOWS_NULL_VALUES, CollectionFeature.KNOWN_ORDER, CollectionFeature.REMOVE_OPERATIONS }; private static final Feature<?>[] LIST_FEATURES = { CollectionSize.ANY, CollectionFeature.ALLOWS_NULL_VALUES, ListFeature.GENERAL_PURPOSE }; private static final Feature<?>[] LIST_FEATURES_REMOVE_SET = { CollectionSize.ANY, CollectionFeature.ALLOWS_NULL_VALUES, ListFeature.REMOVE_OPERATIONS, ListFeature.SUPPORTS_SET }; private static final Feature<?>[] FOR_MAP_FEATURES_ONE = { CollectionSize.ONE, ALLOWS_NULL_VALUES, REMOVE_OPERATIONS, }; private static final Feature<?>[] FOR_MAP_FEATURES_ANY = { CollectionSize.ANY, ALLOWS_NULL_VALUES, REMOVE_OPERATIONS, }; static final Supplier<TreeSet<String>> STRING_TREESET_FACTORY = new Supplier<TreeSet<String>>() { @Override public TreeSet<String> get() { return new TreeSet<String>(Ordering.natural().nullsLast()); } }; static void populateMultimapForGet( Multimap<Integer, String> multimap, String[] elements) { multimap.put(2, "foo"); for (String element : elements) { multimap.put(3, element); } } static void populateMultimapForKeySet( Multimap<String, Integer> multimap, String[] elements) { for (String element : elements) { multimap.put(element, 2); multimap.put(element, 3); } } static void populateMultimapForValues( Multimap<Integer, String> multimap, String[] elements) { for (int i = 0; i < elements.length; i++) { multimap.put(i % 2, elements[i]); } } static void populateMultimapForKeys( Multimap<String, Integer> multimap, String[] elements) { for (int i = 0; i < elements.length; i++) { multimap.put(elements[i], i); } } /** * Implements {@code Multimap.put()} -- and no other methods -- for a {@code * Map} by ignoring all but the latest value for each key. This class exists * only so that we can use * {@link MultimapCollectionTest#populateMultimapForGet(Multimap, String[])} * and similar methods to populate a map to be passed to * {@link Multimaps#forMap(Map)}. All tests should run against the result of * {@link #build()}. */ private static final class PopulatableMapAsMultimap<K, V> extends ForwardingMultimap<K, V> { final Map<K, V> map; final SetMultimap<K, V> unusableDelegate; static <K, V> PopulatableMapAsMultimap<K, V> create() { return new PopulatableMapAsMultimap<K, V>(); } @SuppressWarnings("unchecked") // all methods throw immediately PopulatableMapAsMultimap() { this.map = newHashMap(); this.unusableDelegate = (SetMultimap<K, V>) newProxyInstance( SetMultimap.class.getClassLoader(), new Class<?>[] {SetMultimap.class}, new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { throw new UnsupportedOperationException(); } }); } @Override protected Multimap<K, V> delegate() { return unusableDelegate; } @Override public boolean put(K key, V value) { map.put(key, value); return true; } SetMultimap<K, V> build() { return Multimaps.forMap(map); } } static abstract class TestEntriesGenerator implements TestCollectionGenerator<Entry<String, Integer>> { @Override public SampleElements<Entry<String, Integer>> samples() { return new SampleElements<Entry<String, Integer>>( Maps.immutableEntry("bar", 1), Maps.immutableEntry("bar", 2), Maps.immutableEntry("foo", 3), Maps.immutableEntry("bar", 3), Maps.immutableEntry("cat", 2)); } @Override public Collection<Entry<String, Integer>> create(Object... elements) { Multimap<String, Integer> multimap = createMultimap(); for (Object element : elements) { @SuppressWarnings("unchecked") Entry<String, Integer> entry = (Entry<String, Integer>) element; multimap.put(entry.getKey(), entry.getValue()); } return multimap.entries(); } abstract Multimap<String, Integer> createMultimap(); @Override @SuppressWarnings("unchecked") public Entry<String, Integer>[] createArray(int length) { return (Entry<String, Integer>[]) new Entry<?, ?>[length]; } @Override public List<Entry<String, Integer>> order( List<Entry<String, Integer>> insertionOrder) { return insertionOrder; } } public static abstract class TestEntriesListGenerator extends TestEntriesGenerator implements TestListGenerator<Entry<String, Integer>> { @Override public List<Entry<String, Integer>> create(Object... elements) { return (List<Entry<String, Integer>>) super.create(elements); } } private static abstract class TestEntrySetGenerator extends TestEntriesGenerator { @Override abstract SetMultimap<String, Integer> createMultimap(); @Override public Set<Entry<String, Integer>> create(Object... elements) { return (Set<Entry<String, Integer>>) super.create(elements); } } private static final Predicate<Map.Entry<Integer, String>> FILTER_GET_PREDICATE = new Predicate<Map.Entry<Integer, String>>() { @Override public boolean apply(Entry<Integer, String> entry) { return !"badvalue".equals(entry.getValue()) && 55556 != entry.getKey(); } }; private static final Predicate<Map.Entry<String, Integer>> FILTER_KEYSET_PREDICATE = new Predicate<Map.Entry<String, Integer>>() { @Override public boolean apply(Entry<String, Integer> entry) { return !"badkey".equals(entry.getKey()) && 55556 != entry.getValue(); } }; public static Test suite() { TestSuite suite = new TestSuite(); suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() { @Override protected Set<String> create(String[] elements) { SetMultimap<Integer, String> multimap = HashMultimap.create(); populateMultimapForGet(multimap, elements); return multimap.get(3); } }) .named("HashMultimap.get") .withFeatures(COLLECTION_FEATURES) .createTestSuite()); suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() { @Override protected Set<String> create(String[] elements) { SetMultimap<Integer, String> multimap = LinkedHashMultimap.create(); populateMultimapForGet(multimap, elements); return multimap.get(3); } }) .named("LinkedHashMultimap.get") .withFeatures(COLLECTION_FEATURES_ORDER) .createTestSuite()); suite.addTest(SetTestSuiteBuilder.using( new TestStringSortedSetGenerator() { @Override protected SortedSet<String> create(String[] elements) { SortedSetMultimap<Integer, String> multimap = TreeMultimap.create(Ordering.natural().nullsFirst(), Ordering.natural().nullsLast()); populateMultimapForGet(multimap, elements); return multimap.get(3); } }) .named("TreeMultimap.get") .withFeatures(COLLECTION_FEATURES_ORDER) .createTestSuite()); suite.addTest(ListTestSuiteBuilder.using(new TestStringListGenerator() { @Override protected List<String> create(String[] elements) { ListMultimap<Integer, String> multimap = ArrayListMultimap.create(); populateMultimapForGet(multimap, elements); return multimap.get(3); } }) .named("ArrayListMultimap.get") .withFeatures(LIST_FEATURES) .createTestSuite()); suite.addTest(ListTestSuiteBuilder.using(new TestStringListGenerator() { @Override protected List<String> create(String[] elements) { ListMultimap<Integer, String> multimap = Multimaps.synchronizedListMultimap( ArrayListMultimap.<Integer, String>create()); populateMultimapForGet(multimap, elements); return multimap.get(3); } }) .named("synchronized ArrayListMultimap.get") .withFeatures(LIST_FEATURES) .createTestSuite()); suite.addTest(ListTestSuiteBuilder.using(new TestStringListGenerator() { @Override protected List<String> create(String[] elements) { ListMultimap<Integer, String> multimap = LinkedListMultimap.create(); populateMultimapForGet(multimap, elements); return multimap.get(3); } }) .named("LinkedListMultimap.get") .withFeatures(LIST_FEATURES) .createTestSuite()); suite.addTest(ListTestSuiteBuilder.using(new TestStringListGenerator() { @Override protected List<String> create(String[] elements) { ImmutableListMultimap.Builder<Integer, String> builder = ImmutableListMultimap.builder(); ListMultimap<Integer, String> multimap = builder.put(2, "foo") .putAll(3, elements) .build(); return multimap.get(3); } }) .named("ImmutableListMultimap.get") .withFeatures(CollectionSize.ANY) .createTestSuite()); suite.addTest(SetTestSuiteBuilder.using( new TestStringSetGenerator() { @Override protected Set<String> create(String[] elements) { PopulatableMapAsMultimap<Integer, String> multimap = PopulatableMapAsMultimap.create(); populateMultimapForGet(multimap, elements); return multimap.build().get(3); } }) .named("Multimaps.forMap.get") .withFeatures(FOR_MAP_FEATURES_ONE) .createTestSuite()); suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() { @Override protected Set<String> create(String[] elements) { SetMultimap<Integer, String> multimap = LinkedHashMultimap.create(); populateMultimapForGet(multimap, elements); multimap.put(3, "badvalue"); multimap.put(55556, "foo"); return (Set<String>) Multimaps.filterEntries(multimap, FILTER_GET_PREDICATE).get(3); } }) .named("Multimaps.filterEntries.get") .withFeatures(COLLECTION_FEATURES_ORDER) .suppressing(CollectionIteratorTester.getIteratorKnownOrderRemoveSupportedMethod()) .createTestSuite()); suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() { @Override protected Set<String> create(String[] elements) { Multimap<String, Integer> multimap = HashMultimap.create(); populateMultimapForKeySet(multimap, elements); return multimap.keySet(); } }) .named("HashMultimap.keySet") .withFeatures(COLLECTION_FEATURES_REMOVE) .createTestSuite()); suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() { @Override protected Set<String> create(String[] elements) { Multimap<String, Integer> multimap = LinkedHashMultimap.create(); populateMultimapForKeySet(multimap, elements); return multimap.keySet(); } }) .named("LinkedHashMultimap.keySet") .withFeatures(COLLECTION_FEATURES_REMOVE_ORDER) .createTestSuite()); suite.addTest(SetTestSuiteBuilder.using( new TestStringSortedSetGenerator() { @Override protected SortedSet<String> create(String[] elements) { TreeMultimap<String, Integer> multimap = TreeMultimap.create(Ordering.natural().nullsFirst(), Ordering.natural().nullsLast()); populateMultimapForKeySet(multimap, elements); return multimap.keySet(); } }) .named("TreeMultimap.keySet") .withFeatures(COLLECTION_FEATURES_REMOVE_ORDER) .createTestSuite()); suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() { @Override protected Set<String> create(String[] elements) { Multimap<String, Integer> multimap = ArrayListMultimap.create(); populateMultimapForKeySet(multimap, elements); return multimap.keySet(); } }) .named("ArrayListMultimap.keySet") .withFeatures(COLLECTION_FEATURES_REMOVE) .createTestSuite()); suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() { @Override protected Set<String> create(String[] elements) { Multimap<String, Integer> multimap = LinkedListMultimap.create(); populateMultimapForKeySet(multimap, elements); return multimap.keySet(); } }) .named("LinkedListMultimap.keySet") .withFeatures(COLLECTION_FEATURES_REMOVE_ORDER) .createTestSuite()); suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() { @Override protected Set<String> create(String[] elements) { ImmutableListMultimap.Builder<String, Integer> builder = ImmutableListMultimap.builder(); for (String element : elements) { builder.put(element, 2); builder.put(element, 3); } Multimap<String, Integer> multimap = builder.build(); return multimap.keySet(); } }) .named("ImmutableListMultimap.keySet") .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER) .createTestSuite()); suite.addTest(SetTestSuiteBuilder.using( new TestStringSetGenerator() { @Override protected Set<String> create(String[] elements) { PopulatableMapAsMultimap<String, Integer> multimap = PopulatableMapAsMultimap.create(); populateMultimapForKeySet(multimap, elements); return multimap.build().keySet(); } }) .named("Multimaps.forMap.keySet") .withFeatures(FOR_MAP_FEATURES_ANY) .createTestSuite()); suite.addTest(SetTestSuiteBuilder.using( new TestStringSetGenerator() { @Override protected Set<String> create(String[] elements) { SetMultimap<String, Integer> multimap = LinkedHashMultimap.create(); populateMultimapForKeySet(multimap, elements); multimap.put("badkey", 3); multimap.put("a", 55556); return Multimaps.filterEntries(multimap, FILTER_KEYSET_PREDICATE).keySet(); } }) .named("Multimaps.filterEntries.keySet") .withFeatures(COLLECTION_FEATURES_REMOVE_ORDER) .suppressing(CollectionIteratorTester.getIteratorKnownOrderRemoveSupportedMethod()) .createTestSuite()); suite.addTest(CollectionTestSuiteBuilder.using( new TestStringCollectionGenerator() { @Override public Collection<String> create(String[] elements) { Multimap<Integer, String> multimap = HashMultimap.create(); populateMultimapForValues(multimap, elements); return multimap.values(); } }) .named("HashMultimap.values") .withFeatures(COLLECTION_FEATURES_REMOVE) .createTestSuite()); suite.addTest(CollectionTestSuiteBuilder.using( new TestStringCollectionGenerator() { @Override public Collection<String> create(String[] elements) { Multimap<Integer, String> multimap = LinkedHashMultimap.create(); populateMultimapForValues(multimap, elements); return multimap.values(); } }) .named("LinkedHashMultimap.values") .withFeatures(COLLECTION_FEATURES_REMOVE_ORDER) .createTestSuite()); suite.addTest(CollectionTestSuiteBuilder.using( new TestStringCollectionGenerator() { @Override public Collection<String> create(String[] elements) { Multimap<Integer, String> multimap = TreeMultimap.create(Ordering.natural().nullsFirst(), Ordering.natural().nullsLast()); populateMultimapForValues(multimap, elements); return multimap.values(); } }) .named("TreeMultimap.values") .withFeatures(COLLECTION_FEATURES_REMOVE) .createTestSuite()); suite.addTest(CollectionTestSuiteBuilder.using( new TestStringCollectionGenerator() { @Override public Collection<String> create(String[] elements) { Multimap<Integer, String> multimap = ArrayListMultimap.create(); populateMultimapForValues(multimap, elements); return multimap.values(); } }) .named("ArrayListMultimap.values") .withFeatures(COLLECTION_FEATURES_REMOVE) .createTestSuite()); suite.addTest(ListTestSuiteBuilder.using( new TestStringListGenerator() { @Override public List<String> create(String[] elements) { LinkedListMultimap<Integer, String> multimap = LinkedListMultimap.create(); populateMultimapForValues(multimap, elements); return multimap.values(); } }) .named("LinkedListMultimap.values") .withFeatures(LIST_FEATURES_REMOVE_SET) .createTestSuite()); suite.addTest(CollectionTestSuiteBuilder.using( new TestStringCollectionGenerator() { @Override public Collection<String> create(String[] elements) { ImmutableListMultimap.Builder<Integer, String> builder = ImmutableListMultimap.builder(); for (int i = 0; i < elements.length; i++) { builder.put(i % 2, elements[i]); } return builder.build().values(); } }) .named("ImmutableListMultimap.values") .withFeatures(CollectionSize.ANY) .createTestSuite()); suite.addTest(CollectionTestSuiteBuilder.using( new TestStringCollectionGenerator() { @Override public Collection<String> create(String[] elements) { Multimap<Integer, String> multimap = LinkedHashMultimap.create(); populateMultimapForValues(multimap, elements); multimap.put(3, "badvalue"); multimap.put(55556, "foo"); return Multimaps.filterEntries(multimap, FILTER_GET_PREDICATE).values(); } }) .named("Multimaps.filterEntries.values") .withFeatures(COLLECTION_FEATURES_REMOVE_ORDER) .suppressing(CollectionIteratorTester.getIteratorKnownOrderRemoveSupportedMethod()) .createTestSuite()); // TODO: use collection testers on Multimaps.forMap.values suite.addTest(MultisetTestSuiteBuilder.using( new TestStringMultisetGenerator() { @Override protected Multiset<String> create(String[] elements) { Multimap<String, Integer> multimap = HashMultimap.create(); populateMultimapForKeys(multimap, elements); return multimap.keys(); } }) .named("HashMultimap.keys") .withFeatures(COLLECTION_FEATURES_REMOVE) .createTestSuite()); suite.addTest(MultisetTestSuiteBuilder.using( new TestStringMultisetGenerator() { @Override protected Multiset<String> create(String[] elements) { Multimap<String, Integer> multimap = LinkedHashMultimap.create(); populateMultimapForKeys(multimap, elements); return multimap.keys(); } }) .named("LinkedHashMultimap.keys") .withFeatures(COLLECTION_FEATURES_REMOVE_ORDER) .createTestSuite()); suite.addTest(MultisetTestSuiteBuilder.using( new TestStringMultisetGenerator() { @Override protected Multiset<String> create(String[] elements) { Multimap<String, Integer> multimap = TreeMultimap.create(Ordering.natural().nullsFirst(), Ordering.natural().nullsLast()); populateMultimapForKeys(multimap, elements); return multimap.keys(); } @Override public List<String> order(List<String> insertionOrder) { Collections.sort(insertionOrder, Ordering.natural().nullsFirst()); return insertionOrder; } }) .named("TreeMultimap.keys") .withFeatures(COLLECTION_FEATURES_REMOVE_ORDER) .createTestSuite()); suite.addTest(MultisetTestSuiteBuilder.using( new TestStringMultisetGenerator() { @Override protected Multiset<String> create(String[] elements) { Multimap<String, Integer> multimap = ArrayListMultimap.create(); populateMultimapForKeys(multimap, elements); return multimap.keys(); } }) .named("ArrayListMultimap.keys") .withFeatures(COLLECTION_FEATURES_REMOVE) .createTestSuite()); suite.addTest(MultisetTestSuiteBuilder.using( new TestStringMultisetGenerator() { @Override protected Multiset<String> create(String[] elements) { Multimap<String, Integer> multimap = Multimaps.synchronizedListMultimap( ArrayListMultimap.<String, Integer>create()); populateMultimapForKeys(multimap, elements); return multimap.keys(); } }) .named("synchronized ArrayListMultimap.keys") .withFeatures(COLLECTION_FEATURES_REMOVE) .createTestSuite()); suite.addTest(MultisetTestSuiteBuilder.using( new TestStringMultisetGenerator() { @Override protected Multiset<String> create(String[] elements) { Multimap<String, Integer> multimap = LinkedListMultimap.create(); populateMultimapForKeys(multimap, elements); return multimap.keys(); } }) .named("LinkedListMultimap.keys") .withFeatures(COLLECTION_FEATURES_REMOVE_ORDER) .createTestSuite()); suite.addTest(MultisetTestSuiteBuilder.using( new TestStringMultisetGenerator() { @Override protected Multiset<String> create(String[] elements) { ImmutableListMultimap.Builder<String, Integer> builder = ImmutableListMultimap.builder(); for (int i = 0; i < elements.length; i++) { builder.put(elements[i], i); } Multimap<String, Integer> multimap = builder.build(); return multimap.keys(); } }) .named("ImmutableListMultimap.keys") .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER) .createTestSuite()); suite.addTest(MultisetTestSuiteBuilder.using( new TestStringMultisetGenerator() { @Override protected Multiset<String> create(String[] elements) { PopulatableMapAsMultimap<String, Integer> multimap = PopulatableMapAsMultimap.create(); populateMultimapForKeys(multimap, elements); return multimap.build().keys(); } }) .named("Multimaps.forMap.keys") .withFeatures(FOR_MAP_FEATURES_ANY) .suppressing(getReadsDuplicateInitializingMethods()) .suppressing(getSetCountDuplicateInitializingMethods()) .suppressing(getIteratorDuplicateInitializingMethods()) .createTestSuite()); suite.addTest(MultisetTestSuiteBuilder.using( new TestStringMultisetGenerator() { @Override protected Multiset<String> create(String[] elements) { SetMultimap<String, Integer> multimap = LinkedHashMultimap.create(); populateMultimapForKeys(multimap, elements); multimap.put("badkey", 3); multimap.put("a", 55556); return Multimaps.filterEntries(multimap, FILTER_KEYSET_PREDICATE).keys(); } }) .named("Multimaps.filterEntries.keys") .withFeatures(COLLECTION_FEATURES_REMOVE_ORDER) .suppressing(CollectionIteratorTester.getIteratorKnownOrderRemoveSupportedMethod()) .suppressing(MultisetWritesTester.getEntrySetIteratorMethod()) .suppressing(getIteratorDuplicateInitializingMethods()) .createTestSuite()); suite.addTest(CollectionTestSuiteBuilder.using( new TestEntrySetGenerator() { @Override SetMultimap<String, Integer> createMultimap() { return HashMultimap.create(); } }) .named("HashMultimap.entries") .withFeatures(CollectionSize.ANY, CollectionFeature.REMOVE_OPERATIONS) .createTestSuite()); suite.addTest(CollectionTestSuiteBuilder.using( new TestEntrySetGenerator() { @Override SetMultimap<String, Integer> createMultimap() { return LinkedHashMultimap.create(); } }) .named("LinkedHashMultimap.entries") .withFeatures(CollectionSize.ANY, CollectionFeature.REMOVE_OPERATIONS, CollectionFeature.KNOWN_ORDER) .createTestSuite()); suite.addTest(CollectionTestSuiteBuilder.using( new TestEntrySetGenerator() { @Override SetMultimap<String, Integer> createMultimap() { return TreeMultimap.create(Ordering.natural().nullsFirst(), Ordering.natural().nullsLast()); } }) .named("TreeMultimap.entries") .withFeatures(CollectionSize.ANY, CollectionFeature.REMOVE_OPERATIONS, CollectionFeature.KNOWN_ORDER) .createTestSuite()); suite.addTest(CollectionTestSuiteBuilder.using( new TestEntriesGenerator() { @Override Multimap<String, Integer> createMultimap() { return ArrayListMultimap.create(); } }) .named("ArrayListMultimap.entries") .withFeatures(CollectionSize.ANY, CollectionFeature.REMOVE_OPERATIONS) .createTestSuite()); suite.addTest(CollectionTestSuiteBuilder.using( new TestEntriesGenerator() { @Override Multimap<String, Integer> createMultimap() { return Multimaps.synchronizedListMultimap( ArrayListMultimap.<String, Integer>create()); } }) .named("synchronized ArrayListMultimap.entries") .withFeatures(CollectionSize.ANY, CollectionFeature.REMOVE_OPERATIONS) .createTestSuite()); suite.addTest(ListTestSuiteBuilder.using( new TestEntriesListGenerator() { @Override Multimap<String, Integer> createMultimap() { return LinkedListMultimap.create(); } }) .named("LinkedListMultimap.entries") .withFeatures(CollectionSize.ANY, ListFeature.REMOVE_OPERATIONS, CollectionFeature.KNOWN_ORDER) .createTestSuite()); suite.addTest(CollectionTestSuiteBuilder.using( new TestEntriesGenerator() { @Override Multimap<String, Integer> createMultimap() { return ImmutableListMultimap.of(); } @Override public Collection<Entry<String, Integer>> create( Object... elements) { ImmutableListMultimap.Builder<String, Integer> builder = ImmutableListMultimap.builder(); for (Object element : elements) { @SuppressWarnings("unchecked") Entry<String, Integer> entry = (Entry<String, Integer>) element; builder.put(entry.getKey(), entry.getValue()); } return builder.build().entries(); } }) .named("ImmutableListMultimap.entries") .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER) .createTestSuite()); suite.addTest(CollectionTestSuiteBuilder.using( new TestEntriesGenerator() { @Override Multimap<String, Integer> createMultimap() { Multimap<String, Integer> multimap = LinkedHashMultimap.create(); multimap.put("badkey", 3); multimap.put("a", 55556); return Multimaps.filterEntries(multimap, FILTER_KEYSET_PREDICATE); } }) .named("Multimap.filterEntries.entries") .withFeatures(CollectionSize.ANY, CollectionFeature.REMOVE_OPERATIONS, CollectionFeature.KNOWN_ORDER) .suppressing(CollectionIteratorTester.getIteratorKnownOrderRemoveSupportedMethod()) .createTestSuite()); suite.addTest(ListTestSuiteBuilder.using(new TestStringListGenerator() { @Override protected List<String> create(String[] elements) { ListMultimap<Integer, String> multimap = ArrayListMultimap.create(); populateMultimapForGet(multimap, elements); return Multimaps.transformValues( multimap, Functions.<String> identity()).get(3); } }).named("Multimaps.transformValues[ListMultimap].get").withFeatures( CollectionSize.ANY, CollectionFeature.ALLOWS_NULL_VALUES, CollectionFeature.REMOVE_OPERATIONS, ListFeature.SUPPORTS_REMOVE_WITH_INDEX).createTestSuite()); suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() { @Override protected Set<String> create(String[] elements) { ListMultimap<String, Integer> multimap = ArrayListMultimap.create(); populateMultimapForKeySet(multimap, elements); return Multimaps.transformValues( multimap, Functions.<Integer> identity()).keySet(); } }).named("Multimaps.transformValues[ListMultimap].keySet").withFeatures( CollectionSize.ANY, CollectionFeature.ALLOWS_NULL_VALUES, CollectionFeature.REMOVE_OPERATIONS).createTestSuite()); suite.addTest(MultisetTestSuiteBuilder.using( new TestStringMultisetGenerator() { @Override protected Multiset<String> create(String[] elements) { ListMultimap<String, Integer> multimap = ArrayListMultimap.create(); populateMultimapForKeys(multimap, elements); return Multimaps.transformValues( multimap, Functions.<Integer> identity()).keys(); } }) .named("Multimaps.transform[ListMultimap].keys") .withFeatures(COLLECTION_FEATURES_REMOVE) .createTestSuite()); suite.addTest( CollectionTestSuiteBuilder.using(new TestStringCollectionGenerator() { @Override public Collection<String> create(String[] elements) { ListMultimap<Integer, String> multimap = ArrayListMultimap.create(); populateMultimapForValues(multimap, elements); return Multimaps.transformValues( multimap, Functions.<String> identity()).values(); } }).named("Multimaps.transformValues[ListMultimap].values").withFeatures( COLLECTION_FEATURES_REMOVE).createTestSuite()); suite.addTest(CollectionTestSuiteBuilder.using(new TestEntriesGenerator() { @Override public Collection<Entry<String, Integer>> create( Object... elements) { ListMultimap<String, Integer> multimap = ArrayListMultimap.create(); for (Object element : elements) { @SuppressWarnings("unchecked") Entry<String, Integer> entry = (Entry<String, Integer>) element; multimap.put(entry.getKey(), entry.getValue()); } return Multimaps.transformValues( multimap, Functions.<Integer> identity()).entries(); } @Override Multimap<String, Integer> createMultimap() { return Multimaps.transformValues( ArrayListMultimap.<String, Integer> create(), Functions.<Integer> identity()); } }).named("Multimaps.transformValues[ListMultimap].entries") .withFeatures(CollectionSize.ANY, CollectionFeature.REMOVE_OPERATIONS) .createTestSuite()); suite.addTest( CollectionTestSuiteBuilder.using(new TestStringCollectionGenerator() { @Override protected Collection<String> create(String[] elements) { Multimap<Integer, String> multimap = ArrayListMultimap.create(); populateMultimapForGet(multimap, elements); return Multimaps.transformValues( multimap, Functions.<String> identity()).get(3); } }).named("Multimaps.transformValues[Multimap].get").withFeatures( CollectionSize.ANY, CollectionFeature.ALLOWS_NULL_VALUES, CollectionFeature.REMOVE_OPERATIONS).createTestSuite()); suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() { @Override protected Set<String> create(String[] elements) { Multimap<String, Integer> multimap = ArrayListMultimap.create(); populateMultimapForKeySet(multimap, elements); return Multimaps.transformValues( multimap, Functions.<Integer> identity()).keySet(); } }).named("Multimaps.transformValues[Multimap].keySet").withFeatures( COLLECTION_FEATURES_REMOVE).createTestSuite()); suite.addTest(MultisetTestSuiteBuilder.using( new TestStringMultisetGenerator() { @Override protected Multiset<String> create(String[] elements) { Multimap<String, Integer> multimap = ArrayListMultimap.create(); populateMultimapForKeys(multimap, elements); return Multimaps.transformValues( multimap, Functions.<Integer> identity()).keys(); } }) .named("Multimaps.transformValues[Multimap].keys") .withFeatures(COLLECTION_FEATURES_REMOVE) .createTestSuite()); suite.addTest( CollectionTestSuiteBuilder.using(new TestStringCollectionGenerator() { @Override public Collection<String> create(String[] elements) { Multimap<Integer, String> multimap = ArrayListMultimap.create(); populateMultimapForValues(multimap, elements); return Multimaps.transformValues( multimap, Functions.<String> identity()).values(); } }).named("Multimaps.transformValues[Multimap].values").withFeatures( COLLECTION_FEATURES_REMOVE).createTestSuite()); suite.addTest(CollectionTestSuiteBuilder.using(new TestEntriesGenerator() { @Override public Collection<Entry<String, Integer>> create( Object... elements) { Multimap<String, Integer> multimap = ArrayListMultimap.create(); for (Object element : elements) { @SuppressWarnings("unchecked") Entry<String, Integer> entry = (Entry<String, Integer>) element; multimap.put(entry.getKey(), entry.getValue()); } return Multimaps.transformValues( multimap, Functions.<Integer> identity()).entries(); } @Override Multimap<String, Integer> createMultimap() { return Multimaps.transformValues( (Multimap<String, Integer>) ArrayListMultimap.<String, Integer> create(), Functions.<Integer> identity()); } }).named("Multimaps.transformValues[Multimap].entries") .withFeatures(CollectionSize.ANY, CollectionFeature.REMOVE_OPERATIONS) .createTestSuite()); // TODO: use collection testers on Multimaps.forMap.entries return suite; } }