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