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; 024 025import com.google.common.annotations.GwtCompatible; 026import com.google.common.collect.testing.AbstractMapTester; 027import com.google.common.collect.testing.features.CollectionSize; 028import com.google.common.collect.testing.features.MapFeature; 029import java.util.Map; 030import org.junit.Ignore; 031 032/** 033 * A generic JUnit test which tests {@link Map#compute}. Can't be invoked directly; please see 034 * {@link com.google.common.collect.testing.MapTestSuiteBuilder}. 035 * 036 * @author Louis Wasserman 037 */ 038@GwtCompatible 039@Ignore // Affects only Android test runner, which respects JUnit 4 annotations on JUnit 3 tests. 040public class MapComputeTester<K, V> extends AbstractMapTester<K, V> { 041 @MapFeature.Require({SUPPORTS_PUT, SUPPORTS_REMOVE}) 042 public void testCompute_absentToPresent() { 043 assertEquals( 044 "Map.compute(absent, functionReturningValue) should return value", 045 v3(), 046 getMap() 047 .compute( 048 k3(), 049 (k, v) -> { 050 assertEquals(k3(), k); 051 assertNull(v); 052 return v3(); 053 })); 054 expectAdded(e3()); 055 assertEquals(getNumElements() + 1, getMap().size()); 056 } 057 058 @MapFeature.Require({SUPPORTS_PUT, SUPPORTS_REMOVE}) 059 public void testCompute_absentToAbsent() { 060 assertNull( 061 "Map.compute(absent, functionReturningNull) should return null", 062 getMap() 063 .compute( 064 k3(), 065 (k, v) -> { 066 assertEquals(k3(), k); 067 assertNull(v); 068 return null; 069 })); 070 expectUnchanged(); 071 assertEquals(getNumElements(), getMap().size()); 072 } 073 074 @MapFeature.Require({SUPPORTS_PUT, SUPPORTS_REMOVE}) 075 @CollectionSize.Require(absent = ZERO) 076 public void testCompute_presentToPresent() { 077 assertEquals( 078 "Map.compute(present, functionReturningValue) should return new value", 079 v3(), 080 getMap() 081 .compute( 082 k0(), 083 (k, v) -> { 084 assertEquals(k0(), k); 085 assertEquals(v0(), v); 086 return v3(); 087 })); 088 expectReplacement(entry(k0(), v3())); 089 assertEquals(getNumElements(), getMap().size()); 090 } 091 092 @MapFeature.Require({SUPPORTS_PUT, SUPPORTS_REMOVE}) 093 @CollectionSize.Require(absent = ZERO) 094 public void testCompute_presentToAbsent() { 095 assertNull( 096 "Map.compute(present, functionReturningNull) should return null", 097 getMap() 098 .compute( 099 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) 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) 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) 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) 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}) 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}