/* * 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.map.mutable.primitive; import com.gs.collections.api.block.function.primitive.BooleanFunction; import com.gs.collections.api.block.function.primitive.BooleanFunction0; import com.gs.collections.api.iterator.MutableBooleanIterator; import com.gs.collections.api.list.MutableList; import com.gs.collections.api.map.primitive.MutableObjectBooleanMap; import com.gs.collections.impl.list.mutable.FastList; import com.gs.collections.impl.list.mutable.primitive.BooleanArrayList; import com.gs.collections.impl.test.Verify; import org.junit.Assert; import org.junit.Test; public abstract class AbstractMutableObjectBooleanMapTestCase extends AbstractObjectBooleanMapTestCase { protected final MutableObjectBooleanMap<String> map = this.classUnderTest(); @Override protected abstract MutableObjectBooleanMap<String> classUnderTest(); @Override protected abstract <T> MutableObjectBooleanMap<T> newWithKeysValues(T key1, boolean value1); @Override protected abstract <T> MutableObjectBooleanMap<T> newWithKeysValues(T key1, boolean value1, T key2, boolean value2); @Override protected abstract <T> MutableObjectBooleanMap<T> newWithKeysValues(T key1, boolean value1, T key2, boolean value2, T key3, boolean value3); @Override protected abstract <T> MutableObjectBooleanMap<T> newWithKeysValues(T key1, boolean value1, T key2, boolean value2, T key3, boolean value3, T key4, boolean value4); @Override protected abstract <T> MutableObjectBooleanMap<T> getEmptyMap(); @Override public void get() { super.get(); MutableObjectBooleanMap<String> map1 = this.classUnderTest(); map1.put("0", false); Assert.assertFalse(map1.get("0")); map1.put("5", true); Assert.assertTrue(map1.get("5")); map1.put(null, true); Assert.assertTrue(map1.get(null)); } @Override public void getIfAbsent() { super.getIfAbsent(); MutableObjectBooleanMap<String> map1 = this.classUnderTest(); map1.removeKey("0"); Assert.assertTrue(map1.getIfAbsent("0", true)); Assert.assertFalse(map1.getIfAbsent("0", false)); map1.put("0", false); Assert.assertFalse(map1.getIfAbsent("0", true)); map1.put("5", true); Assert.assertTrue(map1.getIfAbsent("5", false)); map1.put(null, false); Assert.assertFalse(map1.getIfAbsent(null, true)); } @Override public void getOrThrow() { super.getOrThrow(); MutableObjectBooleanMap<String> map1 = this.classUnderTest(); map1.removeKey("0"); Verify.assertThrows(IllegalStateException.class, () -> map1.getOrThrow("0")); map1.put("0", false); Assert.assertFalse(map1.getOrThrow("0")); map1.put("5", true); Assert.assertTrue(map1.getOrThrow("5")); map1.put(null, false); Assert.assertFalse(map1.getOrThrow(null)); } @Override public void containsKey() { super.containsKey(); MutableObjectBooleanMap<String> map1 = this.classUnderTest(); map1.removeKey("0"); Assert.assertFalse(map1.containsKey("0")); Assert.assertFalse(map1.get("0")); map1.removeKey("0"); Assert.assertFalse(map1.containsKey("0")); Assert.assertFalse(map1.get("0")); map1.removeKey("1"); Assert.assertFalse(map1.containsKey("1")); Assert.assertFalse(map1.get("1")); map1.removeKey("2"); Assert.assertFalse(map1.containsKey("2")); Assert.assertFalse(map1.get("2")); map1.removeKey("3"); Assert.assertFalse(map1.containsKey("3")); Assert.assertFalse(map1.get("3")); map1.put(null, true); Assert.assertTrue(map1.containsKey(null)); map1.removeKey(null); Assert.assertFalse(map1.containsKey(null)); } @Override public void containsValue() { super.containsValue(); this.classUnderTest().clear(); this.classUnderTest().put("5", true); Assert.assertTrue(this.classUnderTest().containsValue(true)); this.classUnderTest().put(null, false); Assert.assertTrue(this.classUnderTest().containsValue(false)); } @Override public void size() { super.size(); MutableObjectBooleanMap<Integer> hashMap1 = this.newWithKeysValues(1, true, 0, false); Verify.assertSize(2, hashMap1); hashMap1.removeKey(1); Verify.assertSize(1, hashMap1); hashMap1.removeKey(0); Verify.assertSize(0, hashMap1); } @Override public void contains() { super.contains(); MutableObjectBooleanMap<String> map1 = this.classUnderTest(); map1.clear(); map1.put("5", true); Assert.assertTrue(map1.contains(true)); map1.put(null, false); Assert.assertTrue(map1.contains(false)); map1.removeKey("5"); Assert.assertFalse(map1.contains(true)); Assert.assertTrue(map1.contains(false)); map1.removeKey(null); Assert.assertFalse(map1.contains(false)); } @Override public void containsAll() { super.containsAll(); MutableObjectBooleanMap<String> map1 = this.classUnderTest(); map1.clear(); map1.put("5", true); Assert.assertTrue(map1.containsAll(true)); Assert.assertFalse(map1.containsAll(true, false)); Assert.assertFalse(map1.containsAll(false, false)); map1.put(null, false); Assert.assertTrue(map1.containsAll(false)); Assert.assertTrue(map1.containsAll(true, false)); map1.removeKey("5"); Assert.assertFalse(map1.containsAll(true)); Assert.assertFalse(map1.containsAll(true, false)); Assert.assertTrue(map1.containsAll(false, false)); map1.removeKey(null); Assert.assertFalse(map1.containsAll(false, true)); } @Override public void containsAllIterable() { super.containsAllIterable(); MutableObjectBooleanMap<String> map1 = this.classUnderTest(); map1.clear(); map1.put("5", true); Assert.assertTrue(map1.containsAll(BooleanArrayList.newListWith(true))); Assert.assertFalse(map1.containsAll(BooleanArrayList.newListWith(true, false))); Assert.assertFalse(map1.containsAll(BooleanArrayList.newListWith(false, false))); map1.put(null, false); Assert.assertTrue(map1.containsAll(BooleanArrayList.newListWith(false))); Assert.assertTrue(map1.containsAll(BooleanArrayList.newListWith(true, false))); map1.removeKey("5"); Assert.assertFalse(map1.containsAll(BooleanArrayList.newListWith(true))); Assert.assertFalse(map1.containsAll(BooleanArrayList.newListWith(true, false))); Assert.assertTrue(map1.containsAll(BooleanArrayList.newListWith(false, false))); map1.removeKey(null); Assert.assertFalse(map1.containsAll(BooleanArrayList.newListWith(false, true))); } protected static MutableList<String> generateCollisions() { MutableList<String> collisions = FastList.newList(); ObjectBooleanHashMap<String> hashMap = new ObjectBooleanHashMap<>(); for (int each = 3; collisions.size() <= 10; each++) { if (hashMap.spread(String.valueOf(each)) == hashMap.spread(String.valueOf(3))) { collisions.add(String.valueOf(each)); } } return collisions; } @Test public void clear() { MutableObjectBooleanMap<String> hashMap = this.getEmptyMap(); hashMap.put("0", true); hashMap.clear(); Assert.assertEquals(ObjectBooleanHashMap.newMap(), hashMap); hashMap.put("1", false); hashMap.clear(); Assert.assertEquals(ObjectBooleanHashMap.newMap(), hashMap); hashMap.put(null, true); hashMap.clear(); Assert.assertEquals(ObjectBooleanHashMap.newMap(), hashMap); } @Test public void removeKey() { MutableObjectBooleanMap<String> map0 = this.newWithKeysValues("0", true, "1", false); map0.removeKey("1"); Assert.assertEquals(this.newWithKeysValues("0", true), map0); map0.removeKey("0"); Assert.assertEquals(ObjectBooleanHashMap.newMap(), map0); MutableObjectBooleanMap<String> map1 = this.newWithKeysValues("0", false, "1", true); map1.removeKey("0"); Assert.assertEquals(this.newWithKeysValues("1", true), map1); map1.removeKey("1"); Assert.assertEquals(ObjectBooleanHashMap.newMap(), map1); this.map.removeKey("5"); Assert.assertEquals(this.newWithKeysValues("0", true, "1", true, "2", false), this.map); this.map.removeKey("0"); Assert.assertEquals(this.newWithKeysValues("1", true, "2", false), this.map); this.map.removeKey("1"); Assert.assertEquals(this.newWithKeysValues("2", false), this.map); this.map.removeKey("2"); Assert.assertEquals(ObjectBooleanHashMap.newMap(), this.map); this.map.removeKey("0"); this.map.removeKey("1"); this.map.removeKey("2"); Assert.assertEquals(ObjectBooleanHashMap.newMap(), this.map); Verify.assertEmpty(this.map); this.map.put(null, true); Assert.assertTrue(this.map.get(null)); this.map.removeKey(null); Assert.assertFalse(this.map.get(null)); } @Test public void put() { this.map.put("0", false); this.map.put("1", false); this.map.put("2", true); ObjectBooleanHashMap<String> expected = ObjectBooleanHashMap.newWithKeysValues("0", false, "1", false, "2", true); Assert.assertEquals(expected, this.map); this.map.put("5", true); expected.put("5", true); Assert.assertEquals(expected, this.map); this.map.put(null, false); expected.put(null, false); Assert.assertEquals(expected, this.map); } @Test public void putDuplicateWithRemovedSlot() { String collision1 = generateCollisions().getFirst(); String collision2 = generateCollisions().get(1); String collision3 = generateCollisions().get(2); String collision4 = generateCollisions().get(3); MutableObjectBooleanMap<String> hashMap = this.getEmptyMap(); hashMap.put(collision1, true); hashMap.put(collision2, false); hashMap.put(collision3, true); Assert.assertFalse(hashMap.get(collision2)); hashMap.removeKey(collision2); hashMap.put(collision4, false); Assert.assertEquals(this.newWithKeysValues(collision1, true, collision3, true, collision4, false), hashMap); MutableObjectBooleanMap<String> hashMap1 = this.getEmptyMap(); hashMap1.put(collision1, false); hashMap1.put(collision2, false); hashMap1.put(collision3, true); Assert.assertFalse(hashMap1.get(collision1)); hashMap1.removeKey(collision1); hashMap1.put(collision4, true); Assert.assertEquals(this.newWithKeysValues(collision2, false, collision3, true, collision4, true), hashMap1); MutableObjectBooleanMap<String> hashMap2 = this.getEmptyMap(); hashMap2.put(collision1, true); hashMap2.put(collision2, true); hashMap2.put(collision3, false); Assert.assertFalse(hashMap2.get(collision3)); hashMap2.removeKey(collision3); hashMap2.put(collision4, false); Assert.assertEquals(this.newWithKeysValues(collision1, true, collision2, true, collision4, false), hashMap2); MutableObjectBooleanMap<String> hashMap3 = this.getEmptyMap(); hashMap3.put(collision1, true); hashMap3.put(collision2, true); hashMap3.put(collision3, false); Assert.assertTrue(hashMap3.get(collision2)); Assert.assertFalse(hashMap3.get(collision3)); hashMap3.removeKey(collision2); hashMap3.removeKey(collision3); hashMap3.put(collision4, false); Assert.assertEquals(this.newWithKeysValues(collision1, true, collision4, false), hashMap3); MutableObjectBooleanMap<String> hashMap4 = this.getEmptyMap(); hashMap4.put(null, false); Assert.assertEquals(this.newWithKeysValues(null, false), hashMap4); hashMap4.put(null, true); Assert.assertEquals(this.newWithKeysValues(null, true), hashMap4); } @Test public void getIfAbsentPut_Function() { MutableObjectBooleanMap<Integer> map1 = this.getEmptyMap(); Assert.assertTrue(map1.getIfAbsentPut(0, () -> true)); BooleanFunction0 factoryThrows = () -> { throw new AssertionError(); }; Assert.assertTrue(map1.getIfAbsentPut(0, factoryThrows)); Assert.assertEquals(this.newWithKeysValues(0, true), map1); Assert.assertTrue(map1.getIfAbsentPut(1, () -> true)); Assert.assertTrue(map1.getIfAbsentPut(1, factoryThrows)); Assert.assertEquals(this.newWithKeysValues(0, true, 1, true), map1); MutableObjectBooleanMap<Integer> map2 = this.getEmptyMap(); Assert.assertFalse(map2.getIfAbsentPut(1, () -> false)); Assert.assertFalse(map2.getIfAbsentPut(1, factoryThrows)); Assert.assertEquals(this.newWithKeysValues(1, false), map2); Assert.assertFalse(map2.getIfAbsentPut(0, () -> false)); Assert.assertFalse(map2.getIfAbsentPut(0, factoryThrows)); Assert.assertEquals(this.newWithKeysValues(0, false, 1, false), map2); MutableObjectBooleanMap<Integer> map3 = this.getEmptyMap(); Assert.assertTrue(map3.getIfAbsentPut(null, () -> true)); Assert.assertTrue(map3.getIfAbsentPut(null, factoryThrows)); Assert.assertEquals(this.newWithKeysValues(null, true), map3); } @Test public void getIfAbsentPutWith() { BooleanFunction<String> functionLengthEven = string -> (string.length() & 1) == 0; MutableObjectBooleanMap<Integer> map1 = this.getEmptyMap(); Assert.assertFalse(map1.getIfAbsentPutWith(0, functionLengthEven, "123456789")); BooleanFunction<String> functionThrows = string -> { throw new AssertionError(); }; Assert.assertFalse(map1.getIfAbsentPutWith(0, functionThrows, "unused")); Assert.assertEquals(this.newWithKeysValues(0, false), map1); Assert.assertFalse(map1.getIfAbsentPutWith(1, functionLengthEven, "123456789")); Assert.assertFalse(map1.getIfAbsentPutWith(1, functionThrows, "unused")); Assert.assertEquals(this.newWithKeysValues(0, false, 1, false), map1); MutableObjectBooleanMap<Integer> map2 = this.getEmptyMap(); Assert.assertTrue(map2.getIfAbsentPutWith(1, functionLengthEven, "1234567890")); Assert.assertTrue(map2.getIfAbsentPutWith(1, functionThrows, "unused0")); Assert.assertEquals(this.newWithKeysValues(1, true), map2); Assert.assertTrue(map2.getIfAbsentPutWith(0, functionLengthEven, "1234567890")); Assert.assertTrue(map2.getIfAbsentPutWith(0, functionThrows, "unused0")); Assert.assertEquals(this.newWithKeysValues(0, true, 1, true), map2); MutableObjectBooleanMap<Integer> map3 = this.getEmptyMap(); Assert.assertFalse(map3.getIfAbsentPutWith(null, functionLengthEven, "123456789")); Assert.assertFalse(map3.getIfAbsentPutWith(null, functionThrows, "unused")); Assert.assertEquals(this.newWithKeysValues(null, false), map3); } @Test public void getIfAbsentPutWithKey() { BooleanFunction<Integer> function = anObject -> anObject == null || (anObject & 1) == 0; MutableObjectBooleanMap<Integer> map1 = this.getEmptyMap(); Assert.assertTrue(map1.getIfAbsentPutWithKey(0, function)); BooleanFunction<Integer> functionThrows = anObject -> { throw new AssertionError(); }; Assert.assertTrue(map1.getIfAbsentPutWithKey(0, functionThrows)); Assert.assertEquals(this.newWithKeysValues(0, true), map1); Assert.assertFalse(map1.getIfAbsentPutWithKey(1, function)); Assert.assertFalse(map1.getIfAbsentPutWithKey(1, functionThrows)); Assert.assertEquals(this.newWithKeysValues(0, true, 1, false), map1); MutableObjectBooleanMap<Integer> map2 = this.getEmptyMap(); Assert.assertFalse(map2.getIfAbsentPutWithKey(1, function)); Assert.assertFalse(map2.getIfAbsentPutWithKey(1, functionThrows)); Assert.assertEquals(this.newWithKeysValues(1, false), map2); Assert.assertTrue(map2.getIfAbsentPutWithKey(0, function)); Assert.assertTrue(map2.getIfAbsentPutWithKey(0, functionThrows)); Assert.assertEquals(this.newWithKeysValues(0, true, 1, false), map2); MutableObjectBooleanMap<Integer> map3 = this.getEmptyMap(); Assert.assertTrue(map3.getIfAbsentPutWithKey(null, function)); Assert.assertTrue(map3.getIfAbsentPutWithKey(null, functionThrows)); Assert.assertEquals(this.newWithKeysValues(null, true), map3); } @Test public void withKeysValues() { MutableObjectBooleanMap<Integer> emptyMap = this.getEmptyMap(); MutableObjectBooleanMap<Integer> hashMap = emptyMap.withKeyValue(1, true); Assert.assertEquals(this.newWithKeysValues(1, true), hashMap); Assert.assertSame(emptyMap, hashMap); } @Test public void withoutKey() { MutableObjectBooleanMap<Integer> hashMap = this.newWithKeysValues(1, true, 2, true, 3, false, 4, false); MutableObjectBooleanMap<Integer> actual = hashMap.withoutKey(5); Assert.assertSame(hashMap, actual); Assert.assertEquals(this.newWithKeysValues(1, true, 2, true, 3, false, 4, false), actual); Assert.assertEquals(this.newWithKeysValues(1, true, 2, true, 3, false), hashMap.withoutKey(4)); Assert.assertEquals(this.newWithKeysValues(1, true, 2, true), hashMap.withoutKey(3)); Assert.assertEquals(this.newWithKeysValues(1, true), hashMap.withoutKey(2)); Assert.assertEquals(ObjectBooleanHashMap.newMap(), hashMap.withoutKey(1)); Assert.assertEquals(ObjectBooleanHashMap.newMap(), hashMap.withoutKey(1)); } @Test public void withoutAllKeys() { MutableObjectBooleanMap<Integer> hashMap = this.newWithKeysValues(1, true, 2, true, 3, false, 4, false); MutableObjectBooleanMap<Integer> actual = hashMap.withoutAllKeys(FastList.newListWith(5, 6, 7)); Assert.assertSame(hashMap, actual); Assert.assertEquals(this.newWithKeysValues(1, true, 2, true, 3, false, 4, false), actual); Assert.assertEquals(this.newWithKeysValues(1, true, 2, true), hashMap.withoutAllKeys(FastList.newListWith(5, 4, 3))); Assert.assertEquals(this.newWithKeysValues(1, true), hashMap.withoutAllKeys(FastList.newListWith(2))); Assert.assertEquals(ObjectBooleanHashMap.newMap(), hashMap.withoutAllKeys(FastList.newListWith(1))); Assert.assertEquals(ObjectBooleanHashMap.newMap(), hashMap.withoutAllKeys(FastList.newListWith(5, 6))); } @Test public void asUnmodifiable() { Verify.assertInstanceOf(UnmodifiableObjectBooleanMap.class, this.map.asUnmodifiable()); Assert.assertEquals(new UnmodifiableObjectBooleanMap<>(this.map), this.map.asUnmodifiable()); } @Test public void asSynchronized() { Verify.assertInstanceOf(SynchronizedObjectBooleanMap.class, this.map.asSynchronized()); Assert.assertEquals(new SynchronizedObjectBooleanMap<>(this.map), this.map.asSynchronized()); } @Test public void iterator_remove() { MutableObjectBooleanMap<String> map = this.classUnderTest(); Verify.assertNotEmpty(map); MutableBooleanIterator booleanIterator = map.booleanIterator(); while (booleanIterator.hasNext()) { booleanIterator.next(); booleanIterator.remove(); } Verify.assertEmpty(map); } @Test public void iterator_throws_on_consecutive_invocation_of_remove() { MutableObjectBooleanMap<String> map = this.classUnderTest(); Verify.assertNotEmpty(map); MutableBooleanIterator booleanIterator = map.booleanIterator(); Assert.assertTrue(booleanIterator.hasNext()); booleanIterator.next(); booleanIterator.remove(); Verify.assertThrows(IllegalStateException.class, booleanIterator::remove); } @Test public void iterator_throws_on_invocation_of_remove_before_next() { MutableObjectBooleanMap<String> map = this.classUnderTest(); MutableBooleanIterator booleanIterator = map.booleanIterator(); Assert.assertTrue(booleanIterator.hasNext()); Verify.assertThrows(IllegalStateException.class, booleanIterator::remove); } }