/* * 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.map.immutable; import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Map; import com.gs.collections.api.list.MutableList; import com.gs.collections.api.map.ImmutableMapIterable; import com.gs.collections.api.map.MutableMap; import com.gs.collections.api.set.MutableSet; import com.gs.collections.api.tuple.Pair; import com.gs.collections.impl.block.factory.Functions; import com.gs.collections.impl.block.function.PassThruFunction0; import com.gs.collections.impl.block.procedure.CollectionAddProcedure; import com.gs.collections.impl.factory.Lists; import com.gs.collections.impl.factory.Maps; import com.gs.collections.impl.list.Interval; import com.gs.collections.impl.list.fixed.ArrayAdapter; import com.gs.collections.impl.map.mutable.UnifiedMap; import com.gs.collections.impl.set.mutable.UnifiedSet; import com.gs.collections.impl.test.Verify; import com.gs.collections.impl.tuple.Tuples; import org.junit.Assert; import org.junit.Test; public abstract class ImmutableMapIterableTestCase { /** * @return A map containing 1 => "1", 2 => "2", etc. */ protected abstract ImmutableMapIterable<Integer, String> classUnderTest(); /** * @return Size (and max key) of {@link #classUnderTest()}. */ protected abstract int size(); @Test public void equalsAndHashCode() { MutableMap<Integer, String> expected = this.equalUnifiedMap(); Verify.assertEqualsAndHashCode(expected, this.classUnderTest()); Verify.assertPostSerializedEqualsAndHashCode(this.classUnderTest()); } @Test public void forEachKeyValue() { MutableSet<Integer> actualKeys = UnifiedSet.newSet(); MutableSet<String> actualValues = UnifiedSet.newSet(); this.classUnderTest().forEachKeyValue((key, value) -> { actualKeys.add(key); actualValues.add(value); }); MutableSet<Integer> expectedKeys = this.expectedKeys(); Assert.assertEquals(expectedKeys, actualKeys); MutableSet<String> expectedValues = expectedKeys.collect(String::valueOf); Assert.assertEquals(expectedValues, actualValues); } @Test public void forEachValue() { MutableSet<String> actualValues = UnifiedSet.newSet(); this.classUnderTest().forEachValue(CollectionAddProcedure.on(actualValues)); Assert.assertEquals(this.expectedValues(), actualValues); } @Test public void tap() { MutableList<String> tapResult = Lists.mutable.of(); ImmutableMapIterable<Integer, String> map = this.classUnderTest(); Assert.assertSame(map, map.tap(tapResult::add)); Assert.assertEquals(map.toList(), tapResult); } @Test public void forEach() { MutableSet<String> actualValues = UnifiedSet.newSet(); this.classUnderTest().forEach(CollectionAddProcedure.on(actualValues)); Assert.assertEquals(this.expectedValues(), actualValues); } @Test public void flipUniqueValues() { ImmutableMapIterable<Integer, String> immutableMap = this.classUnderTest(); Assert.assertEquals(Interval.oneTo(this.size()).toMap(String::valueOf, Functions.getIntegerPassThru()), immutableMap.flipUniqueValues()); } @Test public void iterator() { MutableSet<String> actualValues = UnifiedSet.newSet(); for (String eachValue : this.classUnderTest()) { actualValues.add(eachValue); } Assert.assertEquals(this.expectedValues(), actualValues); } @Test public void iteratorThrows() { Verify.assertThrows(UnsupportedOperationException.class, () -> { Iterator<String> iterator = this.classUnderTest().iterator(); iterator.remove(); }); } @Test public void forEachKey() { MutableSet<Integer> actualKeys = UnifiedSet.newSet(); this.classUnderTest().forEachKey(CollectionAddProcedure.on(actualKeys)); Assert.assertEquals(this.expectedKeys(), actualKeys); } @Test public void get() { Integer absentKey = this.size() + 1; String absentValue = String.valueOf(absentKey); // Absent key behavior ImmutableMapIterable<Integer, String> classUnderTest = this.classUnderTest(); Assert.assertNull(classUnderTest.get(absentKey)); Assert.assertFalse(classUnderTest.containsValue(absentValue)); // Present key behavior Assert.assertEquals("1", classUnderTest.get(1)); // Still unchanged Assert.assertEquals(this.equalUnifiedMap(), classUnderTest); } @Test public void getIfAbsent_function() { Integer absentKey = this.size() + 1; String absentValue = String.valueOf(absentKey); // Absent key behavior ImmutableMapIterable<Integer, String> classUnderTest = this.classUnderTest(); Assert.assertEquals(absentValue, classUnderTest.getIfAbsent(absentKey, new PassThruFunction0<>(absentValue))); // Present key behavior Assert.assertEquals("1", classUnderTest.getIfAbsent(1, new PassThruFunction0<>(absentValue))); // Still unchanged Assert.assertEquals(this.equalUnifiedMap(), classUnderTest); } @Test public void getIfAbsent() { Integer absentKey = this.size() + 1; String absentValue = String.valueOf(absentKey); // Absent key behavior ImmutableMapIterable<Integer, String> classUnderTest = this.classUnderTest(); Assert.assertEquals(absentValue, classUnderTest.getIfAbsentValue(absentKey, absentValue)); // Present key behavior Assert.assertEquals("1", classUnderTest.getIfAbsentValue(1, absentValue)); // Still unchanged Assert.assertEquals(this.equalUnifiedMap(), classUnderTest); } @Test public void getIfAbsentWith() { Integer absentKey = this.size() + 1; String absentValue = String.valueOf(absentKey); // Absent key behavior ImmutableMapIterable<Integer, String> classUnderTest = this.classUnderTest(); Assert.assertEquals(absentValue, classUnderTest.getIfAbsentWith(absentKey, String::valueOf, absentValue)); // Present key behavior Assert.assertEquals("1", classUnderTest.getIfAbsentWith(1, String::valueOf, absentValue)); // Still unchanged Assert.assertEquals(this.equalUnifiedMap(), classUnderTest); } @Test public void ifPresentApply() { Integer absentKey = this.size() + 1; ImmutableMapIterable<Integer, String> classUnderTest = this.classUnderTest(); Assert.assertNull(classUnderTest.ifPresentApply(absentKey, Functions.<String>getPassThru())); Assert.assertEquals("1", classUnderTest.ifPresentApply(1, Functions.<String>getPassThru())); } @Test public void notEmpty() { Assert.assertTrue(this.classUnderTest().notEmpty()); } @Test public void forEachWith() { Object actualParameter = new Object(); MutableSet<String> actualValues = UnifiedSet.newSet(); MutableList<Object> actualParameters = Lists.mutable.of(); this.classUnderTest().forEachWith((eachValue, parameter) -> { actualValues.add(eachValue); actualParameters.add(parameter); }, actualParameter); Assert.assertEquals(this.expectedKeys().collect(String::valueOf), actualValues); Assert.assertEquals(Collections.nCopies(this.size(), actualParameter), actualParameters); } @Test public void forEachWithIndex() { MutableSet<String> actualValues = UnifiedSet.newSet(); MutableList<Integer> actualIndices = Lists.mutable.of(); this.classUnderTest().forEachWithIndex((eachValue, index) -> { actualValues.add(eachValue); actualIndices.add(index); }); Assert.assertEquals(this.expectedKeys().collect(String::valueOf), actualValues); Assert.assertEquals(this.expectedIndices(), actualIndices); } @Test public void keyValuesView() { MutableSet<Integer> actualKeys = UnifiedSet.newSet(); MutableSet<String> actualValues = UnifiedSet.newSet(); for (Pair<Integer, String> entry : this.classUnderTest().keyValuesView()) { actualKeys.add(entry.getOne()); actualValues.add(entry.getTwo()); } MutableSet<Integer> expectedKeys = this.expectedKeys(); Assert.assertEquals(expectedKeys, actualKeys); MutableSet<String> expectedValues = expectedKeys.collect(String::valueOf); Assert.assertEquals(expectedValues, actualValues); } @Test public void valuesView() { MutableSet<String> actualValues = UnifiedSet.newSet(); for (String eachValue : this.classUnderTest().valuesView()) { actualValues.add(eachValue); } MutableSet<String> expectedValues = this.expectedValues(); Assert.assertEquals(expectedValues, actualValues); } @Test public void keysView() { MutableSet<Integer> actualKeys = UnifiedSet.newSet(); for (Integer eachKey : this.classUnderTest().keysView()) { actualKeys.add(eachKey); } Assert.assertEquals(this.expectedKeys(), actualKeys); } @Test public void putAll() { Verify.assertThrows(UnsupportedOperationException.class, () -> ((Map<Integer, String>) this.classUnderTest()).putAll(null)); } @Test public void clear() { Verify.assertThrows(UnsupportedOperationException.class, () -> ((Map<Integer, String>) this.classUnderTest()).clear()); } @Test public void put() { Verify.assertThrows(UnsupportedOperationException.class, () -> ((Map<Integer, String>) this.classUnderTest()).put(null, null)); } @Test public void remove() { Verify.assertThrows(UnsupportedOperationException.class, () -> ((Map<Integer, String>) this.classUnderTest()).remove(null)); } @Test public abstract void testToString(); protected MutableMap<Integer, String> equalUnifiedMap() { MutableMap<Integer, String> expected = UnifiedMap.newMap(); for (int i = 1; i <= this.size(); i++) { expected.put(i, String.valueOf(i)); } return expected; } private MutableSet<String> expectedValues() { return this.expectedKeys().collect(String::valueOf); } private MutableSet<Integer> expectedKeys() { if (this.size() == 0) { return UnifiedSet.newSet(); } return Interval.oneTo(this.size()).toSet(); } private List<Integer> expectedIndices() { if (this.size() == 0) { return Lists.mutable.of(); } return Interval.zeroTo(this.size() - 1); } @Test public void newWithKeyValue() { ImmutableMapIterable<Integer, String> immutable = this.classUnderTest(); ImmutableMapIterable<Integer, String> immutable2 = immutable.newWithKeyValue(Integer.MAX_VALUE, Integer.toString(Integer.MAX_VALUE)); Verify.assertSize(immutable.size() + 1, immutable2); } @Test public void newWithAllKeyValuePairs() { ImmutableMapIterable<Integer, String> immutable = this.classUnderTest(); ImmutableMapIterable<Integer, String> immutable2 = immutable.newWithAllKeyValueArguments( Tuples.pair(Integer.MAX_VALUE, Integer.toString(Integer.MAX_VALUE)), Tuples.pair(Integer.MIN_VALUE, Integer.toString(Integer.MIN_VALUE))); Verify.assertSize(immutable.size() + 2, immutable2); } @Test public void newWithAllKeyValues() { ImmutableMapIterable<Integer, String> immutable = this.classUnderTest(); ImmutableMapIterable<Integer, String> immutable2 = immutable.newWithAllKeyValues(ArrayAdapter.newArrayWith( Tuples.pair(Integer.MAX_VALUE, Integer.toString(Integer.MAX_VALUE)), Tuples.pair(Integer.MIN_VALUE, Integer.toString(Integer.MIN_VALUE)))); Verify.assertSize(immutable.size() + 2, immutable2); } @Test public void newWithoutKey() { ImmutableMapIterable<Integer, String> immutable = this.classUnderTest(); ImmutableMapIterable<Integer, String> immutable3 = immutable.newWithoutKey(Integer.MAX_VALUE); Verify.assertSize(immutable.size(), immutable3); } @Test public void newWithoutKeys() { ImmutableMapIterable<Integer, String> immutable = this.classUnderTest(); ImmutableMapIterable<Integer, String> immutable2 = immutable.newWithoutAllKeys(immutable.keysView()); ImmutableMapIterable<Integer, String> immutable3 = immutable.newWithoutAllKeys(Lists.immutable.<Integer>of()); Assert.assertEquals(immutable, immutable3); Assert.assertEquals(Maps.immutable.of(), immutable2); } }