CollectionRemoveAllTester.java revision 0888a09821a98ac0680fad765217302858e70fa4
1/*
2 * Copyright (C) 2008 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
17package com.google.common.collect.testing.testers;
18
19import static com.google.common.collect.testing.features.CollectionFeature.ALLOWS_NULL_QUERIES;
20import static com.google.common.collect.testing.features.CollectionFeature.ALLOWS_NULL_VALUES;
21import static com.google.common.collect.testing.features.CollectionFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION;
22import static com.google.common.collect.testing.features.CollectionFeature.SUPPORTS_REMOVE;
23import static com.google.common.collect.testing.features.CollectionSize.SEVERAL;
24import static com.google.common.collect.testing.features.CollectionSize.ZERO;
25
26import com.google.common.annotations.GwtCompatible;
27import com.google.common.collect.testing.AbstractCollectionTester;
28import com.google.common.collect.testing.MinimalCollection;
29import com.google.common.collect.testing.WrongType;
30import com.google.common.collect.testing.features.CollectionFeature;
31import com.google.common.collect.testing.features.CollectionSize;
32
33import java.util.Collections;
34import java.util.ConcurrentModificationException;
35import java.util.Iterator;
36
37/**
38 * A generic JUnit test which tests {@code removeAll} operations on a
39 * collection. Can't be invoked directly; please see
40 * {@link com.google.common.collect.testing.CollectionTestSuiteBuilder}.
41 *
42 * @author George van den Driessche
43 * @author Chris Povirk
44 */
45@SuppressWarnings("unchecked") // too many "unchecked generic array creations"
46@GwtCompatible
47public class CollectionRemoveAllTester<E> extends AbstractCollectionTester<E> {
48  @CollectionFeature.Require(SUPPORTS_REMOVE)
49  public void testRemoveAll_emptyCollection() {
50    assertFalse("removeAll(emptyCollection) should return false",
51        collection.removeAll(MinimalCollection.of()));
52    expectUnchanged();
53  }
54
55  @CollectionFeature.Require(SUPPORTS_REMOVE)
56  public void testRemoveAll_nonePresent() {
57    assertFalse("removeAll(disjointCollection) should return false",
58        collection.removeAll(MinimalCollection.of(samples.e3)));
59    expectUnchanged();
60  }
61
62  @CollectionFeature.Require(SUPPORTS_REMOVE)
63  @CollectionSize.Require(absent = ZERO)
64  public void testRemoveAll_allPresent() {
65    assertTrue("removeAll(intersectingCollection) should return true",
66        collection.removeAll(MinimalCollection.of(samples.e0)));
67    expectMissing(samples.e0);
68  }
69
70  @CollectionFeature.Require(SUPPORTS_REMOVE)
71  @CollectionSize.Require(absent = ZERO)
72  public void testRemoveAll_somePresent() {
73    assertTrue("removeAll(intersectingCollection) should return true",
74        collection.removeAll(MinimalCollection.of(samples.e0, samples.e3)));
75    expectMissing(samples.e0);
76  }
77
78  @CollectionFeature.Require({SUPPORTS_REMOVE,
79      FAILS_FAST_ON_CONCURRENT_MODIFICATION})
80  @CollectionSize.Require(SEVERAL)
81  public void testRemoveAllSomePresentConcurrentWithIteration() {
82    try {
83      Iterator<E> iterator = collection.iterator();
84      assertTrue(collection.removeAll(MinimalCollection.of(samples.e0, samples.e3)));
85      iterator.next();
86      fail("Expected ConcurrentModificationException");
87    } catch (ConcurrentModificationException expected) {
88      // success
89    }
90  }
91
92  /**
93   * Trigger the other.size() >= this.size() case in AbstractSet.removeAll().
94   */
95  @CollectionFeature.Require(SUPPORTS_REMOVE)
96  @CollectionSize.Require(absent = ZERO)
97  public void testRemoveAll_somePresentLargeCollectionToRemove() {
98    assertTrue("removeAll(largeIntersectingCollection) should return true",
99        collection.removeAll(MinimalCollection.of(
100            samples.e0, samples.e0, samples.e0,
101            samples.e3, samples.e3, samples.e3)));
102    expectMissing(samples.e0);
103  }
104
105  @CollectionFeature.Require(absent = SUPPORTS_REMOVE)
106  public void testRemoveAll_unsupportedEmptyCollection() {
107    try {
108      assertFalse("removeAll(emptyCollection) should return false or throw "
109          + "UnsupportedOperationException",
110        collection.removeAll(MinimalCollection.of()));
111    } catch (UnsupportedOperationException tolerated) {
112    }
113    expectUnchanged();
114  }
115
116  @CollectionFeature.Require(absent = SUPPORTS_REMOVE)
117  public void testRemoveAll_unsupportedNonePresent() {
118    try {
119      assertFalse("removeAll(disjointCollection) should return false or throw "
120          + "UnsupportedOperationException",
121        collection.removeAll(MinimalCollection.of(samples.e3)));
122    } catch (UnsupportedOperationException tolerated) {
123    }
124    expectUnchanged();
125  }
126
127  @CollectionFeature.Require(absent = SUPPORTS_REMOVE)
128  @CollectionSize.Require(absent = ZERO)
129  public void testRemoveAll_unsupportedPresent() {
130    try {
131      collection.removeAll(MinimalCollection.of(samples.e0));
132      fail("removeAll(intersectingCollection) should throw "
133          + "UnsupportedOperationException");
134    } catch (UnsupportedOperationException expected) {
135    }
136    expectUnchanged();
137    assertTrue(collection.contains(samples.e0));
138  }
139
140  /*
141   * AbstractCollection fails the removeAll(null) test when the subject
142   * collection is empty, but we'd still like to test removeAll(null) when we
143   * can. We split the test into empty and non-empty cases. This allows us to
144   * suppress only the former.
145   */
146
147  @CollectionFeature.Require(SUPPORTS_REMOVE)
148  @CollectionSize.Require(ZERO)
149  public void testRemoveAll_nullCollectionReferenceEmptySubject() {
150    try {
151      collection.removeAll(null);
152      // Returning successfully is not ideal, but tolerated.
153    } catch (NullPointerException expected) {
154    }
155  }
156
157  @CollectionFeature.Require(SUPPORTS_REMOVE)
158  @CollectionSize.Require(absent = ZERO)
159  public void testRemoveAll_nullCollectionReferenceNonEmptySubject() {
160    try {
161      collection.removeAll(null);
162      fail("removeAll(null) should throw NullPointerException");
163    } catch (NullPointerException expected) {
164    }
165  }
166
167  @CollectionFeature.Require(value = SUPPORTS_REMOVE,
168      absent = ALLOWS_NULL_QUERIES)
169  public void testRemoveAll_containsNullNo() {
170    MinimalCollection<?> containsNull = MinimalCollection.of((Object) null);
171    try {
172      assertFalse("removeAll(containsNull) should return false or throw",
173          collection.removeAll(containsNull));
174    } catch (NullPointerException tolerated) {
175    }
176    expectUnchanged();
177  }
178
179  @CollectionFeature.Require({SUPPORTS_REMOVE, ALLOWS_NULL_QUERIES})
180  public void testRemoveAll_containsNullNoButAllowed() {
181    MinimalCollection<?> containsNull = MinimalCollection.of((Object) null);
182    assertFalse("removeAll(containsNull) should return false",
183        collection.removeAll(containsNull));
184    expectUnchanged();
185  }
186
187  @CollectionFeature.Require({SUPPORTS_REMOVE, ALLOWS_NULL_VALUES})
188  @CollectionSize.Require(absent = ZERO)
189  public void testRemoveAll_containsNullYes() {
190    initCollectionWithNullElement();
191    assertTrue("removeAll(containsNull) should return true",
192        collection.removeAll(Collections.singleton(null)));
193    // TODO: make this work with MinimalCollection
194  }
195
196  @CollectionFeature.Require(SUPPORTS_REMOVE)
197  public void testRemoveAll_containsWrongType() {
198    try {
199      assertFalse("removeAll(containsWrongType) should return false or throw",
200          collection.removeAll(MinimalCollection.of(WrongType.VALUE)));
201    } catch (ClassCastException tolerated) {
202    }
203    expectUnchanged();
204  }
205}
206