/* * ModeShape (http://www.modeshape.org) * * 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 org.modeshape.common.collection; import static org.hamcrest.core.Is.is; import static org.junit.Assert.assertThat; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import org.junit.After; import org.junit.Before; import org.junit.Test; public abstract class AbstractMultimapTest { protected Multimap<String, String> multimap; protected String[] keys; protected String[] values; @Before public void beforeEach() { multimap = createMultimap(); keys = new String[] {"key1", "key2", "key3", "key4"}; values = new String[] {"value1", "value2", "value3", "value4", "value5", "value6"}; } @After public void afterEach() { multimap = null; } protected abstract <K, V> Multimap<K, V> createMultimap(); protected abstract boolean valuesAllowDuplicates(); @Test public void shouldBeEmptyAfterCreation() { assertThat(multimap.isEmpty(), is(true)); } @Test public void shouldHaveZeroSizeAfterCreation() { assertThat(multimap.size(), is(0)); } @Test public void shouldNotBeEmptyAfterAddingKeyValuePairToEmptyCollection() { multimap.put(keys[0], values[0]); assertThat(multimap.isEmpty(), is(false)); assertThat(multimap.size(), is(1)); assertKeys(multimap, keys[0]); assertValues(multimap, keys[0], values[0]); assertEntries(multimap, entry(keys[0], values[0])); } @SuppressWarnings( "unchecked" ) @Test public void shouldNotBeEmptyAfterAddingKeyAndTwoValuesToEmptyCollection() { multimap.put(keys[0], values[0]); multimap.put(keys[0], values[1]); assertThat(multimap.isEmpty(), is(false)); assertThat(multimap.size(), is(2)); assertKeys(multimap, keys[0]); assertValues(multimap, keys[0], values[0], values[1]); assertEntries(multimap, entry(keys[0], values[0]), entry(keys[0], values[1])); } @SuppressWarnings( "unchecked" ) @Test public void shouldNotBeEmptyAfterAddingMultipleKeyValuePairsToEmptyCollection() { multimap.put(keys[0], values[0]); multimap.put(keys[1], values[1]); assertThat(multimap.isEmpty(), is(false)); assertThat(multimap.size(), is(2)); assertKeys(multimap, keys[0], keys[1]); assertValues(multimap, keys[0], values[0]); assertValues(multimap, keys[1], values[1]); assertEntries(multimap, entry(keys[0], values[0]), entry(keys[1], values[1])); } @SuppressWarnings( "unchecked" ) @Test public void shouldNotBeEmptyAfterAddingMultipleKeyValuePairsMultipleTimesToEmptyCollection() { for (int i = 0; i != 3; ++i) { multimap.put(keys[0], values[0]); multimap.put(keys[1], values[1]); } if (valuesAllowDuplicates()) { assertThat(multimap.isEmpty(), is(false)); assertThat(multimap.size(), is(6)); assertKeys(multimap, keys[0], keys[1]); assertValues(multimap, keys[0], values[0], values[0], values[0]); assertValues(multimap, keys[1], values[1], values[1], values[1]); Collection<Map.Entry<String, String>> entries = new ArrayList<Map.Entry<String, String>>(); for (int i = 0; i != 3; ++i) { entries.add(entry(keys[0], values[0])); entries.add(entry(keys[1], values[1])); } assertEntries(multimap, entries); } else { assertThat(multimap.isEmpty(), is(false)); assertThat(multimap.size(), is(2)); assertKeys(multimap, keys[0], keys[1]); assertValues(multimap, keys[0], values[0]); assertValues(multimap, keys[1], values[1]); assertEntries(multimap, entry(keys[0], values[0]), entry(keys[1], values[1])); } } @SuppressWarnings( "unchecked" ) @Test public void shouldAllowAddingToCollectionOfValues() { multimap.put(keys[0], values[0]); Collection<String> vals = multimap.get(keys[0]); vals.add(values[1]); vals.add(values[2]); assertThat(multimap.isEmpty(), is(false)); assertThat(multimap.size(), is(3)); assertKeys(multimap, keys[0]); assertValues(multimap, keys[0], values[0], values[1], values[2]); assertEntries(multimap, entry(keys[0], values[0]), entry(keys[0], values[1]), entry(keys[0], values[2])); } protected <K, V> Map.Entry<K, V> entry( K key, V value ) { return new ImmutableMapEntry<K, V>(key, value); } protected <K, V> void assertEntries( Multimap<K, V> multimap, Map.Entry<K, V> entry ) { assertEntries(multimap, java.util.Collections.singletonList(entry)); } @SafeVarargs protected final <K, V> void assertEntries( Multimap<K, V> multimap, Map.Entry<K, V>... entries ) { assertEntries(multimap, Arrays.asList(entries)); } protected <K, V> void assertEntries( Multimap<K, V> multimap, Collection<Map.Entry<K, V>> entries ) { Collection<Map.Entry<K, V>> actualEntries = multimap.entries(); assertThat(actualEntries.size(), is(entries.size())); assertThat(actualEntries.containsAll(entries), is(true)); assertThat(entries.containsAll(actualEntries), is(true)); } protected <K, V> void assertKeys( Multimap<K, V> multimap, K key ) { assertKeys(multimap, java.util.Collections.singletonList(key)); } @SafeVarargs protected final <K, V> void assertKeys( Multimap<K, V> multimap, K... keys ) { assertKeys(multimap, Arrays.asList(keys)); } protected <K, V> void assertKeys( Multimap<K, V> multimap, Collection<K> expectedKeys ) { Set<K> actualKeys = multimap.keySet(); assertThat(actualKeys.size(), is(expectedKeys.size())); assertThat(actualKeys.containsAll(expectedKeys), is(true)); assertThat(expectedKeys.containsAll(actualKeys), is(true)); } protected <K, V> void assertValues( Multimap<K, V> multimap, K key, V value ) { Collection<V> expectedValues = null; if (valuesAllowDuplicates()) { expectedValues = java.util.Collections.singletonList(value); } else { expectedValues = java.util.Collections.singleton(value); } assertValues(multimap, key, expectedValues); } @SafeVarargs protected final <K, V> void assertValues( Multimap<K, V> multimap, K key, V... values ) { Collection<V> expectedValues = null; if (valuesAllowDuplicates()) { expectedValues = Arrays.asList(values); } else { expectedValues = new HashSet<V>(Arrays.asList(values)); } assertValues(multimap, key, expectedValues); } protected <K, V> void assertValues( Multimap<K, V> multimap, K key, Collection<V> expectedValues ) { Collection<V> actualValues = multimap.get(key); assertThat(actualValues.size(), is(expectedValues.size())); if (actualValues instanceof List) { assertThat(actualValues, is(expectedValues)); Iterator<V> actualIter = actualValues.iterator(); Iterator<V> expectedIter = expectedValues.iterator(); while (expectedIter.hasNext()) { V actual = actualIter.next(); V expected = expectedIter.next(); assertThat(actual, is(expected)); } } else { assertThat(actualValues.containsAll(expectedValues), is(true)); assertThat(expectedValues.containsAll(actualValues), is(true)); } } }