001/* 002 * Copyright (C) 2015 The Guava Authors 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package com.google.common.collect.testing.testers; 018 019import static com.google.common.collect.testing.features.CollectionSize.ZERO; 020import static com.google.common.collect.testing.features.MapFeature.ALLOWS_NULL_KEYS; 021import static com.google.common.collect.testing.features.MapFeature.ALLOWS_NULL_VALUES; 022import static com.google.common.collect.testing.features.MapFeature.SUPPORTS_PUT; 023import static com.google.common.collect.testing.features.MapFeature.SUPPORTS_REMOVE; 024import static com.google.common.collect.testing.testers.ReflectionFreeAssertThrows.assertThrows; 025 026import com.google.common.annotations.GwtCompatible; 027import com.google.common.collect.testing.AbstractMapTester; 028import com.google.common.collect.testing.features.CollectionSize; 029import com.google.common.collect.testing.features.MapFeature; 030import com.google.common.collect.testing.testers.TestExceptions.SomeUncheckedException; 031import java.util.Map; 032import org.junit.Ignore; 033 034/** 035 * A generic JUnit test which tests {@link Map#compute}. Can't be invoked directly; please see 036 * {@link com.google.common.collect.testing.MapTestSuiteBuilder}. 037 * 038 * @author Louis Wasserman 039 */ 040@GwtCompatible 041@Ignore("test runners must not instantiate and run this directly, only via suites we build") 042// @Ignore affects the Android test runner, which respects JUnit 4 annotations on JUnit 3 tests. 043@SuppressWarnings("JUnit4ClassUsedInJUnit3") 044@IgnoreJRERequirement // We opt into library desugaring for our tests. 045public class MapComputeTester<K, V> extends AbstractMapTester<K, V> { 046 @MapFeature.Require({SUPPORTS_PUT, SUPPORTS_REMOVE}) 047 public void testCompute_absentToPresent() { 048 assertEquals( 049 "Map.compute(absent, functionReturningValue) should return value", 050 v3(), 051 getMap() 052 .compute( 053 k3(), 054 (k, v) -> { 055 assertEquals(k3(), k); 056 assertNull(v); 057 return v3(); 058 })); 059 expectAdded(e3()); 060 assertEquals(getNumElements() + 1, getMap().size()); 061 } 062 063 @MapFeature.Require({SUPPORTS_PUT, SUPPORTS_REMOVE}) 064 public void testCompute_absentToAbsent() { 065 assertNull( 066 "Map.compute(absent, functionReturningNull) should return null", 067 getMap() 068 .compute( 069 k3(), 070 (k, v) -> { 071 assertEquals(k3(), k); 072 assertNull(v); 073 return null; 074 })); 075 expectUnchanged(); 076 assertEquals(getNumElements(), getMap().size()); 077 } 078 079 @MapFeature.Require({SUPPORTS_PUT, SUPPORTS_REMOVE}) 080 @CollectionSize.Require(absent = ZERO) 081 public void testCompute_presentToPresent() { 082 assertEquals( 083 "Map.compute(present, functionReturningValue) should return new value", 084 v3(), 085 getMap() 086 .compute( 087 k0(), 088 (k, v) -> { 089 assertEquals(k0(), k); 090 assertEquals(v0(), v); 091 return v3(); 092 })); 093 expectReplacement(entry(k0(), v3())); 094 assertEquals(getNumElements(), getMap().size()); 095 } 096 097 @MapFeature.Require({SUPPORTS_PUT, SUPPORTS_REMOVE}) 098 @CollectionSize.Require(absent = ZERO) 099 public void testCompute_presentToAbsent() { 100 assertNull( 101 "Map.compute(present, functionReturningNull) should return null", 102 getMap() 103 .compute( 104 k0(), 105 (k, v) -> { 106 assertEquals(k0(), k); 107 assertEquals(v0(), v); 108 return null; 109 })); 110 expectMissing(e0()); 111 expectMissingKeys(k0()); 112 assertEquals(getNumElements() - 1, getMap().size()); 113 } 114 115 @MapFeature.Require({SUPPORTS_PUT, SUPPORTS_REMOVE, ALLOWS_NULL_VALUES}) 116 @CollectionSize.Require(absent = ZERO) 117 public void testCompute_presentNullToPresentNonnull() { 118 initMapWithNullValue(); 119 V value = getValueForNullKey(); 120 assertEquals( 121 "Map.compute(presentMappedToNull, functionReturningValue) should return new value", 122 value, 123 getMap() 124 .compute( 125 getKeyForNullValue(), 126 (k, v) -> { 127 assertEquals(getKeyForNullValue(), k); 128 assertNull(v); 129 return value; 130 })); 131 expectReplacement(entry(getKeyForNullValue(), value)); 132 assertEquals(getNumElements(), getMap().size()); 133 } 134 135 @MapFeature.Require({SUPPORTS_PUT, SUPPORTS_REMOVE, ALLOWS_NULL_VALUES}) 136 @CollectionSize.Require(absent = ZERO) 137 public void testCompute_presentNullToNull() { 138 // The spec is somewhat ambiguous about this case, but the actual default implementation 139 // in Map will remove a present null. 140 initMapWithNullValue(); 141 assertNull( 142 "Map.compute(presentMappedToNull, functionReturningNull) should return null", 143 getMap() 144 .compute( 145 getKeyForNullValue(), 146 (k, v) -> { 147 assertEquals(getKeyForNullValue(), k); 148 assertNull(v); 149 return null; 150 })); 151 expectMissingKeys(getKeyForNullValue()); 152 assertEquals(getNumElements() - 1, getMap().size()); 153 } 154 155 @MapFeature.Require({SUPPORTS_PUT, SUPPORTS_REMOVE, ALLOWS_NULL_KEYS}) 156 @CollectionSize.Require(absent = ZERO) 157 public void testCompute_nullKeyPresentToPresent() { 158 initMapWithNullKey(); 159 assertEquals( 160 "Map.compute(present, functionReturningValue) should return new value", 161 v3(), 162 getMap() 163 .compute( 164 null, 165 (k, v) -> { 166 assertNull(k); 167 assertEquals(getValueForNullKey(), v); 168 return v3(); 169 })); 170 assertEquals(getNumElements(), getMap().size()); 171 } 172 173 @MapFeature.Require({SUPPORTS_PUT, SUPPORTS_REMOVE}) 174 @CollectionSize.Require(absent = ZERO) 175 public void testCompute_presentFunctionThrows() { 176 assertThrows( 177 SomeUncheckedException.class, 178 () -> 179 getMap() 180 .compute( 181 k0(), 182 (k, v) -> { 183 assertEquals(k0(), k); 184 assertEquals(v0(), v); 185 throw new SomeUncheckedException(); 186 })); 187 expectUnchanged(); 188 } 189 190 @MapFeature.Require({SUPPORTS_PUT, SUPPORTS_REMOVE}) 191 public void testCompute_absentFunctionThrows() { 192 assertThrows( 193 SomeUncheckedException.class, 194 () -> 195 getMap() 196 .compute( 197 k3(), 198 (k, v) -> { 199 assertEquals(k3(), k); 200 assertNull(v); 201 throw new SomeUncheckedException(); 202 })); 203 expectUnchanged(); 204 } 205}