1 /* 2 * Copyright (C) 2015 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.testing.testers; 18 19 import static com.google.common.collect.testing.features.CollectionSize.ZERO; 20 import static com.google.common.collect.testing.features.MapFeature.ALLOWS_NULL_KEYS; 21 import static com.google.common.collect.testing.features.MapFeature.ALLOWS_NULL_VALUES; 22 import static com.google.common.collect.testing.features.MapFeature.SUPPORTS_PUT; 23 import static com.google.common.collect.testing.features.MapFeature.SUPPORTS_REMOVE; 24 25 import com.google.common.annotations.GwtCompatible; 26 import com.google.common.collect.testing.AbstractMapTester; 27 import com.google.common.collect.testing.features.CollectionSize; 28 import com.google.common.collect.testing.features.MapFeature; 29 import java.util.Map; 30 import org.junit.Ignore; 31 32 /** 33 * A generic JUnit test which tests {@link Map#compute}. Can't be invoked directly; please see 34 * {@link com.google.common.collect.testing.MapTestSuiteBuilder}. 35 * 36 * @author Louis Wasserman 37 */ 38 @GwtCompatible 39 @Ignore // Affects only Android test runner, which respects JUnit 4 annotations on JUnit 3 tests. 40 public class MapComputeTester<K, V> extends AbstractMapTester<K, V> { 41 @MapFeature.Require({SUPPORTS_PUT, SUPPORTS_REMOVE}) testCompute_absentToPresent()42 public void testCompute_absentToPresent() { 43 assertEquals( 44 "Map.compute(absent, functionReturningValue) should return value", 45 v3(), 46 getMap() 47 .compute( 48 k3(), 49 (k, v) -> { 50 assertEquals(k3(), k); 51 assertNull(v); 52 return v3(); 53 })); 54 expectAdded(e3()); 55 assertEquals(getNumElements() + 1, getMap().size()); 56 } 57 58 @MapFeature.Require({SUPPORTS_PUT, SUPPORTS_REMOVE}) testCompute_absentToAbsent()59 public void testCompute_absentToAbsent() { 60 assertNull( 61 "Map.compute(absent, functionReturningNull) should return null", 62 getMap() 63 .compute( 64 k3(), 65 (k, v) -> { 66 assertEquals(k3(), k); 67 assertNull(v); 68 return null; 69 })); 70 expectUnchanged(); 71 assertEquals(getNumElements(), getMap().size()); 72 } 73 74 @MapFeature.Require({SUPPORTS_PUT, SUPPORTS_REMOVE}) 75 @CollectionSize.Require(absent = ZERO) testCompute_presentToPresent()76 public void testCompute_presentToPresent() { 77 assertEquals( 78 "Map.compute(present, functionReturningValue) should return new value", 79 v3(), 80 getMap() 81 .compute( 82 k0(), 83 (k, v) -> { 84 assertEquals(k0(), k); 85 assertEquals(v0(), v); 86 return v3(); 87 })); 88 expectReplacement(entry(k0(), v3())); 89 assertEquals(getNumElements(), getMap().size()); 90 } 91 92 @MapFeature.Require({SUPPORTS_PUT, SUPPORTS_REMOVE}) 93 @CollectionSize.Require(absent = ZERO) testCompute_presentToAbsent()94 public void testCompute_presentToAbsent() { 95 assertNull( 96 "Map.compute(present, functionReturningNull) should return null", 97 getMap() 98 .compute( 99 k0(), 100 (k, v) -> { 101 assertEquals(k0(), k); 102 assertEquals(v0(), v); 103 return null; 104 })); 105 expectMissing(e0()); 106 expectMissingKeys(k0()); 107 assertEquals(getNumElements() - 1, getMap().size()); 108 } 109 110 @MapFeature.Require({SUPPORTS_PUT, SUPPORTS_REMOVE, ALLOWS_NULL_VALUES}) 111 @CollectionSize.Require(absent = ZERO) testCompute_presentNullToPresentNonnull()112 public void testCompute_presentNullToPresentNonnull() { 113 initMapWithNullValue(); 114 V value = getValueForNullKey(); 115 assertEquals( 116 "Map.compute(presentMappedToNull, functionReturningValue) should return new value", 117 value, 118 getMap() 119 .compute( 120 getKeyForNullValue(), 121 (k, v) -> { 122 assertEquals(getKeyForNullValue(), k); 123 assertNull(v); 124 return value; 125 })); 126 expectReplacement(entry(getKeyForNullValue(), value)); 127 assertEquals(getNumElements(), getMap().size()); 128 } 129 130 @MapFeature.Require({SUPPORTS_PUT, SUPPORTS_REMOVE, ALLOWS_NULL_VALUES}) 131 @CollectionSize.Require(absent = ZERO) testCompute_presentNullToNull()132 public void testCompute_presentNullToNull() { 133 // The spec is somewhat ambiguous about this case, but the actual default implementation 134 // in Map will remove a present null. 135 initMapWithNullValue(); 136 assertNull( 137 "Map.compute(presentMappedToNull, functionReturningNull) should return null", 138 getMap() 139 .compute( 140 getKeyForNullValue(), 141 (k, v) -> { 142 assertEquals(getKeyForNullValue(), k); 143 assertNull(v); 144 return null; 145 })); 146 expectMissingKeys(getKeyForNullValue()); 147 assertEquals(getNumElements() - 1, getMap().size()); 148 } 149 150 @MapFeature.Require({SUPPORTS_PUT, SUPPORTS_REMOVE, ALLOWS_NULL_KEYS}) 151 @CollectionSize.Require(absent = ZERO) testCompute_nullKeyPresentToPresent()152 public void testCompute_nullKeyPresentToPresent() { 153 initMapWithNullKey(); 154 assertEquals( 155 "Map.compute(present, functionReturningValue) should return new value", 156 v3(), 157 getMap() 158 .compute( 159 null, 160 (k, v) -> { 161 assertNull(k); 162 assertEquals(getValueForNullKey(), v); 163 return v3(); 164 })); 165 assertEquals(getNumElements(), getMap().size()); 166 } 167 168 static class ExpectedException extends RuntimeException {} 169 170 @MapFeature.Require({SUPPORTS_PUT, SUPPORTS_REMOVE}) 171 @CollectionSize.Require(absent = ZERO) testCompute_presentFunctionThrows()172 public void testCompute_presentFunctionThrows() { 173 try { 174 getMap() 175 .compute( 176 k0(), 177 (k, v) -> { 178 assertEquals(k0(), k); 179 assertEquals(v0(), v); 180 throw new ExpectedException(); 181 }); 182 fail("Expected ExpectedException"); 183 } catch (ExpectedException expected) { 184 } 185 expectUnchanged(); 186 } 187 188 @MapFeature.Require({SUPPORTS_PUT, SUPPORTS_REMOVE}) testCompute_absentFunctionThrows()189 public void testCompute_absentFunctionThrows() { 190 try { 191 getMap() 192 .compute( 193 k3(), 194 (k, v) -> { 195 assertEquals(k3(), k); 196 assertNull(v); 197 throw new ExpectedException(); 198 }); 199 fail("Expected ExpectedException"); 200 } catch (ExpectedException expected) { 201 } 202 expectUnchanged(); 203 } 204 } 205