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