/* * 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.sorted.immutable; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Set; import java.util.SortedMap; import com.gs.collections.api.block.function.Function2; import com.gs.collections.api.list.MutableList; import com.gs.collections.api.map.ImmutableMap; import com.gs.collections.api.map.MutableMap; import com.gs.collections.api.map.sorted.ImmutableSortedMap; import com.gs.collections.api.map.sorted.MutableSortedMap; import com.gs.collections.api.tuple.Pair; import com.gs.collections.impl.block.factory.Comparators; 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.factory.SortedMaps; import com.gs.collections.impl.list.Interval; import com.gs.collections.impl.list.fixed.ArrayAdapter; import com.gs.collections.impl.list.mutable.FastList; import com.gs.collections.impl.map.MapIterableTestCase; import com.gs.collections.impl.map.mutable.UnifiedMap; import com.gs.collections.impl.map.sorted.mutable.TreeSortedMap; import com.gs.collections.impl.test.Verify; import com.gs.collections.impl.tuple.Tuples; import org.junit.Assert; import org.junit.Test; /** * JUnit test for {@link ImmutableSortedMap}. */ public abstract class ImmutableSortedMapTestCase extends MapIterableTestCase { private static final Comparator<? super Integer> REV_INT_COMPARATOR = Comparators.reverseNaturalOrder(); /** * @return A map containing 1 => "1", 2 => "2", etc. */ protected abstract ImmutableSortedMap<Integer, String> classUnderTest(); protected abstract ImmutableSortedMap<Integer, String> classUnderTest(Comparator<? super Integer> comparator); /** * @return Size (and max key) of {@link #classUnderTest()}. */ protected abstract int size(); @Test public void castToSortedMap() { ImmutableSortedMap<Integer, String> immutable = this.classUnderTest(); SortedMap<Integer, String> map = immutable.castToSortedMap(); Assert.assertSame(immutable, map); Assert.assertEquals(immutable, new HashMap<>(map)); ImmutableSortedMap<Integer, String> revImmutable = this.classUnderTest(REV_INT_COMPARATOR); SortedMap<Integer, String> revMap = revImmutable.castToSortedMap(); Assert.assertSame(revImmutable, revMap); Assert.assertEquals(revImmutable, new HashMap<>(revMap)); } @Override @Test public void toSortedMap() { super.toSortedMap(); ImmutableSortedMap<Integer, String> immutable = this.classUnderTest(); MutableSortedMap<Integer, String> map = immutable.toSortedMap(); Assert.assertNotSame(immutable, map); Assert.assertEquals(immutable, map); ImmutableSortedMap<Integer, String> revImmutable = this.classUnderTest(REV_INT_COMPARATOR); MutableSortedMap<Integer, String> revMap = revImmutable.toSortedMap(); Assert.assertNotSame(revImmutable, revMap); Assert.assertEquals(revImmutable, revMap); } @Override @Test public void equalsAndHashCode() { super.equalsAndHashCode(); MutableMap<Integer, String> expected = this.equalUnifiedMap(); MutableSortedMap<Integer, String> sortedMap = this.equalSortedMap(); Verify.assertEqualsAndHashCode(expected, this.classUnderTest()); Verify.assertEqualsAndHashCode(sortedMap, this.classUnderTest()); Verify.assertEqualsAndHashCode(expected, this.classUnderTest(REV_INT_COMPARATOR)); Verify.assertEqualsAndHashCode(sortedMap, this.classUnderTest(REV_INT_COMPARATOR)); } @Override @Test public void forEachKeyValue() { super.forEachKeyValue(); MutableList<Integer> actualKeys = Lists.mutable.of(); MutableList<String> actualValues = Lists.mutable.of(); this.classUnderTest().forEachKeyValue((key, value) -> { actualKeys.add(key); actualValues.add(value); }); MutableList<Integer> expectedKeys = this.expectedKeys(); Verify.assertListsEqual(expectedKeys, actualKeys); MutableList<String> expectedValues = expectedKeys.collect(String::valueOf); Verify.assertListsEqual(expectedValues, actualValues); MutableList<Integer> revActualKeys = Lists.mutable.of(); MutableList<String> revActualValues = Lists.mutable.of(); this.classUnderTest(REV_INT_COMPARATOR).forEachKeyValue((key, value) -> { revActualKeys.add(key); revActualValues.add(value); }); MutableList<Integer> reverseKeys = expectedKeys.reverseThis(); Verify.assertListsEqual(reverseKeys, revActualKeys); MutableList<String> reverseValues = expectedValues.reverseThis(); Verify.assertListsEqual(reverseValues, revActualValues); } @Override @Test public void forEachValue() { super.forEachValue(); MutableList<String> actualValues = Lists.mutable.of(); this.classUnderTest().forEachValue(CollectionAddProcedure.on(actualValues)); Verify.assertListsEqual(this.expectedValues(), actualValues); MutableList<String> revActualValues = Lists.mutable.of(); this.classUnderTest(REV_INT_COMPARATOR).forEachValue(CollectionAddProcedure.on(revActualValues)); Verify.assertListsEqual(this.expectedValues().reverseThis(), revActualValues); } @Override @Test public void tap() { super.tap(); MutableList<String> tapResult = Lists.mutable.of(); ImmutableSortedMap<Integer, String> map = this.classUnderTest(); Assert.assertSame(map, map.tap(tapResult::add)); Assert.assertEquals(map.toList(), tapResult); MutableList<String> revTapResult = Lists.mutable.of(); ImmutableSortedMap<Integer, String> revMap = this.classUnderTest(REV_INT_COMPARATOR); Assert.assertSame(revMap, revMap.tap(revTapResult::add)); Assert.assertEquals(revMap.toList(), revTapResult); } @Override @Test public void forEach() { super.forEach(); MutableList<String> actualValues = Lists.mutable.of(); this.classUnderTest().forEach(CollectionAddProcedure.on(actualValues)); Verify.assertListsEqual(this.expectedValues(), actualValues); MutableList<String> revActualValues = Lists.mutable.of(); this.classUnderTest(REV_INT_COMPARATOR).forEach(CollectionAddProcedure.on(revActualValues)); Verify.assertListsEqual(this.expectedValues().reverseThis(), revActualValues); } @Override @Test public void iterator() { super.iterator(); MutableList<String> actualValues = Lists.mutable.of(); for (String eachValue : this.classUnderTest()) { actualValues.add(eachValue); } Verify.assertListsEqual(this.expectedValues(), actualValues); MutableList<String> revActualValues = Lists.mutable.of(); for (String eachValue : this.classUnderTest(REV_INT_COMPARATOR)) { revActualValues.add(eachValue); } Verify.assertListsEqual(this.expectedValues().reverseThis(), revActualValues); } @Test public void iteratorThrows() { Verify.assertThrows(UnsupportedOperationException.class, () -> { Iterator<String> iterator = this.classUnderTest().iterator(); iterator.remove(); }); } @Override @Test public void forEachKey() { super.forEachKey(); MutableList<Integer> actualKeys = Lists.mutable.of(); this.classUnderTest().forEachKey(CollectionAddProcedure.on(actualKeys)); Verify.assertListsEqual(this.expectedKeys(), actualKeys); MutableList<Integer> revActualKeys = Lists.mutable.of(); this.classUnderTest(REV_INT_COMPARATOR).forEachKey(CollectionAddProcedure.on(revActualKeys)); Verify.assertListsEqual(this.expectedKeys().reverseThis(), revActualKeys); } @Test public void get() { Integer absentKey = this.size() + 1; String absentValue = String.valueOf(absentKey); // Absent key behavior ImmutableSortedMap<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); } @Override @Test public void getIfAbsent() { super.getIfAbsent(); Integer absentKey = this.size() + 1; String absentValue = String.valueOf(absentKey); // Absent key behavior ImmutableSortedMap<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 getIfAbsentValue() { Integer absentKey = this.size() + 1; String absentValue = String.valueOf(absentKey); // Absent key behavior ImmutableSortedMap<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); } @Override @Test public void getIfAbsentWith() { super.getIfAbsentWith(); Integer absentKey = this.size() + 1; String absentValue = String.valueOf(absentKey); // Absent key behavior ImmutableSortedMap<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); } @Override @Test public void forEachWith() { super.forEachWith(); Object actualParameter = new Object(); MutableList<String> actualValues = Lists.mutable.of(); MutableList<Object> actualParameters = Lists.mutable.of(); this.classUnderTest().forEachWith((eachValue, parameter) -> { actualValues.add(eachValue); actualParameters.add(parameter); }, actualParameter); Verify.assertListsEqual(this.expectedKeys().collect(String::valueOf), actualValues); Verify.assertListsEqual(Collections.nCopies(this.size(), actualParameter), actualParameters); MutableList<String> revActualValues = Lists.mutable.of(); MutableList<Object> revActualParameters = Lists.mutable.of(); this.classUnderTest(REV_INT_COMPARATOR).forEachWith((eachValue, parameter) -> { revActualValues.add(eachValue); revActualParameters.add(parameter); }, actualParameter); Verify.assertListsEqual(this.expectedKeys().collect(String::valueOf).reverseThis(), revActualValues); Verify.assertListsEqual(Collections.nCopies(this.size(), actualParameter), revActualParameters); } @Override @Test public void forEachWithIndex() { super.forEachWithIndex(); MutableList<String> actualValues = Lists.mutable.of(); MutableList<Integer> actualIndices = Lists.mutable.of(); this.classUnderTest().forEachWithIndex((eachValue, index) -> { actualValues.add(eachValue); actualIndices.add(index); }); Verify.assertListsEqual(this.expectedKeys().collect(String::valueOf), actualValues); Verify.assertListsEqual(this.expectedIndices(), actualIndices); MutableList<String> revActualValues = Lists.mutable.of(); MutableList<Integer> revActualIndices = Lists.mutable.of(); this.classUnderTest(REV_INT_COMPARATOR).forEachWithIndex((eachValue, index) -> { revActualValues.add(eachValue); revActualIndices.add(index); }); Verify.assertListsEqual(this.expectedKeys().collect(String::valueOf).reverseThis(), revActualValues); Verify.assertListsEqual(this.expectedIndices(), revActualIndices); } @Override @Test public void valuesView() { super.valuesView(); MutableList<String> actualValues = Lists.mutable.of(); for (String eachValue : this.classUnderTest().valuesView()) { actualValues.add(eachValue); } MutableList<String> expectedValues = this.expectedValues(); Verify.assertListsEqual(expectedValues, actualValues); MutableList<String> revActualValues = Lists.mutable.of(); for (String eachValue : this.classUnderTest(REV_INT_COMPARATOR).valuesView()) { revActualValues.add(eachValue); } Verify.assertListsEqual(this.expectedValues().reverseThis(), revActualValues); } @Override @Test public void keysView() { super.keysView(); MutableList<Integer> actualKeys = Lists.mutable.of(); for (Integer eachKey : this.classUnderTest().keysView()) { actualKeys.add(eachKey); } Verify.assertListsEqual(this.expectedKeys(), actualKeys); MutableList<Integer> revActualKeys = Lists.mutable.of(); for (Integer eachKey : this.classUnderTest(REV_INT_COMPARATOR).keysView()) { revActualKeys.add(eachKey); } Verify.assertListsEqual(this.expectedKeys().reverseThis(), revActualKeys); } @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 entrySet() { ImmutableSortedMap<Integer, String> immutableSortedMap = this.classUnderTest(); Map<Integer, String> map = new HashMap<>(immutableSortedMap.castToSortedMap()); Assert.assertEquals(map.entrySet(), immutableSortedMap.castToSortedMap().entrySet()); Set<Map.Entry<Integer, String>> entries = immutableSortedMap.castToSortedMap().entrySet(); MutableList<Map.Entry<Integer, String>> entriesList = FastList.newList(entries); MutableList<Map.Entry<Integer, String>> sortedEntryList = entriesList.toSortedListBy(Functions.getKeyFunction()); Assert.assertEquals(sortedEntryList, entriesList); } @Override @Test public void selectMap() { super.selectMap(); ImmutableSortedMap<Integer, String> map = this.classUnderTest(); ImmutableSortedMap<Integer, String> select = map.select((argument1, argument2) -> argument1 < this.size()); Verify.assertListsEqual(Interval.oneTo(this.size() - 1), select.keysView().toList()); Verify.assertListsEqual(Interval.oneTo(this.size() - 1).collect(String::valueOf).toList(), select.valuesView().toList()); ImmutableSortedMap<Integer, String> revMap = this.classUnderTest(REV_INT_COMPARATOR); ImmutableSortedMap<Integer, String> revSelect = revMap.select((argument1, argument2) -> argument1 < this.size()); Verify.assertListsEqual(Interval.oneTo(this.size() - 1).reverseThis(), revSelect.keysView().toList()); Verify.assertListsEqual(Interval.oneTo(this.size() - 1).collect(String::valueOf).toList().reverseThis(), revSelect.valuesView().toList()); } @Override @Test public void rejectMap() { super.rejectMap(); ImmutableSortedMap<Integer, String> map = this.classUnderTest(); ImmutableSortedMap<Integer, String> reject = map.reject((argument1, argument2) -> argument1 == 1); Verify.assertListsEqual(Interval.fromTo(2, this.size()), reject.keysView().toList()); Verify.assertListsEqual(Interval.fromTo(2, this.size()).collect(String::valueOf).toList(), reject.valuesView().toList()); ImmutableSortedMap<Integer, String> revMap = this.classUnderTest(REV_INT_COMPARATOR); ImmutableSortedMap<Integer, String> revReject = revMap.reject((argument1, argument2) -> argument1 == 1); Verify.assertListsEqual(Interval.fromTo(2, this.size()).reverseThis(), revReject.keysView().toList()); Verify.assertListsEqual(Interval.fromTo(2, this.size()).collect(String::valueOf).toList().reverseThis(), revReject.valuesView().toList()); } @Override @Test public void collectMap() { super.collectMap(); ImmutableSortedMap<Integer, String> map = this.classUnderTest(); Function2<Integer, String, Pair<String, Integer>> function = (Integer argument1, String argument2) -> Tuples.pair(argument2, argument1); ImmutableMap<String, Integer> collect = map.collect(function); Verify.assertSetsEqual(Interval.oneTo(this.size()).collect(String::valueOf).toSet(), collect.keysView().toSet()); Verify.assertSetsEqual(Interval.oneTo(this.size()).toSet(), collect.valuesView().toSet()); ImmutableSortedMap<Integer, String> revMap = this.classUnderTest(REV_INT_COMPARATOR); ImmutableMap<String, Integer> revCollect = revMap.collect(function); Verify.assertSetsEqual(Interval.oneTo(this.size()).collect(String::valueOf).toSet(), revCollect.keysView().toSet()); Verify.assertSetsEqual(Interval.oneTo(this.size()).toSet(), revCollect.valuesView().toSet()); } @Override @Test public void collectValues() { super.collectValues(); ImmutableSortedMap<Integer, String> map = this.classUnderTest(); ImmutableSortedMap<Integer, Integer> result = map.collectValues((argument1, argument2) -> argument1); Verify.assertListsEqual(result.keysView().toList(), result.valuesView().toList()); ImmutableSortedMap<Integer, String> revMap = this.classUnderTest(REV_INT_COMPARATOR); ImmutableSortedMap<Integer, Integer> revResult = revMap.collectValues((argument1, argument2) -> argument1); Verify.assertListsEqual(revResult.keysView().toList(), revResult.valuesView().toList()); } @Test public void newWithKeyValue() { ImmutableSortedMap<Integer, String> immutable = this.classUnderTest(); ImmutableSortedMap<Integer, String> immutable2 = immutable.newWithKeyValue(Integer.MAX_VALUE, Integer.toString(Integer.MAX_VALUE)); Verify.assertSize(immutable.size() + 1, immutable2.castToSortedMap()); } @Test public void newWithAllKeyValuePairs() { ImmutableSortedMap<Integer, String> immutable = this.classUnderTest(); ImmutableSortedMap<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.castToSortedMap()); } @Test public void newWithAllKeyValues() { ImmutableSortedMap<Integer, String> immutable = this.classUnderTest(); ImmutableSortedMap<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.castToSortedMap()); } @Test public void newWithoutKey() { ImmutableSortedMap<Integer, String> immutable = this.classUnderTest(); ImmutableSortedMap<Integer, String> immutable3 = immutable.newWithoutKey(Integer.MAX_VALUE); Verify.assertSize(immutable.size(), immutable3.castToSortedMap()); } @Test public void newWithoutAllKeys() { ImmutableSortedMap<Integer, String> immutable = this.classUnderTest(); ImmutableSortedMap<Integer, String> immutable2 = immutable.newWithoutAllKeys(immutable.keysView()); ImmutableSortedMap<Integer, String> immutable3 = immutable.newWithoutAllKeys(Lists.immutable.<Integer>of()); Assert.assertEquals(immutable, immutable3); Assert.assertEquals(Maps.immutable.of(), immutable2); } @Test public void toImmutable() { ImmutableSortedMap<Integer, String> immutableSortedMap = this.classUnderTest(); Assert.assertSame(immutableSortedMap, immutableSortedMap.toImmutable()); } @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(); @Test public void take() { ImmutableSortedMap<Integer, String> strings1 = this.classUnderTest(); Assert.assertEquals(SortedMaps.immutable.of(strings1.comparator()), strings1.take(0)); Assert.assertSame(strings1.comparator(), strings1.take(0).comparator()); Assert.assertEquals(SortedMaps.immutable.of(strings1.comparator(), 1, "1", 2, "2", 3, "3"), strings1.take(3)); Assert.assertSame(strings1.comparator(), strings1.take(3).comparator()); Assert.assertEquals(SortedMaps.immutable.of(strings1.comparator(), 1, "1", 2, "2", 3, "3"), strings1.take(strings1.size() - 1)); ImmutableSortedMap<Integer, String> strings2 = this.classUnderTest(Comparators.reverseNaturalOrder()); Assert.assertSame(strings2, strings2.take(strings2.size())); Assert.assertSame(strings2, strings2.take(10)); Assert.assertSame(strings2, strings2.take(Integer.MAX_VALUE)); } @Test(expected = IllegalArgumentException.class) public void take_throws() { this.classUnderTest().take(-1); } @Test public void drop() { ImmutableSortedMap<Integer, String> strings1 = this.classUnderTest(); Assert.assertSame(strings1, strings1.drop(0)); Assert.assertSame(strings1.comparator(), strings1.drop(0).comparator()); Assert.assertEquals(SortedMaps.immutable.of(strings1.comparator(), 4, "4"), strings1.drop(3)); Assert.assertSame(strings1.comparator(), strings1.drop(3).comparator()); Assert.assertEquals(SortedMaps.immutable.of(strings1.comparator(), 4, "4"), strings1.drop(strings1.size() - 1)); ImmutableSortedMap<Integer, String> expectedMap = SortedMaps.immutable.of(Comparators.reverseNaturalOrder()); ImmutableSortedMap<Integer, String> strings2 = this.classUnderTest(Comparators.reverseNaturalOrder()); Assert.assertEquals(expectedMap, strings2.drop(strings2.size())); Assert.assertEquals(expectedMap, strings2.drop(10)); Assert.assertEquals(expectedMap, strings2.drop(Integer.MAX_VALUE)); } @Test(expected = IllegalArgumentException.class) public void drop_throws() { this.classUnderTest().drop(-1); } 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; } protected MutableSortedMap<Integer, String> equalSortedMap() { MutableSortedMap<Integer, String> expected = TreeSortedMap.newMap(); for (int i = 1; i <= this.size(); i++) { expected.put(i, String.valueOf(i)); } return expected; } private MutableList<String> expectedValues() { return this.expectedKeys().collect(String::valueOf); } private MutableList<Integer> expectedKeys() { if (this.size() == 0) { return Lists.mutable.of(); } return Interval.oneTo(this.size()).toList(); } private MutableList<Integer> expectedIndices() { if (this.size() == 0) { return Lists.mutable.of(); } return Interval.zeroTo(this.size() - 1).toList(); } }