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 24 import com.google.common.annotations.GwtCompatible; 25 import com.google.common.collect.testing.AbstractMapTester; 26 import com.google.common.collect.testing.features.CollectionSize; 27 import com.google.common.collect.testing.features.MapFeature; 28 import java.util.Map; 29 import junit.framework.AssertionFailedError; 30 import org.junit.Ignore; 31 32 /** 33 * A generic JUnit test which tests {@link Map#computeIfAbsent}. Can't be invoked directly; please 34 * see {@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 MapComputeIfAbsentTester<K, V> extends AbstractMapTester<K, V> { 41 42 @MapFeature.Require(SUPPORTS_PUT) testComputeIfAbsent_supportedAbsent()43 public void testComputeIfAbsent_supportedAbsent() { 44 assertEquals( 45 "computeIfAbsent(notPresent, function) should return new value", 46 v3(), 47 getMap() 48 .computeIfAbsent( 49 k3(), 50 k -> { 51 assertEquals(k3(), k); 52 return v3(); 53 })); 54 expectAdded(e3()); 55 } 56 57 @MapFeature.Require(SUPPORTS_PUT) 58 @CollectionSize.Require(absent = ZERO) testComputeIfAbsent_supportedPresent()59 public void testComputeIfAbsent_supportedPresent() { 60 assertEquals( 61 "computeIfAbsent(present, function) should return existing value", 62 v0(), 63 getMap() 64 .computeIfAbsent( 65 k0(), 66 k -> { 67 throw new AssertionFailedError(); 68 })); 69 expectUnchanged(); 70 } 71 72 @MapFeature.Require(SUPPORTS_PUT) testComputeIfAbsent_functionReturnsNullNotInserted()73 public void testComputeIfAbsent_functionReturnsNullNotInserted() { 74 assertNull( 75 "computeIfAbsent(absent, returnsNull) should return null", 76 getMap() 77 .computeIfAbsent( 78 k3(), 79 k -> { 80 assertEquals(k3(), k); 81 return null; 82 })); 83 expectUnchanged(); 84 } 85 86 @MapFeature.Require({SUPPORTS_PUT, ALLOWS_NULL_VALUES}) 87 @CollectionSize.Require(absent = ZERO) testComputeIfAbsent_nullTreatedAsAbsent()88 public void testComputeIfAbsent_nullTreatedAsAbsent() { 89 initMapWithNullValue(); 90 assertEquals( 91 "computeIfAbsent(presentAssignedToNull, function) should return newValue", 92 getValueForNullKey(), 93 getMap() 94 .computeIfAbsent( 95 getKeyForNullValue(), 96 k -> { 97 assertEquals(getKeyForNullValue(), k); 98 return getValueForNullKey(); 99 })); 100 expectReplacement(entry(getKeyForNullValue(), getValueForNullKey())); 101 } 102 103 @MapFeature.Require({SUPPORTS_PUT, ALLOWS_NULL_KEYS}) testComputeIfAbsent_nullKeySupported()104 public void testComputeIfAbsent_nullKeySupported() { 105 getMap() 106 .computeIfAbsent( 107 null, 108 k -> { 109 assertNull(k); 110 return v3(); 111 }); 112 expectAdded(entry(null, v3())); 113 } 114 115 static class ExpectedException extends RuntimeException {} 116 117 @MapFeature.Require(SUPPORTS_PUT) testComputeIfAbsent_functionThrows()118 public void testComputeIfAbsent_functionThrows() { 119 try { 120 getMap() 121 .computeIfAbsent( 122 k3(), 123 k -> { 124 assertEquals(k3(), k); 125 throw new ExpectedException(); 126 }); 127 fail("Expected ExpectedException"); 128 } catch (ExpectedException expected) { 129 } 130 expectUnchanged(); 131 } 132 133 @MapFeature.Require(absent = SUPPORTS_PUT) testComputeIfAbsent_unsupportedAbsent()134 public void testComputeIfAbsent_unsupportedAbsent() { 135 try { 136 getMap() 137 .computeIfAbsent( 138 k3(), 139 k -> { 140 // allowed to be called 141 assertEquals(k3(), k); 142 return v3(); 143 }); 144 fail("computeIfAbsent(notPresent, function) should throw"); 145 } catch (UnsupportedOperationException expected) { 146 } 147 expectUnchanged(); 148 } 149 150 @MapFeature.Require(absent = SUPPORTS_PUT) 151 @CollectionSize.Require(absent = ZERO) testComputeIfAbsent_unsupportedPresentExistingValue()152 public void testComputeIfAbsent_unsupportedPresentExistingValue() { 153 try { 154 assertEquals( 155 "computeIfAbsent(present, returnsCurrentValue) should return present or throw", 156 v0(), 157 getMap() 158 .computeIfAbsent( 159 k0(), 160 k -> { 161 assertEquals(k0(), k); 162 return v0(); 163 })); 164 } catch (UnsupportedOperationException tolerated) { 165 } 166 expectUnchanged(); 167 } 168 169 @MapFeature.Require(absent = SUPPORTS_PUT) 170 @CollectionSize.Require(absent = ZERO) testComputeIfAbsent_unsupportedPresentDifferentValue()171 public void testComputeIfAbsent_unsupportedPresentDifferentValue() { 172 try { 173 assertEquals( 174 "computeIfAbsent(present, returnsDifferentValue) should return present or throw", 175 v0(), 176 getMap() 177 .computeIfAbsent( 178 k0(), 179 k -> { 180 assertEquals(k0(), k); 181 return v3(); 182 })); 183 } catch (UnsupportedOperationException tolerated) { 184 } 185 expectUnchanged(); 186 } 187 188 @MapFeature.Require(value = SUPPORTS_PUT, absent = ALLOWS_NULL_KEYS) testComputeIfAbsent_nullKeyUnsupported()189 public void testComputeIfAbsent_nullKeyUnsupported() { 190 try { 191 getMap() 192 .computeIfAbsent( 193 null, 194 k -> { 195 assertNull(k); 196 return v3(); 197 }); 198 fail("computeIfAbsent(null, function) should throw"); 199 } catch (NullPointerException expected) { 200 } 201 expectUnchanged(); 202 expectNullKeyMissingWhenNullKeysUnsupported( 203 "Should not contain null key after unsupported computeIfAbsent(null, function)"); 204 } 205 } 206