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.CollectionFeature.ALLOWS_NULL_VALUES; 20 import static com.google.common.collect.testing.features.CollectionFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION; 21 import static com.google.common.collect.testing.features.CollectionFeature.RESTRICTS_ELEMENTS; 22 import static com.google.common.collect.testing.features.CollectionFeature.SUPPORTS_ADD; 23 import static com.google.common.collect.testing.features.CollectionSize.ZERO; 24 import static java.util.Collections.singletonList; 25 26 import com.google.common.annotations.GwtCompatible; 27 import com.google.common.annotations.GwtIncompatible; 28 import com.google.common.collect.testing.AbstractCollectionTester; 29 import com.google.common.collect.testing.Helpers; 30 import com.google.common.collect.testing.MinimalCollection; 31 import com.google.common.collect.testing.features.CollectionFeature; 32 import com.google.common.collect.testing.features.CollectionSize; 33 34 import java.lang.reflect.Method; 35 import java.util.ConcurrentModificationException; 36 import java.util.Iterator; 37 import java.util.List; 38 39 /** 40 * A generic JUnit test which tests addAll operations on a collection. Can't be 41 * invoked directly; please see 42 * {@link com.google.common.collect.testing.CollectionTestSuiteBuilder}. 43 * 44 * @author Chris Povirk 45 * @author Kevin Bourrillion 46 */ 47 @SuppressWarnings("unchecked") // too many "unchecked generic array creations" 48 @GwtCompatible(emulated = true) 49 public class CollectionAddAllTester<E> extends AbstractCollectionTester<E> { 50 @CollectionFeature.Require(SUPPORTS_ADD) 51 public void testAddAll_supportedNothing() { 52 assertFalse("addAll(nothing) should return false", 53 collection.addAll(emptyCollection())); 54 expectUnchanged(); 55 } 56 57 @CollectionFeature.Require(absent = SUPPORTS_ADD) 58 public void testAddAll_unsupportedNothing() { 59 try { 60 assertFalse("addAll(nothing) should return false or throw", 61 collection.addAll(emptyCollection())); 62 } catch (UnsupportedOperationException tolerated) { 63 } 64 expectUnchanged(); 65 } 66 67 @CollectionFeature.Require(SUPPORTS_ADD) 68 public void testAddAll_supportedNonePresent() { 69 assertTrue("addAll(nonePresent) should return true", 70 collection.addAll(createDisjointCollection())); 71 expectAdded(samples.e3, samples.e4); 72 } 73 74 @CollectionFeature.Require(absent = SUPPORTS_ADD) 75 public void testAddAll_unsupportedNonePresent() { 76 try { 77 collection.addAll(createDisjointCollection()); 78 fail("addAll(nonePresent) should throw"); 79 } catch (UnsupportedOperationException expected) { 80 } 81 expectUnchanged(); 82 expectMissing(samples.e3, samples.e4); 83 } 84 85 @CollectionFeature.Require(SUPPORTS_ADD) 86 @CollectionSize.Require(absent = ZERO) 87 public void testAddAll_supportedSomePresent() { 88 assertTrue("addAll(somePresent) should return true", 89 collection.addAll(MinimalCollection.of(samples.e3, samples.e0))); 90 assertTrue("should contain " + samples.e3, collection.contains(samples.e3)); 91 assertTrue("should contain " + samples.e0, collection.contains(samples.e0)); 92 } 93 94 @CollectionFeature.Require(absent = SUPPORTS_ADD) 95 @CollectionSize.Require(absent = ZERO) 96 public void testAddAll_unsupportedSomePresent() { 97 try { 98 collection.addAll(MinimalCollection.of(samples.e3, samples.e0)); 99 fail("addAll(somePresent) should throw"); 100 } catch (UnsupportedOperationException expected) { 101 } 102 expectUnchanged(); 103 } 104 105 @CollectionFeature.Require({SUPPORTS_ADD, 106 FAILS_FAST_ON_CONCURRENT_MODIFICATION}) 107 @CollectionSize.Require(absent = ZERO) 108 public void testAddAllConcurrentWithIteration() { 109 try { 110 Iterator<E> iterator = collection.iterator(); 111 assertTrue(collection.addAll(MinimalCollection.of(samples.e3, samples.e0))); 112 iterator.next(); 113 fail("Expected ConcurrentModificationException"); 114 } catch (ConcurrentModificationException expected) { 115 // success 116 } 117 } 118 119 @CollectionFeature.Require(absent = SUPPORTS_ADD) 120 @CollectionSize.Require(absent = ZERO) 121 public void testAddAll_unsupportedAllPresent() { 122 try { 123 assertFalse("addAll(allPresent) should return false or throw", 124 collection.addAll(MinimalCollection.of(samples.e0))); 125 } catch (UnsupportedOperationException tolerated) { 126 } 127 expectUnchanged(); 128 } 129 130 @CollectionFeature.Require(value = {SUPPORTS_ADD, 131 ALLOWS_NULL_VALUES}, absent = RESTRICTS_ELEMENTS) 132 public void testAddAll_nullSupported() { 133 List<E> containsNull = singletonList(null); 134 assertTrue("addAll(containsNull) should return true", collection 135 .addAll(containsNull)); 136 /* 137 * We need (E) to force interpretation of null as the single element of a 138 * varargs array, not the array itself 139 */ 140 expectAdded((E) null); 141 } 142 143 @CollectionFeature.Require(value = SUPPORTS_ADD, 144 absent = ALLOWS_NULL_VALUES) 145 public void testAddAll_nullUnsupported() { 146 List<E> containsNull = singletonList(null); 147 try { 148 collection.addAll(containsNull); 149 fail("addAll(containsNull) should throw"); 150 } catch (NullPointerException expected) { 151 } 152 expectUnchanged(); 153 expectNullMissingWhenNullUnsupported( 154 "Should not contain null after unsupported addAll(containsNull)"); 155 } 156 157 @CollectionFeature.Require(SUPPORTS_ADD) 158 public void testAddAll_nullCollectionReference() { 159 try { 160 collection.addAll(null); 161 fail("addAll(null) should throw NullPointerException"); 162 } catch (NullPointerException expected) { 163 } 164 } 165 166 /** 167 * Returns the {@link Method} instance for {@link 168 * #testAddAll_nullUnsupported()} so that tests can suppress it with {@code 169 * FeatureSpecificTestSuiteBuilder.suppressing()} until <a 170 * href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5045147">Sun 171 * bug 5045147</a> is fixed. 172 */ 173 @GwtIncompatible("reflection") 174 public static Method getAddAllNullUnsupportedMethod() { 175 return Helpers.getMethod(CollectionAddAllTester.class, "testAddAll_nullUnsupported"); 176 } 177 178 /** 179 * Returns the {@link Method} instance for {@link 180 * #testAddAll_unsupportedNonePresent()} so that tests can suppress it with 181 * {@code FeatureSpecificTestSuiteBuilder.suppressing()} while we figure out 182 * what to do with <a href="http://goo.gl/qJBruX">{@code ConcurrentHashMap} 183 * support for {@code entrySet().add()}</a>. 184 */ 185 @GwtIncompatible("reflection") 186 public static Method getAddAllUnsupportedNonePresentMethod() { 187 return Helpers.getMethod(CollectionAddAllTester.class, "testAddAll_unsupportedNonePresent"); 188 } 189 190 /** 191 * Returns the {@link Method} instance for {@link 192 * #testAddAll_unsupportedSomePresent()} so that tests can suppress it with 193 * {@code FeatureSpecificTestSuiteBuilder.suppressing()} while we figure out 194 * what to do with <a href="http://goo.gl/qJBruX">{@code ConcurrentHashMap} 195 * support for {@code entrySet().add()}</a>. 196 */ 197 @GwtIncompatible("reflection") 198 public static Method getAddAllUnsupportedSomePresentMethod() { 199 return Helpers.getMethod(CollectionAddAllTester.class, "testAddAll_unsupportedSomePresent"); 200 } 201 } 202