• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2008 The Guava Authors
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.google.common.collect;
18 
19 import com.google.common.annotations.GwtCompatible;
20 import com.google.common.base.Function;
21 import com.google.common.base.Functions;
22 import com.google.common.collect.testing.MapInterfaceTest;
23 
24 import java.util.Collection;
25 import java.util.Iterator;
26 import java.util.Map;
27 import java.util.Set;
28 
29 import javax.annotation.Nullable;
30 
31 /**
32  * Tests for {@link Maps#transformValues}.
33  *
34  * @author Isaac Shum
35  */
36 @GwtCompatible
37 public class MapsTransformValuesTest extends MapInterfaceTest<String, String> {
38 
39   /**
40    * Constructor that assigns {@code supportsIteratorRemove} the same value as
41    * {@code supportsRemove}.
42    */
MapsTransformValuesTest( boolean allowsNullKeys, boolean allowsNullValues, boolean supportsPut, boolean supportsRemove, boolean supportsClear)43   protected MapsTransformValuesTest(
44       boolean allowsNullKeys,
45       boolean allowsNullValues,
46       boolean supportsPut,
47       boolean supportsRemove,
48       boolean supportsClear) {
49     super(allowsNullKeys, allowsNullValues, supportsPut, supportsRemove,
50         supportsClear, supportsRemove);
51   }
52 
MapsTransformValuesTest()53   public MapsTransformValuesTest() {
54     super(false, true, false, true, true);
55   }
56 
makeEmptyMap()57   protected Map<String, String> makeEmptyMap() {
58     return Maps.transformValues(Maps.<String, String>newHashMap(),
59         Functions.<String>identity());
60   }
61 
62   @Override
makePopulatedMap()63   protected Map<String, String> makePopulatedMap() {
64     Map<String, Integer> underlying = Maps.newHashMap();
65     underlying.put("a", 1);
66     underlying.put("b", 2);
67     underlying.put("c", 3);
68     return Maps.transformValues(underlying, Functions.toStringFunction());
69   }
70 
getKeyNotInPopulatedMap()71   @Override protected String getKeyNotInPopulatedMap()
72       throws UnsupportedOperationException {
73     return "z";
74   }
75 
getValueNotInPopulatedMap()76   @Override protected String getValueNotInPopulatedMap()
77       throws UnsupportedOperationException {
78     return "26";
79   }
80 
81   /** Helper assertion comparing two maps */
assertMapsEqual(Map<?, ?> expected, Map<?, ?> map)82   private void assertMapsEqual(Map<?, ?> expected, Map<?, ?> map) {
83     assertEquals(expected, map);
84     assertEquals(expected.hashCode(), map.hashCode());
85     assertEquals(expected.entrySet(), map.entrySet());
86 
87     // Assert that expectedValues > mapValues and that
88     // mapValues > expectedValues; i.e. that expectedValues == mapValues.
89     Collection<?> expectedValues = expected.values();
90     Collection<?> mapValues = map.values();
91     assertEquals(expectedValues.size(), mapValues.size());
92     assertTrue(expectedValues.containsAll(mapValues));
93     assertTrue(mapValues.containsAll(expectedValues));
94   }
95 
testTransformEmptyMapEquality()96   public void testTransformEmptyMapEquality() {
97     Map<String, String> map = Maps.transformValues(
98         ImmutableMap.<String, Integer>of(), Functions.toStringFunction());
99     assertMapsEqual(Maps.newHashMap(), map);
100   }
101 
testTransformSingletonMapEquality()102   public void testTransformSingletonMapEquality() {
103     Map<String, String> map = Maps.transformValues(
104         ImmutableMap.of("a", 1), Functions.toStringFunction());
105     Map<String, String> expected = ImmutableMap.of("a", "1");
106     assertMapsEqual(expected, map);
107     assertEquals(expected.get("a"), map.get("a"));
108   }
109 
testTransformIdentityFunctionEquality()110   public void testTransformIdentityFunctionEquality() {
111     Map<String, Integer> underlying = ImmutableMap.of("a", 1);
112     Map<String, Integer> map = Maps.transformValues(
113         underlying, Functions.<Integer>identity());
114     assertMapsEqual(underlying, map);
115   }
116 
testTransformPutEntryIsUnsupported()117   public void testTransformPutEntryIsUnsupported() {
118     Map<String, String> map = Maps.transformValues(
119         ImmutableMap.of("a", 1), Functions.toStringFunction());
120     try {
121       map.put("b", "2");
122       fail();
123     } catch (UnsupportedOperationException expected) {
124     }
125 
126     try {
127       map.putAll(ImmutableMap.of("b", "2"));
128       fail();
129     } catch (UnsupportedOperationException expected) {
130     }
131 
132     try {
133       map.entrySet().iterator().next().setValue("one");
134       fail();
135     } catch (UnsupportedOperationException expected) {
136     }
137   }
138 
testTransformRemoveEntry()139   public void testTransformRemoveEntry() {
140     Map<String, Integer> underlying = Maps.newHashMap();
141     underlying.put("a", 1);
142     Map<String, String> map
143         = Maps.transformValues(underlying, Functions.toStringFunction());
144     assertEquals("1", map.remove("a"));
145     assertNull(map.remove("b"));
146   }
147 
testTransformEqualityOfMapsWithNullValues()148   public void testTransformEqualityOfMapsWithNullValues() {
149     Map<String, String> underlying = Maps.newHashMap();
150     underlying.put("a", null);
151     underlying.put("b", "");
152 
153     Map<String, Boolean> map = Maps.transformValues(underlying,
154         new Function<String, Boolean>() {
155           @Override
156           public Boolean apply(@Nullable String from) {
157             return from == null;
158           }
159         }
160     );
161     Map<String, Boolean> expected = ImmutableMap.of("a", true, "b", false);
162     assertMapsEqual(expected, map);
163     assertEquals(expected.get("a"), map.get("a"));
164     assertEquals(expected.containsKey("a"), map.containsKey("a"));
165     assertEquals(expected.get("b"), map.get("b"));
166     assertEquals(expected.containsKey("b"), map.containsKey("b"));
167     assertEquals(expected.get("c"), map.get("c"));
168     assertEquals(expected.containsKey("c"), map.containsKey("c"));
169   }
170 
testTransformReflectsUnderlyingMap()171   public void testTransformReflectsUnderlyingMap() {
172     Map<String, Integer> underlying = Maps.newHashMap();
173     underlying.put("a", 1);
174     underlying.put("b", 2);
175     underlying.put("c", 3);
176     Map<String, String> map
177         = Maps.transformValues(underlying, Functions.toStringFunction());
178     assertEquals(underlying.size(), map.size());
179 
180     underlying.put("d", 4);
181     assertEquals(underlying.size(), map.size());
182     assertEquals("4", map.get("d"));
183 
184     underlying.remove("c");
185     assertEquals(underlying.size(), map.size());
186     assertFalse(map.containsKey("c"));
187 
188     underlying.clear();
189     assertEquals(underlying.size(), map.size());
190   }
191 
testTransformChangesAreReflectedInUnderlyingMap()192   public void testTransformChangesAreReflectedInUnderlyingMap() {
193     Map<String, Integer> underlying = Maps.newLinkedHashMap();
194     underlying.put("a", 1);
195     underlying.put("b", 2);
196     underlying.put("c", 3);
197     underlying.put("d", 4);
198     underlying.put("e", 5);
199     underlying.put("f", 6);
200     underlying.put("g", 7);
201     Map<String, String> map
202         = Maps.transformValues(underlying, Functions.toStringFunction());
203 
204     map.remove("a");
205     assertFalse(underlying.containsKey("a"));
206 
207     Set<String> keys = map.keySet();
208     keys.remove("b");
209     assertFalse(underlying.containsKey("b"));
210 
211     Iterator<String> keyIterator = keys.iterator();
212     keyIterator.next();
213     keyIterator.remove();
214     assertFalse(underlying.containsKey("c"));
215 
216     Collection<String> values = map.values();
217     values.remove("4");
218     assertFalse(underlying.containsKey("d"));
219 
220     Iterator<String> valueIterator = values.iterator();
221     valueIterator.next();
222     valueIterator.remove();
223     assertFalse(underlying.containsKey("e"));
224 
225     Set<Map.Entry<String, String>> entries = map.entrySet();
226     Map.Entry<String, String> firstEntry = entries.iterator().next();
227     entries.remove(firstEntry);
228     assertFalse(underlying.containsKey("f"));
229 
230     Iterator<Map.Entry<String, String>> entryIterator = entries.iterator();
231     entryIterator.next();
232     entryIterator.remove();
233     assertFalse(underlying.containsKey("g"));
234 
235     assertTrue(underlying.isEmpty());
236     assertTrue(map.isEmpty());
237     assertTrue(keys.isEmpty());
238     assertTrue(values.isEmpty());
239     assertTrue(entries.isEmpty());
240   }
241 
testTransformEquals()242   public void testTransformEquals() {
243     Map<String, Integer> underlying = ImmutableMap.of("a", 0, "b", 1, "c", 2);
244     Map<String, Integer> expected
245         = Maps.transformValues(underlying, Functions.<Integer>identity());
246 
247     assertMapsEqual(expected, expected);
248 
249     Map<String, Integer> equalToUnderlying = Maps.newTreeMap();
250     equalToUnderlying.putAll(underlying);
251     Map<String, Integer> map = Maps.transformValues(
252         equalToUnderlying, Functions.<Integer>identity());
253     assertMapsEqual(expected, map);
254 
255     map = Maps.transformValues(ImmutableMap.of("a", 1, "b", 2, "c", 3),
256         new Function<Integer, Integer>() {
257           @Override
258           public Integer apply(Integer from) {
259             return from - 1;
260           }
261         }
262     );
263     assertMapsEqual(expected, map);
264   }
265 
testTransformEntrySetContains()266   public void testTransformEntrySetContains() {
267     Map<String, Boolean> underlying = Maps.newHashMap();
268     underlying.put("a", null);
269     underlying.put("b", true);
270     underlying.put(null, true);
271 
272     Map<String, Boolean> map = Maps.transformValues(
273         underlying, new Function<Boolean, Boolean>() {
274           @Override
275           public Boolean apply(@Nullable Boolean from) {
276             return (from == null) ? true : null;
277           }
278         }
279     );
280 
281     Set<Map.Entry<String, Boolean>> entries = map.entrySet();
282     assertTrue(entries.contains(Maps.immutableEntry("a", true)));
283     assertTrue(entries.contains(Maps.immutableEntry("b", (Boolean) null)));
284     assertTrue(entries.contains(
285         Maps.immutableEntry((String) null, (Boolean) null)));
286 
287     assertFalse(entries.contains(Maps.immutableEntry("c", (Boolean) null)));
288     assertFalse(entries.contains(Maps.immutableEntry((String) null, true)));
289   }
290 
testKeySetRemoveAllNullFromEmpty()291   @Override public void testKeySetRemoveAllNullFromEmpty() {
292     try {
293       super.testKeySetRemoveAllNullFromEmpty();
294     } catch (RuntimeException tolerated) {
295       // GWT's HashMap.keySet().removeAll(null) doesn't throws NPE.
296     }
297   }
298 
testEntrySetRemoveAllNullFromEmpty()299   @Override public void testEntrySetRemoveAllNullFromEmpty() {
300     try {
301       super.testEntrySetRemoveAllNullFromEmpty();
302     } catch (RuntimeException tolerated) {
303       // GWT's HashMap.entrySet().removeAll(null) doesn't throws NPE.
304     }
305   }
306 }
307