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.Entry; 029import java.util.concurrent.ConcurrentMap; 030 031/** 032 * A generic JUnit test which tests {@code putIfAbsent} operations on a concurrent map. Can't be 033 * invoked directly; please see {@link 034 * com.google.common.collect.testing.ConcurrentMapTestSuiteBuilder}. 035 * 036 * @author Louis Wasserman 037 */ 038@GwtCompatible 039public class ConcurrentMapPutIfAbsentTester<K, V> extends AbstractMapTester<K, V> { 040 @Override 041 protected ConcurrentMap<K, V> getMap() { 042 return (ConcurrentMap<K, V>) super.getMap(); 043 } 044 045 @MapFeature.Require(SUPPORTS_PUT) 046 public void testPutIfAbsent_supportedAbsent() { 047 assertNull("putIfAbsent(notPresent, value) should return null", putIfAbsent(e3())); 048 expectAdded(e3()); 049 } 050 051 @MapFeature.Require(SUPPORTS_PUT) 052 @CollectionSize.Require(absent = ZERO) 053 public void testPutIfAbsent_supportedPresent() { 054 assertEquals( 055 "putIfAbsent(present, value) should return existing value", 056 v0(), 057 getMap().putIfAbsent(k0(), v3())); 058 expectUnchanged(); 059 } 060 061 @MapFeature.Require(absent = SUPPORTS_PUT) 062 public void testPutIfAbsent_unsupportedAbsent() { 063 try { 064 putIfAbsent(e3()); 065 fail("putIfAbsent(notPresent, value) should throw"); 066 } catch (UnsupportedOperationException expected) { 067 } 068 expectUnchanged(); 069 expectMissing(e3()); 070 } 071 072 @MapFeature.Require(absent = SUPPORTS_PUT) 073 @CollectionSize.Require(absent = ZERO) 074 public void testPutIfAbsent_unsupportedPresentExistingValue() { 075 try { 076 assertEquals( 077 "putIfAbsent(present, existingValue) should return present or throw", 078 v0(), 079 putIfAbsent(e0())); 080 } catch (UnsupportedOperationException tolerated) { 081 } 082 expectUnchanged(); 083 } 084 085 @MapFeature.Require(absent = SUPPORTS_PUT) 086 @CollectionSize.Require(absent = ZERO) 087 public void testPutIfAbsent_unsupportedPresentDifferentValue() { 088 try { 089 getMap().putIfAbsent(k0(), v3()); 090 } catch (UnsupportedOperationException tolerated) { 091 } 092 expectUnchanged(); 093 } 094 095 @MapFeature.Require(value = SUPPORTS_PUT, absent = ALLOWS_NULL_KEYS) 096 public void testPutIfAbsent_nullKeyUnsupported() { 097 try { 098 getMap().putIfAbsent(null, v3()); 099 fail("putIfAbsent(null, value) should throw"); 100 } catch (NullPointerException expected) { 101 } 102 expectUnchanged(); 103 expectNullKeyMissingWhenNullKeysUnsupported( 104 "Should not contain null key after unsupported putIfAbsent(null, value)"); 105 } 106 107 @MapFeature.Require(value = SUPPORTS_PUT, absent = ALLOWS_NULL_VALUES) 108 public void testPutIfAbsent_nullValueUnsupported() { 109 try { 110 getMap().putIfAbsent(k3(), null); 111 fail("putIfAbsent(key, null) should throw"); 112 } catch (NullPointerException expected) { 113 } 114 expectUnchanged(); 115 expectNullValueMissingWhenNullValuesUnsupported( 116 "Should not contain null value after unsupported put(key, null)"); 117 } 118 119 @MapFeature.Require(value = SUPPORTS_PUT, absent = ALLOWS_NULL_VALUES) 120 @CollectionSize.Require(absent = ZERO) 121 public void testPutIfAbsent_putWithNullValueUnsupported() { 122 try { 123 getMap().putIfAbsent(k0(), null); 124 } catch (NullPointerException tolerated) { 125 } 126 expectUnchanged(); 127 expectNullValueMissingWhenNullValuesUnsupported( 128 "Should not contain null after unsupported putIfAbsent(present, null)"); 129 } 130 131 private V putIfAbsent(Entry<K, V> entry) { 132 return getMap().putIfAbsent(entry.getKey(), entry.getValue()); 133 } 134}