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