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 import java.util.Collection; 24 import java.util.Iterator; 25 import java.util.Map; 26 import java.util.Map.Entry; 27 import java.util.Set; 28 import org.checkerframework.checker.nullness.qual.Nullable; 29 30 /** 31 * Superclass for tests for {@link Maps#transformValues} overloads. 32 * 33 * @author Isaac Shum 34 */ 35 @GwtCompatible 36 @ElementTypesAreNonnullByDefault 37 abstract class AbstractMapsTransformValuesTest extends MapInterfaceTest<String, String> { AbstractMapsTransformValuesTest()38 public AbstractMapsTransformValuesTest() { 39 super(false, true, false, true, true); 40 } 41 42 @Override getKeyNotInPopulatedMap()43 protected String getKeyNotInPopulatedMap() throws UnsupportedOperationException { 44 return "z"; 45 } 46 47 @Override getValueNotInPopulatedMap()48 protected String getValueNotInPopulatedMap() throws UnsupportedOperationException { 49 return "26"; 50 } 51 52 /** Helper assertion comparing two maps */ assertMapsEqual(Map<?, ?> expected, Map<?, ?> map)53 private void assertMapsEqual(Map<?, ?> expected, Map<?, ?> map) { 54 assertEquals(expected, map); 55 assertEquals(expected.hashCode(), map.hashCode()); 56 assertEquals(expected.entrySet(), map.entrySet()); 57 58 // Assert that expectedValues > mapValues and that 59 // mapValues > expectedValues; i.e. that expectedValues == mapValues. 60 Collection<?> expectedValues = expected.values(); 61 Collection<?> mapValues = map.values(); 62 assertEquals(expectedValues.size(), mapValues.size()); 63 assertTrue(expectedValues.containsAll(mapValues)); 64 assertTrue(mapValues.containsAll(expectedValues)); 65 } 66 testTransformEmptyMapEquality()67 public void testTransformEmptyMapEquality() { 68 Map<String, String> map = 69 Maps.transformValues(ImmutableMap.<String, Integer>of(), Functions.toStringFunction()); 70 assertMapsEqual(Maps.newHashMap(), map); 71 } 72 testTransformSingletonMapEquality()73 public void testTransformSingletonMapEquality() { 74 Map<String, String> map = 75 Maps.transformValues(ImmutableMap.of("a", 1), Functions.toStringFunction()); 76 Map<String, String> expected = ImmutableMap.of("a", "1"); 77 assertMapsEqual(expected, map); 78 assertEquals(expected.get("a"), map.get("a")); 79 } 80 testTransformIdentityFunctionEquality()81 public void testTransformIdentityFunctionEquality() { 82 Map<String, Integer> underlying = ImmutableMap.of("a", 1); 83 Map<String, Integer> map = Maps.transformValues(underlying, Functions.<Integer>identity()); 84 assertMapsEqual(underlying, map); 85 } 86 testTransformPutEntryIsUnsupported()87 public void testTransformPutEntryIsUnsupported() { 88 Map<String, String> map = 89 Maps.transformValues(ImmutableMap.of("a", 1), Functions.toStringFunction()); 90 try { 91 map.put("b", "2"); 92 fail(); 93 } catch (UnsupportedOperationException expected) { 94 } 95 96 try { 97 map.putAll(ImmutableMap.of("b", "2")); 98 fail(); 99 } catch (UnsupportedOperationException expected) { 100 } 101 102 try { 103 map.entrySet().iterator().next().setValue("one"); 104 fail(); 105 } catch (UnsupportedOperationException expected) { 106 } 107 } 108 testTransformRemoveEntry()109 public void testTransformRemoveEntry() { 110 Map<String, Integer> underlying = Maps.newHashMap(); 111 underlying.put("a", 1); 112 Map<String, String> map = Maps.transformValues(underlying, Functions.toStringFunction()); 113 assertEquals("1", map.remove("a")); 114 assertNull(map.remove("b")); 115 } 116 testTransformEqualityOfMapsWithNullValues()117 public void testTransformEqualityOfMapsWithNullValues() { 118 Map<String, @Nullable String> underlying = Maps.newHashMap(); 119 underlying.put("a", null); 120 underlying.put("b", ""); 121 122 Map<String, Boolean> map = 123 Maps.transformValues( 124 underlying, 125 new Function<@Nullable String, Boolean>() { 126 @Override 127 public Boolean apply(@Nullable String from) { 128 return from == null; 129 } 130 }); 131 Map<String, Boolean> expected = ImmutableMap.of("a", true, "b", false); 132 assertMapsEqual(expected, map); 133 assertEquals(expected.get("a"), map.get("a")); 134 assertEquals(expected.containsKey("a"), map.containsKey("a")); 135 assertEquals(expected.get("b"), map.get("b")); 136 assertEquals(expected.containsKey("b"), map.containsKey("b")); 137 assertEquals(expected.get("c"), map.get("c")); 138 assertEquals(expected.containsKey("c"), map.containsKey("c")); 139 } 140 testTransformReflectsUnderlyingMap()141 public void testTransformReflectsUnderlyingMap() { 142 Map<String, Integer> underlying = Maps.newHashMap(); 143 underlying.put("a", 1); 144 underlying.put("b", 2); 145 underlying.put("c", 3); 146 Map<String, String> map = Maps.transformValues(underlying, Functions.toStringFunction()); 147 assertEquals(underlying.size(), map.size()); 148 149 underlying.put("d", 4); 150 assertEquals(underlying.size(), map.size()); 151 assertEquals("4", map.get("d")); 152 153 underlying.remove("c"); 154 assertEquals(underlying.size(), map.size()); 155 assertFalse(map.containsKey("c")); 156 157 underlying.clear(); 158 assertEquals(underlying.size(), map.size()); 159 } 160 testTransformChangesAreReflectedInUnderlyingMap()161 public void testTransformChangesAreReflectedInUnderlyingMap() { 162 Map<String, Integer> underlying = Maps.newLinkedHashMap(); 163 underlying.put("a", 1); 164 underlying.put("b", 2); 165 underlying.put("c", 3); 166 underlying.put("d", 4); 167 underlying.put("e", 5); 168 underlying.put("f", 6); 169 underlying.put("g", 7); 170 Map<String, String> map = Maps.transformValues(underlying, Functions.toStringFunction()); 171 172 map.remove("a"); 173 assertFalse(underlying.containsKey("a")); 174 175 Set<String> keys = map.keySet(); 176 keys.remove("b"); 177 assertFalse(underlying.containsKey("b")); 178 179 Iterator<String> keyIterator = keys.iterator(); 180 keyIterator.next(); 181 keyIterator.remove(); 182 assertFalse(underlying.containsKey("c")); 183 184 Collection<String> values = map.values(); 185 values.remove("4"); 186 assertFalse(underlying.containsKey("d")); 187 188 Iterator<String> valueIterator = values.iterator(); 189 valueIterator.next(); 190 valueIterator.remove(); 191 assertFalse(underlying.containsKey("e")); 192 193 Set<Entry<String, String>> entries = map.entrySet(); 194 Entry<String, String> firstEntry = entries.iterator().next(); 195 entries.remove(firstEntry); 196 assertFalse(underlying.containsKey("f")); 197 198 Iterator<Entry<String, String>> entryIterator = entries.iterator(); 199 entryIterator.next(); 200 entryIterator.remove(); 201 assertFalse(underlying.containsKey("g")); 202 203 assertTrue(underlying.isEmpty()); 204 assertTrue(map.isEmpty()); 205 assertTrue(keys.isEmpty()); 206 assertTrue(values.isEmpty()); 207 assertTrue(entries.isEmpty()); 208 } 209 testTransformEquals()210 public void testTransformEquals() { 211 Map<String, Integer> underlying = ImmutableMap.of("a", 0, "b", 1, "c", 2); 212 Map<String, Integer> expected = Maps.transformValues(underlying, Functions.<Integer>identity()); 213 214 assertMapsEqual(expected, expected); 215 216 Map<String, Integer> equalToUnderlying = Maps.newTreeMap(); 217 equalToUnderlying.putAll(underlying); 218 Map<String, Integer> map = 219 Maps.transformValues(equalToUnderlying, Functions.<Integer>identity()); 220 assertMapsEqual(expected, map); 221 222 map = 223 Maps.transformValues( 224 ImmutableMap.of("a", 1, "b", 2, "c", 3), 225 new Function<Integer, Integer>() { 226 @Override 227 public Integer apply(Integer from) { 228 return from - 1; 229 } 230 }); 231 assertMapsEqual(expected, map); 232 } 233 testTransformEntrySetContains()234 public void testTransformEntrySetContains() { 235 Map<@Nullable String, @Nullable Boolean> underlying = Maps.newHashMap(); 236 underlying.put("a", null); 237 underlying.put("b", true); 238 underlying.put(null, true); 239 240 Map<@Nullable String, @Nullable Boolean> map = 241 Maps.transformValues( 242 underlying, 243 new Function<@Nullable Boolean, @Nullable Boolean>() { 244 @Override 245 public @Nullable Boolean apply(@Nullable Boolean from) { 246 return (from == null) ? true : null; 247 } 248 }); 249 250 Set<Entry<@Nullable String, @Nullable Boolean>> entries = map.entrySet(); 251 assertTrue(entries.contains(Maps.immutableEntry("a", true))); 252 assertTrue(entries.contains(Maps.<String, @Nullable Boolean>immutableEntry("b", null))); 253 assertTrue( 254 entries.contains(Maps.<@Nullable String, @Nullable Boolean>immutableEntry(null, null))); 255 256 assertFalse(entries.contains(Maps.<String, @Nullable Boolean>immutableEntry("c", null))); 257 assertFalse(entries.contains(Maps.<@Nullable String, Boolean>immutableEntry(null, true))); 258 } 259 260 @Override testKeySetRemoveAllNullFromEmpty()261 public void testKeySetRemoveAllNullFromEmpty() { 262 try { 263 super.testKeySetRemoveAllNullFromEmpty(); 264 } catch (RuntimeException tolerated) { 265 // GWT's HashMap.keySet().removeAll(null) doesn't throws NPE. 266 } 267 } 268 269 @Override testEntrySetRemoveAllNullFromEmpty()270 public void testEntrySetRemoveAllNullFromEmpty() { 271 try { 272 super.testEntrySetRemoveAllNullFromEmpty(); 273 } catch (RuntimeException tolerated) { 274 // GWT's HashMap.entrySet().removeAll(null) doesn't throws NPE. 275 } 276 } 277 } 278