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;
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 junit.framework.AssertionFailedError;
031import org.junit.Ignore;
032
033/**
034 * A generic JUnit test which tests {@link Map#computeIfPresent}. Can't be invoked directly; please
035 * see {@link com.google.common.collect.testing.MapTestSuiteBuilder}.
036 *
037 * @author Louis Wasserman
038 */
039@GwtCompatible
040@Ignore // Affects only Android test runner, which respects JUnit 4 annotations on JUnit 3 tests.
041@SuppressWarnings("JUnit4ClassUsedInJUnit3")
042public class MapComputeIfPresentTester<K, V> extends AbstractMapTester<K, V> {
043
044  @MapFeature.Require(SUPPORTS_PUT)
045  public void testComputeIfPresent_supportedAbsent() {
046    assertNull(
047        "computeIfPresent(notPresent, function) should return null",
048        getMap()
049            .computeIfPresent(
050                k3(),
051                (k, v) -> {
052                  throw new AssertionFailedError();
053                }));
054    expectUnchanged();
055  }
056
057  @MapFeature.Require(SUPPORTS_PUT)
058  @CollectionSize.Require(absent = ZERO)
059  public void testComputeIfPresent_supportedPresent() {
060    assertEquals(
061        "computeIfPresent(present, function) should return new value",
062        v3(),
063        getMap()
064            .computeIfPresent(
065                k0(),
066                (k, v) -> {
067                  assertEquals(k0(), k);
068                  assertEquals(v0(), v);
069                  return v3();
070                }));
071    expectReplacement(entry(k0(), v3()));
072  }
073
074  @MapFeature.Require(SUPPORTS_PUT)
075  @CollectionSize.Require(absent = ZERO)
076  public void testComputeIfPresent_functionReturnsNull() {
077    assertNull(
078        "computeIfPresent(present, returnsNull) should return null",
079        getMap()
080            .computeIfPresent(
081                k0(),
082                (k, v) -> {
083                  assertEquals(k0(), k);
084                  assertEquals(v0(), v);
085                  return null;
086                }));
087    expectMissing(e0());
088  }
089
090  @MapFeature.Require({SUPPORTS_PUT, ALLOWS_NULL_VALUES})
091  @CollectionSize.Require(absent = ZERO)
092  public void testComputeIfPresent_nullTreatedAsAbsent() {
093    initMapWithNullValue();
094    assertNull(
095        "computeIfPresent(presentAssignedToNull, function) should return null",
096        getMap()
097            .computeIfPresent(
098                getKeyForNullValue(),
099                (k, v) -> {
100                  throw new AssertionFailedError();
101                }));
102    expectReplacement(entry(getKeyForNullValue(), null));
103  }
104
105  static class ExpectedException extends RuntimeException {}
106
107  @MapFeature.Require(SUPPORTS_PUT)
108  @CollectionSize.Require(absent = ZERO)
109  public void testComputeIfPresent_functionThrows() {
110    try {
111      getMap()
112          .computeIfPresent(
113              k0(),
114              (k, v) -> {
115                assertEquals(k0(), k);
116                assertEquals(v0(), v);
117                throw new ExpectedException();
118              });
119      fail("Expected ExpectedException");
120    } catch (ExpectedException expected) {
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    try {
177      getMap().computeIfPresent(k0(), (k, v) -> v3());
178      fail("Expected UnsupportedOperationException");
179    } catch (UnsupportedOperationException expected) {
180    }
181    expectUnchanged();
182  }
183}