11d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/*
21d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Copyright (C) 2007 The Guava Authors
31d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
41d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Licensed under the Apache License, Version 2.0 (the "License");
51d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * you may not use this file except in compliance with the License.
61d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * You may obtain a copy of the License at
71d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
81d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * http://www.apache.org/licenses/LICENSE-2.0
91d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Unless required by applicable law or agreed to in writing, software
111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * distributed under the License is distributed on an "AS IS" BASIS,
121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * See the License for the specific language governing permissions and
141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * limitations under the License.
151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */
161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpackage com.google.common.collect.testing.testers;
181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.collect.testing.features.CollectionSize.ZERO;
201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.collect.testing.features.MapFeature.ALLOWS_NULL_KEYS;
211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.collect.testing.features.MapFeature.ALLOWS_NULL_VALUES;
221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.collect.testing.features.MapFeature.SUPPORTS_PUT_ALL;
231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static java.util.Collections.singletonList;
241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.collect.testing.AbstractMapTester;
261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.collect.testing.MinimalCollection;
271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.collect.testing.features.CollectionSize;
281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.collect.testing.features.MapFeature;
291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Collections;
311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.LinkedHashMap;
321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.List;
331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Map;
341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Map.Entry;
351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/**
371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * A generic JUnit test which tests {@code putAll} operations on a map. Can't be
381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * invoked directly; please see
391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link com.google.common.collect.testing.MapTestSuiteBuilder}.
401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>This class is GWT compatible.
421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author Chris Povirk
441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author Kevin Bourrillion
451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */
461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert@SuppressWarnings("unchecked") // too many "unchecked generic array creations"
471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpublic class MapPutAllTester<K, V> extends AbstractMapTester<K, V> {
481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private List<Entry<K, V>> containsNullKey;
491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private List<Entry<K, V>> containsNullValue;
501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @Override public void setUp() throws Exception {
521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    super.setUp();
531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    containsNullKey = singletonList(entry(null, samples.e3.getValue()));
541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    containsNullValue = singletonList(entry(samples.e3.getKey(), null));
551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @MapFeature.Require(SUPPORTS_PUT_ALL)
581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testPutAll_supportedNothing() {
591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    getMap().putAll(emptyMap());
601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    expectUnchanged();
611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @MapFeature.Require(absent = SUPPORTS_PUT_ALL)
641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testPutAll_unsupportedNothing() {
651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      getMap().putAll(emptyMap());
671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (UnsupportedOperationException tolerated) {
681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    expectUnchanged();
701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @MapFeature.Require(SUPPORTS_PUT_ALL)
731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testPutAll_supportedNonePresent() {
741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    putAll(createDisjointCollection());
751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    expectAdded(samples.e3, samples.e4);
761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @MapFeature.Require(absent = SUPPORTS_PUT_ALL)
791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testPutAll_unsupportedNonePresent() {
801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      putAll(createDisjointCollection());
821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail("putAll(nonePresent) should throw");
831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (UnsupportedOperationException expected) {
841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    expectUnchanged();
861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    expectMissing(samples.e3, samples.e4);
871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @MapFeature.Require(SUPPORTS_PUT_ALL)
901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @CollectionSize.Require(absent = ZERO)
911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testPutAll_supportedSomePresent() {
921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    putAll(MinimalCollection.of(samples.e3, samples.e0));
931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    expectAdded(samples.e3);
941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @MapFeature.Require(absent = SUPPORTS_PUT_ALL)
971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @CollectionSize.Require(absent = ZERO)
981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testPutAll_unsupportedSomePresent() {
991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
1001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      putAll(MinimalCollection.of(samples.e3, samples.e0));
1011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail("putAll(somePresent) should throw");
1021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (UnsupportedOperationException expected) {
1031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    expectUnchanged();
1051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @MapFeature.Require(absent = SUPPORTS_PUT_ALL)
1081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @CollectionSize.Require(absent = ZERO)
1091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testPutAll_unsupportedAllPresent() {
1101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
1111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      putAll(MinimalCollection.of(samples.e0));
1121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (UnsupportedOperationException tolerated) {
1131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    expectUnchanged();
1151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @MapFeature.Require({SUPPORTS_PUT_ALL,
1181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      ALLOWS_NULL_KEYS})
1191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testPutAll_nullKeySupported() {
1201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    putAll(containsNullKey);
1211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    expectAdded(containsNullKey.get(0));
1221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @MapFeature.Require(value = SUPPORTS_PUT_ALL,
1251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      absent = ALLOWS_NULL_KEYS)
1261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testAdd_nullKeyUnsupported() {
1271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
1281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      putAll(containsNullKey);
1291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail("putAll(containsNullKey) should throw");
1301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (NullPointerException expected) {
1311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    expectUnchanged();
1331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    expectNullKeyMissingWhenNullKeysUnsupported(
1341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        "Should not contain null key after unsupported " +
1351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        "putAll(containsNullKey)");
1361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @MapFeature.Require({SUPPORTS_PUT_ALL,
1391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      ALLOWS_NULL_VALUES})
1401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testPutAll_nullValueSupported() {
1411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    putAll(containsNullValue);
1421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    expectAdded(containsNullValue.get(0));
1431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @MapFeature.Require(value = SUPPORTS_PUT_ALL,
1461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      absent = ALLOWS_NULL_VALUES)
1471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testAdd_nullValueUnsupported() {
1481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
1491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      putAll(containsNullValue);
1501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail("putAll(containsNullValue) should throw");
1511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (NullPointerException expected) {
1521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    expectUnchanged();
1541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    expectNullValueMissingWhenNullValuesUnsupported(
1551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        "Should not contain null value after unsupported " +
1561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        "putAll(containsNullValue)");
1571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @MapFeature.Require(SUPPORTS_PUT_ALL)
1601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testPutAll_nullCollectionReference() {
1611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
1621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      getMap().putAll(null);
1631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail("putAll(null) should throw NullPointerException");
1641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (NullPointerException expected) {
1651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private Map<K, V> emptyMap() {
1691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return Collections.emptyMap();
1701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private void putAll(Iterable<Entry<K, V>> entries) {
1731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<K, V> map = new LinkedHashMap<K, V>();
1741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (Entry<K, V> entry : entries) {
1751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      map.put(entry.getKey(), entry.getValue());
1761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    getMap().putAll(map);
1781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert}
180