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 import static java.util.Collections.singletonList; 25 26 import com.google.common.annotations.GwtCompatible; 27 import com.google.common.collect.testing.AbstractMapTester; 28 import com.google.common.collect.testing.MinimalCollection; 29 import com.google.common.collect.testing.features.CollectionSize; 30 import com.google.common.collect.testing.features.MapFeature; 31 32 import java.util.Collections; 33 import java.util.ConcurrentModificationException; 34 import java.util.Iterator; 35 import java.util.LinkedHashMap; 36 import java.util.List; 37 import java.util.Map; 38 import java.util.Map.Entry; 39 40 /** 41 * A generic JUnit test which tests {@code putAll} operations on a map. Can't be 42 * invoked directly; please see 43 * {@link com.google.common.collect.testing.MapTestSuiteBuilder}. 44 * 45 * @author Chris Povirk 46 * @author Kevin Bourrillion 47 */ 48 @SuppressWarnings("unchecked") // too many "unchecked generic array creations" 49 @GwtCompatible(emulated = true) 50 public class MapPutAllTester<K, V> extends AbstractMapTester<K, V> { 51 private List<Entry<K, V>> containsNullKey; 52 private List<Entry<K, V>> containsNullValue; 53 54 @Override public void setUp() throws Exception { 55 super.setUp(); 56 containsNullKey = singletonList(entry(null, samples.e3.getValue())); 57 containsNullValue = singletonList(entry(samples.e3.getKey(), null)); 58 } 59 60 @MapFeature.Require(SUPPORTS_PUT) 61 public void testPutAll_supportedNothing() { 62 getMap().putAll(emptyMap()); 63 expectUnchanged(); 64 } 65 66 @MapFeature.Require(absent = SUPPORTS_PUT) 67 public void testPutAll_unsupportedNothing() { 68 try { 69 getMap().putAll(emptyMap()); 70 } catch (UnsupportedOperationException tolerated) { 71 } 72 expectUnchanged(); 73 } 74 75 @MapFeature.Require(SUPPORTS_PUT) 76 public void testPutAll_supportedNonePresent() { 77 putAll(createDisjointCollection()); 78 expectAdded(samples.e3, samples.e4); 79 } 80 81 @MapFeature.Require(absent = SUPPORTS_PUT) 82 public void testPutAll_unsupportedNonePresent() { 83 try { 84 putAll(createDisjointCollection()); 85 fail("putAll(nonePresent) should throw"); 86 } catch (UnsupportedOperationException expected) { 87 } 88 expectUnchanged(); 89 expectMissing(samples.e3, samples.e4); 90 } 91 92 @MapFeature.Require(SUPPORTS_PUT) 93 @CollectionSize.Require(absent = ZERO) 94 public void testPutAll_supportedSomePresent() { 95 putAll(MinimalCollection.of(samples.e3, samples.e0)); 96 expectAdded(samples.e3); 97 } 98 99 @MapFeature.Require({ FAILS_FAST_ON_CONCURRENT_MODIFICATION, 100 SUPPORTS_PUT }) 101 @CollectionSize.Require(absent = ZERO) 102 public void testPutAllSomePresentConcurrentWithEntrySetIteration() { 103 try { 104 Iterator<Entry<K, V>> iterator = getMap().entrySet().iterator(); 105 putAll(MinimalCollection.of(samples.e3, samples.e0)); 106 iterator.next(); 107 fail("Expected ConcurrentModificationException"); 108 } catch (ConcurrentModificationException expected) { 109 // success 110 } 111 } 112 113 @MapFeature.Require(absent = SUPPORTS_PUT) 114 @CollectionSize.Require(absent = ZERO) 115 public void testPutAll_unsupportedSomePresent() { 116 try { 117 putAll(MinimalCollection.of(samples.e3, samples.e0)); 118 fail("putAll(somePresent) should throw"); 119 } catch (UnsupportedOperationException expected) { 120 } 121 expectUnchanged(); 122 } 123 124 @MapFeature.Require(absent = SUPPORTS_PUT) 125 @CollectionSize.Require(absent = ZERO) 126 public void testPutAll_unsupportedAllPresent() { 127 try { 128 putAll(MinimalCollection.of(samples.e0)); 129 } catch (UnsupportedOperationException tolerated) { 130 } 131 expectUnchanged(); 132 } 133 134 @MapFeature.Require({SUPPORTS_PUT, 135 ALLOWS_NULL_KEYS}) 136 public void testPutAll_nullKeySupported() { 137 putAll(containsNullKey); 138 expectAdded(containsNullKey.get(0)); 139 } 140 141 @MapFeature.Require(value = SUPPORTS_PUT, 142 absent = ALLOWS_NULL_KEYS) 143 public void testPutAll_nullKeyUnsupported() { 144 try { 145 putAll(containsNullKey); 146 fail("putAll(containsNullKey) should throw"); 147 } catch (NullPointerException expected) { 148 } 149 expectUnchanged(); 150 expectNullKeyMissingWhenNullKeysUnsupported( 151 "Should not contain null key after unsupported " + 152 "putAll(containsNullKey)"); 153 } 154 155 @MapFeature.Require({SUPPORTS_PUT, 156 ALLOWS_NULL_VALUES}) 157 public void testPutAll_nullValueSupported() { 158 putAll(containsNullValue); 159 expectAdded(containsNullValue.get(0)); 160 } 161 162 @MapFeature.Require(value = SUPPORTS_PUT, 163 absent = ALLOWS_NULL_VALUES) 164 public void testPutAll_nullValueUnsupported() { 165 try { 166 putAll(containsNullValue); 167 fail("putAll(containsNullValue) should throw"); 168 } catch (NullPointerException expected) { 169 } 170 expectUnchanged(); 171 expectNullValueMissingWhenNullValuesUnsupported( 172 "Should not contain null value after unsupported " + 173 "putAll(containsNullValue)"); 174 } 175 176 @MapFeature.Require(SUPPORTS_PUT) 177 public void testPutAll_nullCollectionReference() { 178 try { 179 getMap().putAll(null); 180 fail("putAll(null) should throw NullPointerException"); 181 } catch (NullPointerException expected) { 182 } 183 } 184 185 private Map<K, V> emptyMap() { 186 return Collections.emptyMap(); 187 } 188 189 private void putAll(Iterable<Entry<K, V>> entries) { 190 Map<K, V> map = new LinkedHashMap<K, V>(); 191 for (Entry<K, V> entry : entries) { 192 map.put(entry.getKey(), entry.getValue()); 193 } 194 getMap().putAll(map); 195 } 196 } 197 198