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") 044public class MapComputeTester<K, V> extends AbstractMapTester<K, V> { 045 @MapFeature.Require({SUPPORTS_PUT, SUPPORTS_REMOVE}) 046 public void testCompute_absentToPresent() { 047 assertEquals( 048 "Map.compute(absent, functionReturningValue) should return value", 049 v3(), 050 getMap() 051 .compute( 052 k3(), 053 (k, v) -> { 054 assertEquals(k3(), k); 055 assertNull(v); 056 return v3(); 057 })); 058 expectAdded(e3()); 059 assertEquals(getNumElements() + 1, getMap().size()); 060 } 061 062 @MapFeature.Require({SUPPORTS_PUT, SUPPORTS_REMOVE}) 063 public void testCompute_absentToAbsent() { 064 assertNull( 065 "Map.compute(absent, functionReturningNull) should return null", 066 getMap() 067 .compute( 068 k3(), 069 (k, v) -> { 070 assertEquals(k3(), k); 071 assertNull(v); 072 return null; 073 })); 074 expectUnchanged(); 075 assertEquals(getNumElements(), getMap().size()); 076 } 077 078 @MapFeature.Require({SUPPORTS_PUT, SUPPORTS_REMOVE}) 079 @CollectionSize.Require(absent = ZERO) 080 public void testCompute_presentToPresent() { 081 assertEquals( 082 "Map.compute(present, functionReturningValue) should return new value", 083 v3(), 084 getMap() 085 .compute( 086 k0(), 087 (k, v) -> { 088 assertEquals(k0(), k); 089 assertEquals(v0(), v); 090 return v3(); 091 })); 092 expectReplacement(entry(k0(), v3())); 093 assertEquals(getNumElements(), getMap().size()); 094 } 095 096 @MapFeature.Require({SUPPORTS_PUT, SUPPORTS_REMOVE}) 097 @CollectionSize.Require(absent = ZERO) 098 public void testCompute_presentToAbsent() { 099 assertNull( 100 "Map.compute(present, functionReturningNull) should return null", 101 getMap() 102 .compute( 103 k0(), 104 (k, v) -> { 105 assertEquals(k0(), k); 106 assertEquals(v0(), v); 107 return null; 108 })); 109 expectMissing(e0()); 110 expectMissingKeys(k0()); 111 assertEquals(getNumElements() - 1, getMap().size()); 112 } 113 114 @MapFeature.Require({SUPPORTS_PUT, SUPPORTS_REMOVE, ALLOWS_NULL_VALUES}) 115 @CollectionSize.Require(absent = ZERO) 116 public void testCompute_presentNullToPresentNonnull() { 117 initMapWithNullValue(); 118 V value = getValueForNullKey(); 119 assertEquals( 120 "Map.compute(presentMappedToNull, functionReturningValue) should return new value", 121 value, 122 getMap() 123 .compute( 124 getKeyForNullValue(), 125 (k, v) -> { 126 assertEquals(getKeyForNullValue(), k); 127 assertNull(v); 128 return value; 129 })); 130 expectReplacement(entry(getKeyForNullValue(), value)); 131 assertEquals(getNumElements(), getMap().size()); 132 } 133 134 @MapFeature.Require({SUPPORTS_PUT, SUPPORTS_REMOVE, ALLOWS_NULL_VALUES}) 135 @CollectionSize.Require(absent = ZERO) 136 public void testCompute_presentNullToNull() { 137 // The spec is somewhat ambiguous about this case, but the actual default implementation 138 // in Map will remove a present null. 139 initMapWithNullValue(); 140 assertNull( 141 "Map.compute(presentMappedToNull, functionReturningNull) should return null", 142 getMap() 143 .compute( 144 getKeyForNullValue(), 145 (k, v) -> { 146 assertEquals(getKeyForNullValue(), k); 147 assertNull(v); 148 return null; 149 })); 150 expectMissingKeys(getKeyForNullValue()); 151 assertEquals(getNumElements() - 1, getMap().size()); 152 } 153 154 @MapFeature.Require({SUPPORTS_PUT, SUPPORTS_REMOVE, ALLOWS_NULL_KEYS}) 155 @CollectionSize.Require(absent = ZERO) 156 public void testCompute_nullKeyPresentToPresent() { 157 initMapWithNullKey(); 158 assertEquals( 159 "Map.compute(present, functionReturningValue) should return new value", 160 v3(), 161 getMap() 162 .compute( 163 null, 164 (k, v) -> { 165 assertNull(k); 166 assertEquals(getValueForNullKey(), v); 167 return v3(); 168 })); 169 assertEquals(getNumElements(), getMap().size()); 170 } 171 172 @MapFeature.Require({SUPPORTS_PUT, SUPPORTS_REMOVE}) 173 @CollectionSize.Require(absent = ZERO) 174 public void testCompute_presentFunctionThrows() { 175 assertThrows( 176 SomeUncheckedException.class, 177 () -> 178 getMap() 179 .compute( 180 k0(), 181 (k, v) -> { 182 assertEquals(k0(), k); 183 assertEquals(v0(), v); 184 throw new SomeUncheckedException(); 185 })); 186 expectUnchanged(); 187 } 188 189 @MapFeature.Require({SUPPORTS_PUT, SUPPORTS_REMOVE}) 190 public void testCompute_absentFunctionThrows() { 191 assertThrows( 192 SomeUncheckedException.class, 193 () -> 194 getMap() 195 .compute( 196 k3(), 197 (k, v) -> { 198 assertEquals(k3(), k); 199 assertNull(v); 200 throw new SomeUncheckedException(); 201 })); 202 expectUnchanged(); 203 } 204}