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; 023 024import com.google.common.annotations.GwtCompatible; 025import com.google.common.collect.testing.AbstractMapTester; 026import com.google.common.collect.testing.features.CollectionSize; 027import com.google.common.collect.testing.features.MapFeature; 028import java.util.Map; 029import junit.framework.AssertionFailedError; 030import org.junit.Ignore; 031 032/** 033 * A generic JUnit test which tests {@link Map#computeIfAbsent}. Can't be invoked directly; please 034 * see {@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. 040@SuppressWarnings("JUnit4ClassUsedInJUnit3") 041public class MapComputeIfAbsentTester<K, V> extends AbstractMapTester<K, V> { 042 043 @MapFeature.Require(SUPPORTS_PUT) 044 public void testComputeIfAbsent_supportedAbsent() { 045 assertEquals( 046 "computeIfAbsent(notPresent, function) should return new value", 047 v3(), 048 getMap() 049 .computeIfAbsent( 050 k3(), 051 k -> { 052 assertEquals(k3(), k); 053 return v3(); 054 })); 055 expectAdded(e3()); 056 } 057 058 @MapFeature.Require(SUPPORTS_PUT) 059 @CollectionSize.Require(absent = ZERO) 060 public void testComputeIfAbsent_supportedPresent() { 061 assertEquals( 062 "computeIfAbsent(present, function) should return existing value", 063 v0(), 064 getMap() 065 .computeIfAbsent( 066 k0(), 067 k -> { 068 throw new AssertionFailedError(); 069 })); 070 expectUnchanged(); 071 } 072 073 @MapFeature.Require(SUPPORTS_PUT) 074 public void testComputeIfAbsent_functionReturnsNullNotInserted() { 075 assertNull( 076 "computeIfAbsent(absent, returnsNull) should return null", 077 getMap() 078 .computeIfAbsent( 079 k3(), 080 k -> { 081 assertEquals(k3(), k); 082 return null; 083 })); 084 expectUnchanged(); 085 } 086 087 @MapFeature.Require({SUPPORTS_PUT, ALLOWS_NULL_VALUES}) 088 @CollectionSize.Require(absent = ZERO) 089 public void testComputeIfAbsent_nullTreatedAsAbsent() { 090 initMapWithNullValue(); 091 assertEquals( 092 "computeIfAbsent(presentAssignedToNull, function) should return newValue", 093 getValueForNullKey(), 094 getMap() 095 .computeIfAbsent( 096 getKeyForNullValue(), 097 k -> { 098 assertEquals(getKeyForNullValue(), k); 099 return getValueForNullKey(); 100 })); 101 expectReplacement(entry(getKeyForNullValue(), getValueForNullKey())); 102 } 103 104 @MapFeature.Require({SUPPORTS_PUT, ALLOWS_NULL_KEYS}) 105 public void testComputeIfAbsent_nullKeySupported() { 106 getMap() 107 .computeIfAbsent( 108 null, 109 k -> { 110 assertNull(k); 111 return v3(); 112 }); 113 expectAdded(entry(null, v3())); 114 } 115 116 static class ExpectedException extends RuntimeException {} 117 118 @MapFeature.Require(SUPPORTS_PUT) 119 public void testComputeIfAbsent_functionThrows() { 120 try { 121 getMap() 122 .computeIfAbsent( 123 k3(), 124 k -> { 125 assertEquals(k3(), k); 126 throw new ExpectedException(); 127 }); 128 fail("Expected ExpectedException"); 129 } catch (ExpectedException expected) { 130 } 131 expectUnchanged(); 132 } 133 134 @MapFeature.Require(absent = SUPPORTS_PUT) 135 public void testComputeIfAbsent_unsupportedAbsent() { 136 try { 137 getMap() 138 .computeIfAbsent( 139 k3(), 140 k -> { 141 // allowed to be called 142 assertEquals(k3(), k); 143 return v3(); 144 }); 145 fail("computeIfAbsent(notPresent, function) should throw"); 146 } catch (UnsupportedOperationException expected) { 147 } 148 expectUnchanged(); 149 } 150 151 @MapFeature.Require(absent = SUPPORTS_PUT) 152 @CollectionSize.Require(absent = ZERO) 153 public void testComputeIfAbsent_unsupportedPresentExistingValue() { 154 try { 155 assertEquals( 156 "computeIfAbsent(present, returnsCurrentValue) should return present or throw", 157 v0(), 158 getMap() 159 .computeIfAbsent( 160 k0(), 161 k -> { 162 assertEquals(k0(), k); 163 return v0(); 164 })); 165 } catch (UnsupportedOperationException tolerated) { 166 } 167 expectUnchanged(); 168 } 169 170 @MapFeature.Require(absent = SUPPORTS_PUT) 171 @CollectionSize.Require(absent = ZERO) 172 public void testComputeIfAbsent_unsupportedPresentDifferentValue() { 173 try { 174 assertEquals( 175 "computeIfAbsent(present, returnsDifferentValue) should return present or throw", 176 v0(), 177 getMap() 178 .computeIfAbsent( 179 k0(), 180 k -> { 181 assertEquals(k0(), k); 182 return v3(); 183 })); 184 } catch (UnsupportedOperationException tolerated) { 185 } 186 expectUnchanged(); 187 } 188 189 @MapFeature.Require(value = SUPPORTS_PUT, absent = ALLOWS_NULL_KEYS) 190 public void testComputeIfAbsent_nullKeyUnsupported() { 191 try { 192 getMap() 193 .computeIfAbsent( 194 null, 195 k -> { 196 assertNull(k); 197 return v3(); 198 }); 199 fail("computeIfAbsent(null, function) should throw"); 200 } catch (NullPointerException expected) { 201 } 202 expectUnchanged(); 203 expectNullKeyMissingWhenNullKeysUnsupported( 204 "Should not contain null key after unsupported computeIfAbsent(null, function)"); 205 } 206}