/*
* Copyright 2015 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.bimap.mutable;
import java.util.Iterator;
import java.util.NoSuchElementException;
import com.gs.collections.api.bimap.BiMap;
import com.gs.collections.api.bimap.ImmutableBiMap;
import com.gs.collections.api.bimap.MutableBiMap;
import com.gs.collections.api.block.function.Function2;
import com.gs.collections.api.multimap.set.MutableSetMultimap;
import com.gs.collections.api.set.MutableSet;
import com.gs.collections.impl.IntegerWithCast;
import com.gs.collections.impl.factory.BiMaps;
import com.gs.collections.impl.map.mutable.MutableMapIterableTestCase;
import com.gs.collections.impl.map.mutable.UnifiedMap;
import com.gs.collections.impl.multimap.set.UnifiedSetMultimap;
import com.gs.collections.impl.set.mutable.UnifiedSet;
import com.gs.collections.impl.test.Verify;
import org.junit.Assert;
import org.junit.Test;
public abstract class AbstractMutableBiMapTestCase extends MutableMapIterableTestCase
{
public abstract MutableBiMap<Integer, Character> classUnderTest();
public abstract MutableBiMap<Integer, Character> getEmptyMap();
@Override
protected abstract <K, V> MutableBiMap<K, V> newMap();
@Override
protected abstract <K, V> MutableBiMap<K, V> newMapWithKeyValue(K key, V value);
@Override
protected abstract <K, V> MutableBiMap<K, V> newMapWithKeysValues(K key1, V value1, K key2, V value2);
@Override
protected abstract <K, V> MutableBiMap<K, V> newMapWithKeysValues(K key1, V value1, K key2, V value2, K key3, V value3);
@Override
protected abstract <K, V> MutableBiMap<K, V> newMapWithKeysValues(K key1, V value1, K key2, V value2, K key3, V value3, K key4, V value4);
public static void assertBiMapsEqual(BiMap<?, ?> expected, BiMap<?, ?> actual)
{
Assert.assertEquals(expected, actual);
Assert.assertEquals(expected.inverse(), actual.inverse());
}
@Test
@Override
public void flip()
{
Verify.assertEmpty(this.newMap().flip());
MutableSetMultimap<Integer, String> expected = UnifiedSetMultimap.newMultimap();
expected.put(1, "One");
expected.put(2, "Two");
expected.put(3, "Three");
expected.put(4, "Four");
Assert.assertEquals(
expected,
this.newMapWithKeysValues("One", 1, "Two", 2, "Three", 3, "Four", 4).flip());
}
@Test
public void size()
{
Verify.assertSize(3, this.classUnderTest());
Verify.assertSize(0, this.getEmptyMap());
}
@Test
public void forcePut()
{
MutableBiMap<Integer, Character> biMap = this.classUnderTest();
Assert.assertNull(biMap.forcePut(4, 'd'));
AbstractMutableBiMapTestCase.assertBiMapsEqual(HashBiMap.newWithKeysValues(1, null, null, 'b', 3, 'c', 4, 'd'), biMap);
Assert.assertEquals(UnifiedMap.newWithKeysValues(1, null, null, 'b', 3, 'c', 4, 'd'), biMap);
Assert.assertNull(biMap.forcePut(1, null));
AbstractMutableBiMapTestCase.assertBiMapsEqual(HashBiMap.newWithKeysValues(1, null, null, 'b', 3, 'c', 4, 'd'), biMap);
Assert.assertNull(biMap.forcePut(1, 'e'));
AbstractMutableBiMapTestCase.assertBiMapsEqual(HashBiMap.newWithKeysValues(1, 'e', null, 'b', 3, 'c', 4, 'd'), biMap);
Assert.assertNull(biMap.forcePut(5, 'e'));
AbstractMutableBiMapTestCase.assertBiMapsEqual(HashBiMap.newWithKeysValues(5, 'e', null, 'b', 3, 'c', 4, 'd'), biMap);
Assert.assertEquals(Character.valueOf('d'), biMap.forcePut(4, 'e'));
AbstractMutableBiMapTestCase.assertBiMapsEqual(HashBiMap.newWithKeysValues(4, 'e', null, 'b', 3, 'c'), biMap);
HashBiMap<Integer, Character> actual = HashBiMap.newMap();
actual.forcePut(1, null);
AbstractMutableBiMapTestCase.assertBiMapsEqual(HashBiMap.newWithKeysValues(1, null), actual);
}
@Override
@Test
public void put()
{
MutableBiMap<Integer, Character> biMap = this.classUnderTest();
Assert.assertNull(biMap.put(4, 'd'));
AbstractMutableBiMapTestCase.assertBiMapsEqual(HashBiMap.newWithKeysValues(1, null, null, 'b', 3, 'c', 4, 'd'), biMap);
Assert.assertEquals(UnifiedMap.newWithKeysValues(1, null, null, 'b', 3, 'c', 4, 'd'), biMap);
Assert.assertNull(biMap.put(1, null));
AbstractMutableBiMapTestCase.assertBiMapsEqual(HashBiMap.newWithKeysValues(1, null, null, 'b', 3, 'c', 4, 'd'), biMap);
Assert.assertNull(biMap.put(1, 'e'));
AbstractMutableBiMapTestCase.assertBiMapsEqual(HashBiMap.newWithKeysValues(1, 'e', null, 'b', 3, 'c', 4, 'd'), biMap);
Verify.assertThrows(IllegalArgumentException.class, () -> biMap.put(5, 'e'));
AbstractMutableBiMapTestCase.assertBiMapsEqual(HashBiMap.newWithKeysValues(1, 'e', null, 'b', 3, 'c', 4, 'd'), biMap);
Verify.assertThrows(IllegalArgumentException.class, () -> biMap.put(4, 'e'));
AbstractMutableBiMapTestCase.assertBiMapsEqual(HashBiMap.newWithKeysValues(1, 'e', null, 'b', 3, 'c', 4, 'd'), biMap);
HashBiMap<Integer, Character> actual = HashBiMap.newMap();
actual.put(1, null);
AbstractMutableBiMapTestCase.assertBiMapsEqual(HashBiMap.newWithKeysValues(1, null), actual);
}
@Override
@Test
public void flipUniqueValues()
{
MutableBiMap<Integer, Character> map = this.classUnderTest();
MutableBiMap<Character, Integer> result = map.flipUniqueValues();
Assert.assertEquals(map.inverse(), result);
Assert.assertNotSame(map.inverse(), result);
result.put('d', 4);
Assert.assertEquals(this.classUnderTest(), map);
}
@Test
public void get()
{
MutableBiMap<Integer, Character> biMap = this.classUnderTest();
Assert.assertNull(biMap.get(1));
Assert.assertEquals(Character.valueOf('b'), biMap.get(null));
Assert.assertEquals(Character.valueOf('c'), biMap.get(3));
Assert.assertNull(biMap.get(4));
Assert.assertNull(biMap.put(4, 'd'));
Assert.assertNull(biMap.get(1));
Assert.assertEquals(Character.valueOf('b'), biMap.get(null));
Assert.assertEquals(Character.valueOf('c'), biMap.get(3));
Assert.assertEquals(Character.valueOf('d'), biMap.get(4));
Assert.assertNull(biMap.put(1, null));
Assert.assertNull(biMap.get(1));
Assert.assertEquals(Character.valueOf('b'), biMap.get(null));
Assert.assertEquals(Character.valueOf('c'), biMap.get(3));
Assert.assertEquals(Character.valueOf('d'), biMap.get(4));
Assert.assertNull(biMap.forcePut(1, 'e'));
Assert.assertEquals(Character.valueOf('e'), biMap.get(1));
Assert.assertEquals(Character.valueOf('b'), biMap.get(null));
Assert.assertEquals(Character.valueOf('c'), biMap.get(3));
Assert.assertEquals(Character.valueOf('d'), biMap.get(4));
Assert.assertNull(biMap.forcePut(5, 'e'));
Assert.assertNull(biMap.get(1));
Assert.assertEquals(Character.valueOf('e'), biMap.get(5));
Assert.assertEquals(Character.valueOf('b'), biMap.get(null));
Assert.assertEquals(Character.valueOf('c'), biMap.get(3));
Assert.assertEquals(Character.valueOf('d'), biMap.get(4));
Assert.assertEquals(Character.valueOf('d'), biMap.forcePut(4, 'e'));
Assert.assertNull(biMap.get(1));
Assert.assertNull(biMap.get(5));
Assert.assertEquals(Character.valueOf('b'), biMap.get(null));
Assert.assertEquals(Character.valueOf('c'), biMap.get(3));
Assert.assertEquals(Character.valueOf('e'), biMap.get(4));
HashBiMap<Integer, Character> actual = HashBiMap.newMap();
Assert.assertNull(actual.get(1));
actual.put(1, null);
Assert.assertNull(actual.get(1));
}
@Override
@Test
public void containsKey()
{
super.containsKey();
MutableBiMap<Integer, Character> biMap = this.classUnderTest();
Assert.assertTrue(biMap.containsKey(1));
Assert.assertTrue(biMap.containsKey(null));
Assert.assertTrue(biMap.containsKey(3));
Assert.assertFalse(biMap.containsKey(4));
Assert.assertNull(biMap.put(4, 'd'));
Assert.assertTrue(biMap.containsKey(1));
Assert.assertTrue(biMap.containsKey(null));
Assert.assertTrue(biMap.containsKey(3));
Assert.assertTrue(biMap.containsKey(4));
Assert.assertNull(biMap.put(1, null));
Assert.assertTrue(biMap.containsKey(1));
Assert.assertTrue(biMap.containsKey(null));
Assert.assertTrue(biMap.containsKey(3));
Assert.assertTrue(biMap.containsKey(4));
Assert.assertNull(biMap.forcePut(1, 'e'));
Assert.assertTrue(biMap.containsKey(1));
Assert.assertTrue(biMap.containsKey(null));
Assert.assertTrue(biMap.containsKey(3));
Assert.assertTrue(biMap.containsKey(4));
Assert.assertNull(biMap.forcePut(5, 'e'));
Assert.assertFalse(biMap.containsKey(1));
Assert.assertTrue(biMap.containsKey(5));
Assert.assertTrue(biMap.containsKey(null));
Assert.assertTrue(biMap.containsKey(3));
Assert.assertTrue(biMap.containsKey(4));
Assert.assertEquals(Character.valueOf('d'), biMap.forcePut(4, 'e'));
Assert.assertFalse(biMap.containsKey(1));
Assert.assertTrue(biMap.containsKey(null));
Assert.assertTrue(biMap.containsKey(3));
Assert.assertTrue(biMap.containsKey(4));
Assert.assertFalse(biMap.containsKey(5));
HashBiMap<Integer, Character> actual = HashBiMap.newMap();
actual.put(1, null);
Assert.assertTrue(actual.containsKey(1));
Assert.assertFalse(actual.containsKey(0));
}
@Override
@Test
public void containsValue()
{
super.containsValue();
MutableBiMap<Integer, Character> biMap = this.classUnderTest();
Assert.assertTrue(biMap.containsValue(null));
Assert.assertTrue(biMap.containsValue('b'));
Assert.assertTrue(biMap.containsValue('c'));
Assert.assertFalse(biMap.containsValue('d'));
Assert.assertNull(biMap.put(4, 'd'));
Assert.assertTrue(biMap.containsValue(null));
Assert.assertTrue(biMap.containsValue('b'));
Assert.assertTrue(biMap.containsValue('c'));
Assert.assertTrue(biMap.containsValue('d'));
Assert.assertNull(biMap.put(1, null));
Assert.assertTrue(biMap.containsValue(null));
Assert.assertTrue(biMap.containsValue('b'));
Assert.assertTrue(biMap.containsValue('c'));
Assert.assertTrue(biMap.containsValue('d'));
Assert.assertNull(biMap.forcePut(1, 'e'));
Assert.assertTrue(biMap.containsValue('e'));
Assert.assertFalse(biMap.containsValue(null));
Assert.assertTrue(biMap.containsValue('b'));
Assert.assertTrue(biMap.containsValue('c'));
Assert.assertTrue(biMap.containsValue('d'));
Assert.assertNull(biMap.forcePut(5, 'e'));
Assert.assertFalse(biMap.containsValue(null));
Assert.assertTrue(biMap.containsValue('e'));
Assert.assertTrue(biMap.containsValue('b'));
Assert.assertTrue(biMap.containsValue('c'));
Assert.assertTrue(biMap.containsValue('d'));
Assert.assertEquals(Character.valueOf('d'), biMap.forcePut(4, 'e'));
Assert.assertFalse(biMap.containsValue(null));
Assert.assertTrue(biMap.containsValue('e'));
Assert.assertTrue(biMap.containsValue('b'));
Assert.assertTrue(biMap.containsValue('c'));
Assert.assertFalse(biMap.containsValue('d'));
HashBiMap<Integer, Character> actual = HashBiMap.newMap();
actual.put(1, null);
Assert.assertTrue(actual.containsValue(null));
Assert.assertFalse(actual.containsValue('\0'));
}
@Override
@Test
public void putAll()
{
MutableBiMap<Integer, Character> biMap = this.classUnderTest();
biMap.putAll(UnifiedMap.<Integer, Character>newMap());
AbstractMutableBiMapTestCase.assertBiMapsEqual(HashBiMap.newWithKeysValues(1, null, null, 'b', 3, 'c'), biMap);
biMap.putAll(UnifiedMap.newWithKeysValues(1, null, null, 'b', 3, 'c'));
HashBiMap<Integer, Character> expected = HashBiMap.newWithKeysValues(1, null, null, 'b', 3, 'c');
Assert.assertEquals(expected, biMap);
biMap.putAll(UnifiedMap.newWithKeysValues(4, 'd', 5, 'e', 6, 'f'));
expected.put(4, 'd');
expected.put(5, 'e');
expected.put(6, 'f');
Assert.assertEquals(expected, biMap);
}
@Test
public void remove()
{
MutableBiMap<Integer, Character> biMap = this.classUnderTest();
Assert.assertNull(biMap.remove(4));
Verify.assertSize(3, biMap);
Assert.assertNull(biMap.remove(1));
Assert.assertNull(biMap.get(1));
Assert.assertNull(biMap.inverse().get(null));
AbstractMutableBiMapTestCase.assertBiMapsEqual(HashBiMap.newWithKeysValues(null, 'b', 3, 'c'), biMap);
Assert.assertEquals(Character.valueOf('b'), biMap.remove(null));
Assert.assertNull(biMap.get(null));
Assert.assertNull(biMap.inverse().get('b'));
AbstractMutableBiMapTestCase.assertBiMapsEqual(HashBiMap.newWithKeysValues(3, 'c'), biMap);
Assert.assertEquals(Character.valueOf('c'), biMap.remove(3));
Assert.assertNull(biMap.get(3));
Assert.assertNull(biMap.inverse().get('c'));
AbstractMutableBiMapTestCase.assertBiMapsEqual(HashBiMap.newMap(), biMap);
Verify.assertEmpty(biMap);
Assert.assertNull(HashBiMap.newMap().remove(1));
}
@Override
@Test
public void clear()
{
MutableBiMap<Integer, Character> biMap = this.classUnderTest();
biMap.clear();
Verify.assertEmpty(biMap);
AbstractMutableBiMapTestCase.assertBiMapsEqual(HashBiMap.newMap(), biMap);
}
@Test
public void testToString()
{
Assert.assertEquals("{}", this.getEmptyMap().toString());
String actualString = HashBiMap.newWithKeysValues(1, null, 2, 'b').toString();
Assert.assertTrue("{1=null, 2=b}".equals(actualString) || "{2=b, 1=null}".equals(actualString));
}
@Override
@Test
public void equalsAndHashCode()
{
super.equalsAndHashCode();
MutableBiMap<Integer, Character> emptyMap = this.getEmptyMap();
Verify.assertEqualsAndHashCode(UnifiedMap.newMap(), emptyMap);
Assert.assertEquals(emptyMap, emptyMap);
Verify.assertEqualsAndHashCode(UnifiedMap.newWithKeysValues(1, null, null, 'b', 3, 'c'), this.classUnderTest());
Verify.assertEqualsAndHashCode(UnifiedMap.newWithKeysValues(null, 'b', 1, null, 3, 'c'), this.classUnderTest());
Assert.assertNotEquals(HashBiMap.newWithKeysValues(null, 1, 'b', null, 'c', 3), this.classUnderTest());
Verify.assertEqualsAndHashCode(HashBiMap.newWithKeysValues(null, 1, 'b', null, 'c', 3), this.classUnderTest().inverse());
}
@Override
@Test
public void nullCollisionWithCastInEquals()
{
MutableBiMap<IntegerWithCast, String> mutableMap = this.newMap();
mutableMap.put(new IntegerWithCast(0), "Test 2");
mutableMap.forcePut(new IntegerWithCast(0), "Test 3");
mutableMap.put(null, "Test 1");
Assert.assertEquals(
this.newMapWithKeysValues(
new IntegerWithCast(0), "Test 3",
null, "Test 1"),
mutableMap);
Assert.assertEquals("Test 3", mutableMap.get(new IntegerWithCast(0)));
Assert.assertEquals("Test 1", mutableMap.get(null));
}
@Override
@Test
public void iterator()
{
MutableSet<Character> expected = UnifiedSet.newSetWith(null, 'b', 'c');
MutableSet<Character> actual = UnifiedSet.newSet();
MutableBiMap<Integer, Character> biMap = this.classUnderTest();
Iterator<Character> iterator = biMap.iterator();
Assert.assertTrue(iterator.hasNext());
Verify.assertThrows(IllegalStateException.class, iterator::remove);
Verify.assertSize(3, biMap);
Verify.assertSize(3, biMap.inverse());
for (int i = 0; i < 3; i++)
{
Assert.assertTrue(iterator.hasNext());
actual.add(iterator.next());
}
Assert.assertEquals(expected, actual);
Assert.assertFalse(iterator.hasNext());
Verify.assertThrows(NoSuchElementException.class, (Runnable) iterator::next);
Iterator<Character> iteratorRemove = biMap.iterator();
Assert.assertTrue(iteratorRemove.hasNext());
Character first = iteratorRemove.next();
iteratorRemove.remove();
MutableBiMap<Integer, Character> expectedMap = this.classUnderTest();
expectedMap.inverse().remove(first);
Assert.assertEquals(expectedMap, biMap);
Assert.assertEquals(expectedMap.inverse(), biMap.inverse());
Verify.assertSize(2, biMap);
Verify.assertSize(2, biMap.inverse());
Assert.assertTrue(iteratorRemove.hasNext());
Character second = iteratorRemove.next();
iteratorRemove.remove();
expectedMap.inverse().remove(second);
Assert.assertEquals(expectedMap, biMap);
Assert.assertEquals(expectedMap.inverse(), biMap.inverse());
Verify.assertSize(1, biMap);
Verify.assertSize(1, biMap.inverse());
Assert.assertTrue(iteratorRemove.hasNext());
Character third = iteratorRemove.next();
iteratorRemove.remove();
expectedMap.inverse().remove(third);
Assert.assertEquals(expectedMap, biMap);
Assert.assertEquals(expectedMap.inverse(), biMap.inverse());
Verify.assertEmpty(biMap);
Verify.assertEmpty(biMap.inverse());
Assert.assertFalse(iteratorRemove.hasNext());
Verify.assertThrows(NoSuchElementException.class, (Runnable) iteratorRemove::next);
}
@Override
@Test
public void updateValueWith()
{
MutableBiMap<Integer, Character> biMap = this.classUnderTest();
Function2<Character, Boolean, Character> toUpperOrLowerCase = (character, parameter) -> parameter ? Character.toUpperCase(character) : Character.toLowerCase(character);
Assert.assertEquals(Character.valueOf('D'), biMap.updateValueWith(4, () -> 'd', toUpperOrLowerCase, true));
AbstractMutableBiMapTestCase.assertBiMapsEqual(HashBiMap.newWithKeysValues(1, null, null, 'b', 3, 'c', 4, 'D'), biMap);
Assert.assertEquals(Character.valueOf('B'), biMap.updateValueWith(null, () -> 'd', toUpperOrLowerCase, true));
AbstractMutableBiMapTestCase.assertBiMapsEqual(HashBiMap.newWithKeysValues(1, null, null, 'B', 3, 'c', 4, 'D'), biMap);
Assert.assertEquals(Character.valueOf('d'), biMap.updateValueWith(4, () -> 'x', toUpperOrLowerCase, false));
AbstractMutableBiMapTestCase.assertBiMapsEqual(HashBiMap.newWithKeysValues(1, null, null, 'B', 3, 'c', 4, 'd'), biMap);
}
@Override
@Test
public void updateValue()
{
MutableBiMap<Integer, Character> biMap = this.classUnderTest();
Assert.assertEquals(Character.valueOf('D'), biMap.updateValue(4, () -> 'd', Character::toUpperCase));
AbstractMutableBiMapTestCase.assertBiMapsEqual(HashBiMap.newWithKeysValues(1, null, null, 'b', 3, 'c', 4, 'D'), biMap);
Assert.assertEquals(Character.valueOf('B'), biMap.updateValue(null, () -> 'd', Character::toUpperCase));
AbstractMutableBiMapTestCase.assertBiMapsEqual(HashBiMap.newWithKeysValues(1, null, null, 'B', 3, 'c', 4, 'D'), biMap);
}
@Override
@Test
public void updateValue_collisions()
{
// testing collisions not applicable here
}
@Override
@Test
public void updateValueWith_collisions()
{
// testing collisions not applicable here
}
@Override
public void toImmutable()
{
ImmutableBiMap<Integer, Character> expectedImmutableBiMap = BiMaps.immutable.of(null, 'b', 1, null, 3, 'c');
ImmutableBiMap<Integer, Character> characters = this.classUnderTest().toImmutable();
Assert.assertEquals(expectedImmutableBiMap, characters);
}
@Override
@Test(expected = UnsupportedOperationException.class)
public void asSynchronized()
{
//asSynchronized not implemented yet
this.classUnderTest().asSynchronized();
}
@Test
public void testClone()
{
MutableBiMap<Integer, String> map = this.newMapWithKeysValues(1, "One", 2, "Two");
MutableBiMap<Integer, String> clone = map.clone();
Assert.assertNotSame(map, clone);
Verify.assertEqualsAndHashCode(map, clone);
}
}