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