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.Helpers.mapEntry;
020import static com.google.common.collect.testing.features.CollectionFeature.KNOWN_ORDER;
021import static com.google.common.collect.testing.features.CollectionSize.ZERO;
022import static com.google.common.collect.testing.features.MapFeature.SUPPORTS_PUT;
023import static org.junit.Assert.assertThrows;
024
025import com.google.common.annotations.GwtCompatible;
026import com.google.common.collect.testing.AbstractMapTester;
027import com.google.common.collect.testing.SampleElements;
028import com.google.common.collect.testing.features.CollectionFeature;
029import com.google.common.collect.testing.features.CollectionSize;
030import com.google.common.collect.testing.features.MapFeature;
031import java.util.ArrayList;
032import java.util.List;
033import java.util.Map.Entry;
034
035/**
036 * A generic JUnit test which tests {@code replaceAll()} operations on a map. Can't be invoked
037 * directly; please see {@link com.google.common.collect.testing.MapTestSuiteBuilder}.
038 *
039 * @author Louis Wasserman
040 */
041@GwtCompatible
042public class MapReplaceAllTester<K, V> extends AbstractMapTester<K, V> {
043  private SampleElements<K> keys() {
044    return new SampleElements<>(k0(), k1(), k2(), k3(), k4());
045  }
046
047  private SampleElements<V> values() {
048    return new SampleElements<>(v0(), v1(), v2(), v3(), v4());
049  }
050
051  @MapFeature.Require(SUPPORTS_PUT)
052  public void testReplaceAllRotate() {
053    getMap()
054        .replaceAll(
055            (K k, V v) -> {
056              int index = keys().asList().indexOf(k);
057              return values().asList().get(index + 1);
058            });
059    List<Entry<K, V>> expectedEntries = new ArrayList<>();
060    for (Entry<K, V> entry : getSampleEntries()) {
061      int index = keys().asList().indexOf(entry.getKey());
062      expectedEntries.add(mapEntry(entry.getKey(), values().asList().get(index + 1)));
063    }
064    expectContents(expectedEntries);
065  }
066
067  @MapFeature.Require(SUPPORTS_PUT)
068  @CollectionFeature.Require(KNOWN_ORDER)
069  public void testReplaceAllPreservesOrder() {
070    getMap()
071        .replaceAll(
072            (K k, V v) -> {
073              int index = keys().asList().indexOf(k);
074              return values().asList().get(index + 1);
075            });
076    List<Entry<K, V>> orderedEntries = getOrderedElements();
077    int index = 0;
078    for (K key : getMap().keySet()) {
079      assertEquals(orderedEntries.get(index).getKey(), key);
080      index++;
081    }
082  }
083
084  @MapFeature.Require(absent = SUPPORTS_PUT)
085  @CollectionSize.Require(absent = ZERO)
086  public void testReplaceAll_unsupported() {
087    assertThrows(
088        UnsupportedOperationException.class,
089        () ->
090            getMap()
091                .replaceAll(
092                    (K k, V v) -> {
093                      int index = keys().asList().indexOf(k);
094                      return values().asList().get(index + 1);
095                    }));
096    expectUnchanged();
097  }
098
099  @MapFeature.Require(absent = SUPPORTS_PUT)
100  @CollectionSize.Require(ZERO)
101  public void testReplaceAll_unsupportedByEmptyCollection() {
102    try {
103      getMap()
104          .replaceAll(
105              (K k, V v) -> {
106                int index = keys().asList().indexOf(k);
107                return values().asList().get(index + 1);
108              });
109    } catch (UnsupportedOperationException tolerated) {
110    }
111    expectUnchanged();
112  }
113
114  @MapFeature.Require(absent = SUPPORTS_PUT)
115  public void testReplaceAll_unsupportedNoOpFunction() {
116    try {
117      getMap().replaceAll((K k, V v) -> v);
118    } catch (UnsupportedOperationException tolerated) {
119    }
120    expectUnchanged();
121  }
122}