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 java.util.Map.Entry;
030import org.junit.Ignore;
031
032/**
033 * A generic JUnit test which tests {@link Map#putIfAbsent}. 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 MapPutIfAbsentTester<K, V> extends AbstractMapTester<K, V> {
041
042  @MapFeature.Require(SUPPORTS_PUT)
043  public void testPutIfAbsent_supportedAbsent() {
044    assertNull(
045        "putIfAbsent(notPresent, value) should return null", getMap().putIfAbsent(k3(), v3()));
046    expectAdded(e3());
047  }
048
049  @MapFeature.Require(SUPPORTS_PUT)
050  @CollectionSize.Require(absent = ZERO)
051  public void testPutIfAbsent_supportedPresent() {
052    assertEquals(
053        "putIfAbsent(present, value) should return existing value",
054        v0(),
055        getMap().putIfAbsent(k0(), v3()));
056    expectUnchanged();
057  }
058
059  @MapFeature.Require(absent = SUPPORTS_PUT)
060  public void testPutIfAbsent_unsupportedAbsent() {
061    try {
062      getMap().putIfAbsent(k3(), v3());
063      fail("putIfAbsent(notPresent, value) should throw");
064    } catch (UnsupportedOperationException expected) {
065    }
066    expectUnchanged();
067    expectMissing(e3());
068  }
069
070  @MapFeature.Require(absent = SUPPORTS_PUT)
071  @CollectionSize.Require(absent = ZERO)
072  public void testPutIfAbsent_unsupportedPresentExistingValue() {
073    try {
074      assertEquals(
075          "putIfAbsent(present, existingValue) should return present or throw",
076          v0(),
077          getMap().putIfAbsent(k0(), v0()));
078    } catch (UnsupportedOperationException tolerated) {
079    }
080    expectUnchanged();
081  }
082
083  @MapFeature.Require(absent = SUPPORTS_PUT)
084  @CollectionSize.Require(absent = ZERO)
085  public void testPutIfAbsent_unsupportedPresentDifferentValue() {
086    try {
087      getMap().putIfAbsent(k0(), v3());
088    } catch (UnsupportedOperationException tolerated) {
089    }
090    expectUnchanged();
091  }
092
093  @MapFeature.Require(value = SUPPORTS_PUT, absent = ALLOWS_NULL_KEYS)
094  public void testPutIfAbsent_nullKeyUnsupported() {
095    try {
096      getMap().putIfAbsent(null, v3());
097      fail("putIfAbsent(null, value) should throw");
098    } catch (NullPointerException expected) {
099    }
100    expectUnchanged();
101    expectNullKeyMissingWhenNullKeysUnsupported(
102        "Should not contain null key after unsupported putIfAbsent(null, value)");
103  }
104
105  @MapFeature.Require(value = SUPPORTS_PUT, absent = ALLOWS_NULL_VALUES)
106  public void testPutIfAbsent_nullValueUnsupportedAndKeyAbsent() {
107    try {
108      getMap().putIfAbsent(k3(), null);
109      fail("putIfAbsent(key, null) should throw");
110    } catch (NullPointerException expected) {
111    }
112    expectUnchanged();
113    expectNullValueMissingWhenNullValuesUnsupported(
114        "Should not contain null value after unsupported putIfAbsent(key, null)");
115  }
116
117  @MapFeature.Require(value = SUPPORTS_PUT, absent = ALLOWS_NULL_VALUES)
118  @CollectionSize.Require(absent = ZERO)
119  public void testPutIfAbsent_nullValueUnsupportedAndKeyPresent() {
120    try {
121      getMap().putIfAbsent(k0(), null);
122    } catch (NullPointerException tolerated) {
123    }
124    expectUnchanged();
125    expectNullValueMissingWhenNullValuesUnsupported(
126        "Should not contain null after unsupported putIfAbsent(present, null)");
127  }
128
129  @MapFeature.Require({SUPPORTS_PUT, ALLOWS_NULL_VALUES})
130  public void testPut_nullValueSupported() {
131    Entry<K, V> nullValueEntry = entry(k3(), null);
132    assertNull(
133        "putIfAbsent(key, null) should return null",
134        getMap().putIfAbsent(nullValueEntry.getKey(), nullValueEntry.getValue()));
135    expectAdded(nullValueEntry);
136  }
137}