001/*
002 * Copyright (C) 2016 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.testers.ReflectionFreeAssertThrows.assertThrows;
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 com.google.common.collect.testing.testers.TestExceptions.SomeUncheckedException;
030import java.util.Map;
031import java.util.Map.Entry;
032import junit.framework.AssertionFailedError;
033import org.junit.Ignore;
034
035/**
036 * A generic JUnit test which tests {@link Map#computeIfPresent}. Can't be invoked directly; please
037 * see {@link com.google.common.collect.testing.MapTestSuiteBuilder}.
038 *
039 * @author Louis Wasserman
040 */
041@GwtCompatible
042@Ignore("test runners must not instantiate and run this directly, only via suites we build")
043// @Ignore affects the Android test runner, which respects JUnit 4 annotations on JUnit 3 tests.
044@SuppressWarnings("JUnit4ClassUsedInJUnit3")
045public class MapComputeIfPresentTester<K, V> extends AbstractMapTester<K, V> {
046
047  @MapFeature.Require(SUPPORTS_PUT)
048  public void testComputeIfPresent_supportedAbsent() {
049    assertNull(
050        "computeIfPresent(notPresent, function) should return null",
051        getMap()
052            .computeIfPresent(
053                k3(),
054                (k, v) -> {
055                  throw new AssertionFailedError();
056                }));
057    expectUnchanged();
058  }
059
060  @MapFeature.Require(SUPPORTS_PUT)
061  @CollectionSize.Require(absent = ZERO)
062  public void testComputeIfPresent_supportedPresent() {
063    assertEquals(
064        "computeIfPresent(present, function) should return new value",
065        v3(),
066        getMap()
067            .computeIfPresent(
068                k0(),
069                (k, v) -> {
070                  assertEquals(k0(), k);
071                  assertEquals(v0(), v);
072                  return v3();
073                }));
074    expectReplacement(entry(k0(), v3()));
075  }
076
077  @MapFeature.Require(SUPPORTS_PUT)
078  @CollectionSize.Require(absent = ZERO)
079  public void testComputeIfPresent_functionReturnsNull() {
080    assertNull(
081        "computeIfPresent(present, returnsNull) should return null",
082        getMap()
083            .computeIfPresent(
084                k0(),
085                (k, v) -> {
086                  assertEquals(k0(), k);
087                  assertEquals(v0(), v);
088                  return null;
089                }));
090    expectMissing(e0());
091  }
092
093  @MapFeature.Require({SUPPORTS_PUT, ALLOWS_NULL_VALUES})
094  @CollectionSize.Require(absent = ZERO)
095  public void testComputeIfPresent_nullTreatedAsAbsent() {
096    initMapWithNullValue();
097    assertNull(
098        "computeIfPresent(presentAssignedToNull, function) should return null",
099        getMap()
100            .computeIfPresent(
101                getKeyForNullValue(),
102                (k, v) -> {
103                  throw new AssertionFailedError();
104                }));
105    expectReplacement(entry(getKeyForNullValue(), null));
106  }
107
108  @MapFeature.Require(SUPPORTS_PUT)
109  @CollectionSize.Require(absent = ZERO)
110  public void testComputeIfPresent_functionThrows() {
111    assertThrows(
112        SomeUncheckedException.class,
113        () ->
114            getMap()
115                .computeIfPresent(
116                    k0(),
117                    (k, v) -> {
118                      assertEquals(k0(), k);
119                      assertEquals(v0(), v);
120                      throw new SomeUncheckedException();
121                    }));
122    expectUnchanged();
123  }
124
125  @MapFeature.Require({SUPPORTS_PUT, ALLOWS_NULL_KEYS})
126  @CollectionSize.Require(absent = ZERO)
127  public void testComputeIfPresent_nullKeySupportedPresent() {
128    initMapWithNullKey();
129    assertEquals(
130        "computeIfPresent(null, function) should return new value",
131        v3(),
132        getMap()
133            .computeIfPresent(
134                null,
135                (k, v) -> {
136                  assertNull(k);
137                  assertEquals(getValueForNullKey(), v);
138                  return v3();
139                }));
140
141    Entry<K, V>[] expected = createArrayWithNullKey();
142    expected[getNullLocation()] = entry(null, v3());
143    expectContents(expected);
144  }
145
146  @MapFeature.Require({SUPPORTS_PUT, ALLOWS_NULL_KEYS})
147  public void testComputeIfPresent_nullKeySupportedAbsent() {
148    assertNull(
149        "computeIfPresent(null, function) should return null",
150        getMap()
151            .computeIfPresent(
152                null,
153                (k, v) -> {
154                  throw new AssertionFailedError();
155                }));
156    expectUnchanged();
157  }
158
159  @MapFeature.Require(absent = SUPPORTS_PUT)
160  public void testComputeIfPresent_unsupportedAbsent() {
161    try {
162      getMap()
163          .computeIfPresent(
164              k3(),
165              (k, v) -> {
166                throw new AssertionFailedError();
167              });
168    } catch (UnsupportedOperationException tolerated) {
169    }
170    expectUnchanged();
171  }
172
173  @MapFeature.Require(absent = SUPPORTS_PUT)
174  @CollectionSize.Require(absent = ZERO)
175  public void testComputeIfPresent_unsupportedPresent() {
176    assertThrows(
177        UnsupportedOperationException.class, () -> getMap().computeIfPresent(k0(), (k, v) -> v3()));
178    expectUnchanged();
179  }
180}