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")
045@IgnoreJRERequirement // We opt into library desugaring for our tests.
046public class MapComputeIfPresentTester<K, V> extends AbstractMapTester<K, V> {
047
048  @MapFeature.Require(SUPPORTS_PUT)
049  public void testComputeIfPresent_supportedAbsent() {
050    assertNull(
051        "computeIfPresent(notPresent, function) should return null",
052        getMap()
053            .computeIfPresent(
054                k3(),
055                (k, v) -> {
056                  throw new AssertionFailedError();
057                }));
058    expectUnchanged();
059  }
060
061  @MapFeature.Require(SUPPORTS_PUT)
062  @CollectionSize.Require(absent = ZERO)
063  public void testComputeIfPresent_supportedPresent() {
064    assertEquals(
065        "computeIfPresent(present, function) should return new value",
066        v3(),
067        getMap()
068            .computeIfPresent(
069                k0(),
070                (k, v) -> {
071                  assertEquals(k0(), k);
072                  assertEquals(v0(), v);
073                  return v3();
074                }));
075    expectReplacement(entry(k0(), v3()));
076  }
077
078  @MapFeature.Require(SUPPORTS_PUT)
079  @CollectionSize.Require(absent = ZERO)
080  public void testComputeIfPresent_functionReturnsNull() {
081    assertNull(
082        "computeIfPresent(present, returnsNull) should return null",
083        getMap()
084            .computeIfPresent(
085                k0(),
086                (k, v) -> {
087                  assertEquals(k0(), k);
088                  assertEquals(v0(), v);
089                  return null;
090                }));
091    expectMissing(e0());
092  }
093
094  @MapFeature.Require({SUPPORTS_PUT, ALLOWS_NULL_VALUES})
095  @CollectionSize.Require(absent = ZERO)
096  public void testComputeIfPresent_nullTreatedAsAbsent() {
097    initMapWithNullValue();
098    assertNull(
099        "computeIfPresent(presentAssignedToNull, function) should return null",
100        getMap()
101            .computeIfPresent(
102                getKeyForNullValue(),
103                (k, v) -> {
104                  throw new AssertionFailedError();
105                }));
106    expectReplacement(entry(getKeyForNullValue(), null));
107  }
108
109  @MapFeature.Require(SUPPORTS_PUT)
110  @CollectionSize.Require(absent = ZERO)
111  public void testComputeIfPresent_functionThrows() {
112    assertThrows(
113        SomeUncheckedException.class,
114        () ->
115            getMap()
116                .computeIfPresent(
117                    k0(),
118                    (k, v) -> {
119                      assertEquals(k0(), k);
120                      assertEquals(v0(), v);
121                      throw new SomeUncheckedException();
122                    }));
123    expectUnchanged();
124  }
125
126  @MapFeature.Require({SUPPORTS_PUT, ALLOWS_NULL_KEYS})
127  @CollectionSize.Require(absent = ZERO)
128  public void testComputeIfPresent_nullKeySupportedPresent() {
129    initMapWithNullKey();
130    assertEquals(
131        "computeIfPresent(null, function) should return new value",
132        v3(),
133        getMap()
134            .computeIfPresent(
135                null,
136                (k, v) -> {
137                  assertNull(k);
138                  assertEquals(getValueForNullKey(), v);
139                  return v3();
140                }));
141
142    Entry<K, V>[] expected = createArrayWithNullKey();
143    expected[getNullLocation()] = entry(null, v3());
144    expectContents(expected);
145  }
146
147  @MapFeature.Require({SUPPORTS_PUT, ALLOWS_NULL_KEYS})
148  public void testComputeIfPresent_nullKeySupportedAbsent() {
149    assertNull(
150        "computeIfPresent(null, function) should return null",
151        getMap()
152            .computeIfPresent(
153                null,
154                (k, v) -> {
155                  throw new AssertionFailedError();
156                }));
157    expectUnchanged();
158  }
159
160  @MapFeature.Require(absent = SUPPORTS_PUT)
161  public void testComputeIfPresent_unsupportedAbsent() {
162    try {
163      getMap()
164          .computeIfPresent(
165              k3(),
166              (k, v) -> {
167                throw new AssertionFailedError();
168              });
169    } catch (UnsupportedOperationException tolerated) {
170    }
171    expectUnchanged();
172  }
173
174  @MapFeature.Require(absent = SUPPORTS_PUT)
175  @CollectionSize.Require(absent = ZERO)
176  public void testComputeIfPresent_unsupportedPresent() {
177    assertThrows(
178        UnsupportedOperationException.class, () -> getMap().computeIfPresent(k0(), (k, v) -> v3()));
179    expectUnchanged();
180  }
181}