Home | History | Annotate | Download | only in testers
      1 /*
      2  * Copyright (C) 2007 The Guava Authors
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  * http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.google.common.collect.testing.testers;
     18 
     19 import static com.google.common.collect.testing.features.CollectionSize.ZERO;
     20 import static com.google.common.collect.testing.features.MapFeature.ALLOWS_NULL_KEYS;
     21 import static com.google.common.collect.testing.features.MapFeature.ALLOWS_NULL_VALUES;
     22 import static com.google.common.collect.testing.features.MapFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION;
     23 import static com.google.common.collect.testing.features.MapFeature.SUPPORTS_PUT;
     24 
     25 import com.google.common.annotations.GwtCompatible;
     26 import com.google.common.collect.testing.AbstractMapTester;
     27 import com.google.common.collect.testing.features.CollectionSize;
     28 import com.google.common.collect.testing.features.MapFeature;
     29 
     30 import java.util.ConcurrentModificationException;
     31 import java.util.Iterator;
     32 import java.util.Map;
     33 import java.util.Map.Entry;
     34 
     35 /**
     36  * A generic JUnit test which tests {@code put} operations on a map. Can't be
     37  * invoked directly; please see
     38  * {@link com.google.common.collect.testing.MapTestSuiteBuilder}.
     39  *
     40  * @author Chris Povirk
     41  * @author Kevin Bourrillion
     42  */
     43 @SuppressWarnings("unchecked") // too many "unchecked generic array creations"
     44 @GwtCompatible(emulated = true)
     45 public class MapPutTester<K, V> extends AbstractMapTester<K, V> {
     46   private Entry<K, V> nullKeyEntry;
     47   private Entry<K, V> nullValueEntry;
     48   private Entry<K, V> nullKeyValueEntry;
     49   private Entry<K, V> presentKeyNullValueEntry;
     50 
     51   @Override public void setUp() throws Exception {
     52     super.setUp();
     53     nullKeyEntry = entry(null, samples.e3.getValue());
     54     nullValueEntry = entry(samples.e3.getKey(), null);
     55     nullKeyValueEntry = entry(null, null);
     56     presentKeyNullValueEntry = entry(samples.e0.getKey(), null);
     57   }
     58 
     59   @MapFeature.Require(SUPPORTS_PUT)
     60   public void testPut_supportedNotPresent() {
     61     assertNull("put(notPresent, value) should return null", put(samples.e3));
     62     expectAdded(samples.e3);
     63   }
     64 
     65   @MapFeature.Require({FAILS_FAST_ON_CONCURRENT_MODIFICATION, SUPPORTS_PUT})
     66   @CollectionSize.Require(absent = ZERO)
     67   public void testPutAbsentConcurrentWithEntrySetIteration() {
     68     try {
     69       Iterator<Entry<K, V>> iterator = getMap().entrySet().iterator();
     70       put(samples.e3);
     71       iterator.next();
     72       fail("Expected ConcurrentModificationException");
     73     } catch (ConcurrentModificationException expected) {
     74       // success
     75     }
     76   }
     77 
     78   @MapFeature.Require({FAILS_FAST_ON_CONCURRENT_MODIFICATION, SUPPORTS_PUT})
     79   @CollectionSize.Require(absent = ZERO)
     80   public void testPutAbsentConcurrentWithKeySetIteration() {
     81     try {
     82       Iterator<K> iterator = getMap().keySet().iterator();
     83       put(samples.e3);
     84       iterator.next();
     85       fail("Expected ConcurrentModificationException");
     86     } catch (ConcurrentModificationException expected) {
     87       // success
     88     }
     89   }
     90 
     91   @MapFeature.Require({FAILS_FAST_ON_CONCURRENT_MODIFICATION, SUPPORTS_PUT})
     92   @CollectionSize.Require(absent = ZERO)
     93   public void testPutAbsentConcurrentWithValueIteration() {
     94     try {
     95       Iterator<V> iterator = getMap().values().iterator();
     96       put(samples.e3);
     97       iterator.next();
     98       fail("Expected ConcurrentModificationException");
     99     } catch (ConcurrentModificationException expected) {
    100       // success
    101     }
    102   }
    103 
    104   @MapFeature.Require(absent = SUPPORTS_PUT)
    105   public void testPut_unsupportedNotPresent() {
    106     try {
    107       put(samples.e3);
    108       fail("put(notPresent, value) should throw");
    109     } catch (UnsupportedOperationException expected) {
    110     }
    111     expectUnchanged();
    112     expectMissing(samples.e3);
    113   }
    114 
    115   @MapFeature.Require(absent = SUPPORTS_PUT)
    116   @CollectionSize.Require(absent = ZERO)
    117   public void testPut_unsupportedPresentExistingValue() {
    118     try {
    119       assertEquals("put(present, existingValue) should return present or throw",
    120           samples.e0.getValue(), put(samples.e0));
    121     } catch (UnsupportedOperationException tolerated) {
    122     }
    123     expectUnchanged();
    124   }
    125 
    126   @MapFeature.Require(absent = SUPPORTS_PUT)
    127   @CollectionSize.Require(absent = ZERO)
    128   public void testPut_unsupportedPresentDifferentValue() {
    129     try {
    130       getMap().put(samples.e0.getKey(), samples.e3.getValue());
    131       fail("put(present, differentValue) should throw");
    132     } catch (UnsupportedOperationException expected) {
    133     }
    134     expectUnchanged();
    135   }
    136 
    137   @MapFeature.Require({SUPPORTS_PUT, ALLOWS_NULL_KEYS})
    138   public void testPut_nullKeySupportedNotPresent() {
    139     assertNull("put(null, value) should return null", put(nullKeyEntry));
    140     expectAdded(nullKeyEntry);
    141   }
    142 
    143   @MapFeature.Require({SUPPORTS_PUT, ALLOWS_NULL_KEYS})
    144   @CollectionSize.Require(absent = ZERO)
    145   public void testPut_nullKeySupportedPresent() {
    146     Entry<K, V> newEntry = entry(null, samples.e3.getValue());
    147     initMapWithNullKey();
    148     assertEquals("put(present, value) should return the associated value",
    149         getValueForNullKey(), put(newEntry));
    150 
    151     Entry<K, V>[] expected = createArrayWithNullKey();
    152     expected[getNullLocation()] = newEntry;
    153     expectContents(expected);
    154   }
    155 
    156   @MapFeature.Require(value = SUPPORTS_PUT, absent = ALLOWS_NULL_KEYS)
    157   public void testPut_nullKeyUnsupported() {
    158     try {
    159       put(nullKeyEntry);
    160       fail("put(null, value) should throw");
    161     } catch (NullPointerException expected) {
    162     }
    163     expectUnchanged();
    164     expectNullKeyMissingWhenNullKeysUnsupported(
    165         "Should not contain null key after unsupported put(null, value)");
    166   }
    167 
    168   @MapFeature.Require({SUPPORTS_PUT, ALLOWS_NULL_VALUES})
    169   public void testPut_nullValueSupported() {
    170     assertNull("put(key, null) should return null", put(nullValueEntry));
    171     expectAdded(nullValueEntry);
    172   }
    173 
    174   @MapFeature.Require(value = SUPPORTS_PUT, absent = ALLOWS_NULL_VALUES)
    175   public void testPut_nullValueUnsupported() {
    176     try {
    177       put(nullValueEntry);
    178       fail("put(key, null) should throw");
    179     } catch (NullPointerException expected) {
    180     }
    181     expectUnchanged();
    182     expectNullValueMissingWhenNullValuesUnsupported(
    183         "Should not contain null value after unsupported put(key, null)");
    184   }
    185 
    186   @MapFeature.Require({SUPPORTS_PUT, ALLOWS_NULL_VALUES})
    187   @CollectionSize.Require(absent = ZERO)
    188   public void testPut_replaceWithNullValueSupported() {
    189     assertEquals("put(present, null) should return the associated value",
    190         samples.e0.getValue(), put(presentKeyNullValueEntry));
    191     expectReplacement(presentKeyNullValueEntry);
    192   }
    193 
    194   @MapFeature.Require(value = SUPPORTS_PUT, absent = ALLOWS_NULL_VALUES)
    195   @CollectionSize.Require(absent = ZERO)
    196   public void testPut_replaceWithNullValueUnsupported() {
    197     try {
    198       put(presentKeyNullValueEntry);
    199       fail("put(present, null) should throw");
    200     } catch (NullPointerException expected) {
    201     }
    202     expectUnchanged();
    203     expectNullValueMissingWhenNullValuesUnsupported(
    204         "Should not contain null after unsupported put(present, null)");
    205   }
    206 
    207   @MapFeature.Require({SUPPORTS_PUT, ALLOWS_NULL_VALUES})
    208   @CollectionSize.Require(absent = ZERO)
    209   public void testPut_replaceNullValueWithNullSupported() {
    210     initMapWithNullValue();
    211     assertNull("put(present, null) should return the associated value (null)",
    212         getMap().put(getKeyForNullValue(), null));
    213     expectContents(createArrayWithNullValue());
    214   }
    215 
    216   @MapFeature.Require({SUPPORTS_PUT, ALLOWS_NULL_VALUES})
    217   @CollectionSize.Require(absent = ZERO)
    218   public void testPut_replaceNullValueWithNonNullSupported() {
    219     Entry<K, V> newEntry = entry(getKeyForNullValue(), samples.e3.getValue());
    220     initMapWithNullValue();
    221     assertNull("put(present, value) should return the associated value (null)",
    222         put(newEntry));
    223 
    224     Entry<K, V>[] expected = createArrayWithNullValue();
    225     expected[getNullLocation()] = newEntry;
    226     expectContents(expected);
    227   }
    228 
    229   @MapFeature.Require({SUPPORTS_PUT, ALLOWS_NULL_KEYS, ALLOWS_NULL_VALUES})
    230   public void testPut_nullKeyAndValueSupported() {
    231     assertNull("put(null, null) should return null", put(nullKeyValueEntry));
    232     expectAdded(nullKeyValueEntry);
    233   }
    234 
    235   private V put(Map.Entry<K, V> entry) {
    236     return getMap().put(entry.getKey(), entry.getValue());
    237   }
    238 }
    239 
    240