/* * Copyright 2014 Goldman Sachs. * * 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.gs.collections.impl.multimap; import com.gs.collections.api.RichIterable; import com.gs.collections.api.bag.MutableBag; import com.gs.collections.api.collection.MutableCollection; import com.gs.collections.api.list.ListIterable; import com.gs.collections.api.list.MutableList; import com.gs.collections.api.multimap.Multimap; import com.gs.collections.api.set.MutableSet; import com.gs.collections.api.tuple.Pair; import com.gs.collections.impl.bag.mutable.HashBag; import com.gs.collections.impl.block.factory.Functions; import com.gs.collections.impl.block.procedure.CollectionAddProcedure; import com.gs.collections.impl.factory.Bags; import com.gs.collections.impl.factory.Lists; import com.gs.collections.impl.list.mutable.FastList; import com.gs.collections.impl.set.mutable.UnifiedSet; import com.gs.collections.impl.test.SerializeTestHelper; import com.gs.collections.impl.test.Verify; import com.gs.collections.impl.tuple.Tuples; import com.gs.collections.impl.utility.Iterate; import org.junit.Assert; import org.junit.Test; /** * Helper class for testing {@link Multimap}s. */ public abstract class AbstractMultimapTestCase { protected abstract <K, V> Multimap<K, V> newMultimap(); protected abstract <K, V> Multimap<K, V> newMultimapWithKeyValue( K key, V value); protected abstract <K, V> Multimap<K, V> newMultimapWithKeysValues( K key1, V value1, K key2, V value2); protected abstract <K, V> Multimap<K, V> newMultimapWithKeysValues( K key1, V value1, K key2, V value2, K key3, V value3); protected abstract <K, V> Multimap<K, V> newMultimapWithKeysValues( K key1, V value1, K key2, V value2, K key3, V value3, K key4, V value4); protected abstract <K, V> Multimap<K, V> newMultimap(Pair<K, V>... pairs); protected abstract <K, V> Multimap<K, V> newMultimapFromPairs(Iterable<Pair<K, V>> inputIterable); protected abstract <V> MutableCollection<V> createCollection(V... args); @Test public void testNewMultimap() { Multimap<Integer, Integer> multimap = this.newMultimap(); Verify.assertEmpty(multimap); Verify.assertSize(0, multimap); } @Test public void testNewMultimapWithKeyValue() { Multimap<Integer, String> multimap = this.newMultimapWithKeyValue(1, "One"); Verify.assertNotEmpty(multimap); Verify.assertSize(1, multimap); Verify.assertContainsEntry(1, "One", multimap); } @Test public void testNewMultimapWithWith() { Multimap<Integer, String> multimap = this.newMultimapWithKeysValues(1, "One", 2, "Two"); Verify.assertNotEmpty(multimap); Verify.assertSize(2, multimap); Verify.assertContainsAllEntries(multimap, 1, "One", 2, "Two"); } @Test public void testNewMultimapWithWithWith() { Multimap<Integer, String> multimap = this.newMultimapWithKeysValues(1, "One", 2, "Two", 3, "Three"); Verify.assertNotEmpty(multimap); Verify.assertSize(3, multimap); Verify.assertContainsAllEntries(multimap, 1, "One", 2, "Two", 3, "Three"); } @Test public void testNewMultimapWithWithWithWith() { Multimap<Integer, String> multimap = this.newMultimapWithKeysValues(1, "One", 2, "Two", 3, "Three", 4, "Four"); Verify.assertNotEmpty(multimap); Verify.assertSize(4, multimap); Verify.assertContainsAllEntries(multimap, 1, "One", 2, "Two", 3, "Three", 4, "Four"); } @Test public void testNewMultimapWith() { Pair<Integer, String> pair1 = Tuples.pair(1, "One"); Pair<Integer, String> pair2 = Tuples.pair(2, "Two"); Pair<Integer, String> pair3 = Tuples.pair(3, "Three"); Pair<Integer, String> pair4 = Tuples.pair(4, "Four"); ListIterable<Pair<Integer, String>> pairs = FastList.newListWith(pair1, pair2, pair3, pair4); Multimap<Integer, String> expected = this.newMultimap(pair1, pair2, pair3, pair4); Multimap<Integer, String> actual = this.newMultimapFromPairs(pairs); Assert.assertEquals(expected, actual); } @Test public void newMultimapFromPairs() { Multimap<Integer, String> expected = this.newMultimapWithKeysValues(1, "One", 2, "Two", 3, "Three", 4, "Four"); Multimap<Integer, String> actual = this.newMultimap(Tuples.pair(1, "One"), Tuples.pair(2, "Two"), Tuples.pair(3, "Three"), Tuples.pair(4, "Four")); Assert.assertEquals(expected, actual); } @Test public void isEmpty() { Verify.assertEmpty(this.newMultimap()); Verify.assertNotEmpty(this.newMultimapWithKeyValue(1, 1)); Assert.assertTrue(this.newMultimapWithKeyValue(1, 1).notEmpty()); } @Test public void forEachKeyValue() { MutableBag<String> collection = Bags.mutable.of(); Multimap<Integer, String> multimap = this.newMultimapWithKeysValues(1, "One", 2, "Two", 3, "Three"); multimap.forEachKeyValue((key, value) -> collection.add(key + value)); Assert.assertEquals(HashBag.newBagWith("1One", "2Two", "3Three"), collection); } @Test public void forEachKeyMultiValue() { MutableSet<Pair<Integer, Iterable<String>>> collection = UnifiedSet.newSet(); Multimap<Integer, String> multimap = this.newMultimapWithKeysValues(2, "2", 2, "1", 3, "3", 3, "3"); multimap.forEachKeyMultiValues((key, values) -> collection.add(Tuples.pair(key, values))); Assert.assertEquals(UnifiedSet.newSetWith(Tuples.pair(2, this.createCollection("2", "1")), Tuples.pair(3, this.createCollection("3", "3"))), collection); } @Test public void forEachValue() { MutableBag<String> collection = Bags.mutable.of(); Multimap<Integer, String> multimap = this.newMultimapWithKeysValues(1, "1", 2, "2", 3, "3"); multimap.forEachValue(CollectionAddProcedure.on(collection)); Assert.assertEquals(HashBag.newBagWith("1", "2", "3"), collection); } @Test public void valuesView() { Multimap<Integer, String> multimap = this.newMultimapWithKeysValues(1, "1", 2, "2", 3, "3"); Assert.assertEquals(Bags.mutable.of("1", "2", "3"), multimap.valuesView().toBag()); } @Test public void multiValuesView() { Multimap<Integer, String> multimap = this.newMultimapWithKeysValues(1, "1", 2, "2", 3, "3"); Assert.assertEquals(Bags.mutable.of("1", "2", "3"), multimap.multiValuesView().flatCollect(Functions.<RichIterable<String>>getPassThru()).toBag()); } @Test public void forEachKey() { MutableList<Integer> collection = Lists.mutable.of(); Multimap<Integer, String> multimap = this.newMultimapWithKeysValues(1, "1", 2, "2", 3, "3"); multimap.forEachKey(CollectionAddProcedure.on(collection)); Assert.assertEquals(FastList.newListWith(1, 2, 3), collection); } @Test public void notEmpty() { Assert.assertTrue(this.newMultimap().isEmpty()); Assert.assertFalse(this.newMultimap().notEmpty()); Assert.assertTrue(this.newMultimapWithKeysValues(1, "1", 2, "2").notEmpty()); } @Test public void keysWithMultiValuesView() { Multimap<Integer, String> multimap = this.newMultimapWithKeysValues(1, "1", 2, "2", 3, "3"); Assert.assertEquals(Bags.mutable.of(1, 2, 3), multimap.keyMultiValuePairsView().collect(Pair::getOne).toBag()); Assert.assertEquals( Bags.mutable.of("1", "2", "3"), multimap.keyMultiValuePairsView().flatCollect(Functions.secondOfPair()).toBag()); } @Test public void keyValuePairsView() { Multimap<Integer, String> multimap = this.newMultimapWithKeysValues(1, "1", 2, "2", 3, "3"); Assert.assertEquals(Bags.mutable.of(Tuples.pair(1, "1"), Tuples.pair(2, "2"), Tuples.pair(3, "3")), multimap.keyValuePairsView().toBag()); } @Test public void keyBag() { Multimap<Integer, String> multimap = this.newMultimapWithKeysValues(1, "1", 2, "2", 2, "2.1"); Assert.assertEquals(1, multimap.keyBag().occurrencesOf(1)); Assert.assertEquals(2, multimap.keyBag().occurrencesOf(2)); } @Test public void testEquals() { Multimap<Integer, String> map1 = this.newMultimapWithKeysValues(1, "1", 2, "2", 3, "3"); Multimap<Integer, String> map2 = this.newMultimapWithKeysValues(1, "1", 2, "2", 3, "3"); Multimap<Integer, String> map3 = this.newMultimapWithKeysValues(2, "2", 3, "3", 4, "4"); Assert.assertEquals(map1, map2); Assert.assertNotEquals(map2, map3); } @Test public void testHashCode() { Multimap<Integer, String> map1 = this.newMultimapWithKeysValues(1, "1", 2, "2", 3, "3"); Multimap<Integer, String> map2 = this.newMultimapWithKeysValues(1, "1", 2, "2", 3, "3"); Verify.assertEqualsAndHashCode(map1, map2); } @Test public void serialization() { Multimap<Integer, String> original = this.newMultimapWithKeysValues(1, "1", 2, "2", 3, "3"); Multimap<Integer, String> copy = SerializeTestHelper.serializeDeserialize(original); Verify.assertSize(3, copy); Verify.assertEqualsAndHashCode(original, copy); } @Test public void newEmpty() { Multimap<Object, Object> original = this.newMultimap(); Multimap<Object, Object> newEmpty = original.newEmpty(); Verify.assertEmpty(newEmpty); Assert.assertSame(original.getClass(), newEmpty.getClass()); Verify.assertEqualsAndHashCode(original, newEmpty); } @Test public void keysView() { Multimap<String, Integer> multimap = this.newMultimapWithKeysValues("One", 1, "Two", 2, "Three", 3); Assert.assertEquals(Bags.mutable.of("One", "Two", "Three"), multimap.keysView().toBag()); } @Test public void sizeDistinct() { Multimap<String, Integer> multimap = this.newMultimapWithKeysValues("One", 1, "Two", 2, "Two", 3); Verify.assertSize(3, multimap); Assert.assertEquals(2, multimap.sizeDistinct()); } @Test public void selectKeysValues() { Multimap<String, Integer> multimap = this.newMultimapWithKeysValues("One", 1, "One", 12, "Two", 2, "Two", 3); Multimap<String, Integer> selectedMultimap = multimap.selectKeysValues((key, value) -> ("Two".equals(key) && (value % 2 == 0))); Assert.assertEquals(this.newMultimapWithKeyValue("Two", 2), selectedMultimap); } @Test public void rejectKeysValues() { Multimap<String, Integer> multimap = this.newMultimapWithKeysValues("One", 1, "One", 12, "Two", 2, "Two", 4); Multimap<String, Integer> rejectedMultimap = multimap.rejectKeysValues((key, value) -> ("Two".equals(key) || (value % 2 == 0))); Assert.assertEquals(this.newMultimapWithKeyValue("One", 1), rejectedMultimap); } @Test public void selectKeysMultiValues() { Multimap<String, Integer> multimap = this.newMultimapWithKeysValues("One", 1, "One", 12, "Two", 2, "Two", 3); Multimap<String, Integer> selectedMultimap = multimap.selectKeysMultiValues((key, values) -> "Two".equals(key) && Iterate.contains(values, 2)); Assert.assertEquals(this.newMultimapWithKeysValues("Two", 2, "Two", 3), selectedMultimap); } @Test public void rejectKeysMultiValues() { Multimap<String, Integer> multimap = this.newMultimapWithKeysValues("One", 1, "One", 12, "Two", 2, "Two", 3); Multimap<String, Integer> rejectedMultimap = multimap.rejectKeysMultiValues((key, values) -> "Two".equals(key) && Iterate.contains(values, 2)); Assert.assertEquals(this.newMultimapWithKeysValues("One", 1, "One", 12), rejectedMultimap); } @Test public void collectKeysValues() { Multimap<String, Integer> multimap = this.newMultimapWithKeysValues("1", 1, "1", 12, "2", 2, "3", 3); Multimap<Integer, String> collectedMultimap = multimap.collectKeysValues((key, value) -> Tuples.pair(Integer.valueOf(key), value + "Value")); Multimap<Integer, String> expectedMultimap = this.newMultimapWithKeysValues(1, "1Value", 1, "12Value", 2, "2Value", 3, "3Value"); Assert.assertEquals(expectedMultimap, collectedMultimap); } @Test public void collectValues() { Multimap<String, Integer> multimap = this.newMultimapWithKeysValues("1", 1, "1", 12, "2", 2, "3", 3); Multimap<String, String> collectedMultimap = multimap.collectValues(value -> value + "Value"); Multimap<String, String> expectedMultimap = this.newMultimapWithKeysValues("1", "1Value", "1", "12Value", "2", "2Value", "3", "3Value"); Assert.assertEquals(expectedMultimap, collectedMultimap); } @Test public abstract void flip(); }