001/*
002 * Copyright (C) 2008 The Guava Authors
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package com.google.common.collect.testing.testers;
018
019import static com.google.common.collect.testing.features.CollectionFeature.ALLOWS_NULL_QUERIES;
020import static com.google.common.collect.testing.features.CollectionFeature.ALLOWS_NULL_VALUES;
021import static com.google.common.collect.testing.features.CollectionFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION;
022import static com.google.common.collect.testing.features.CollectionFeature.SUPPORTS_REMOVE;
023import static com.google.common.collect.testing.features.CollectionSize.SEVERAL;
024import static com.google.common.collect.testing.features.CollectionSize.ZERO;
025
026import com.google.common.annotations.GwtCompatible;
027import com.google.common.collect.testing.AbstractCollectionTester;
028import com.google.common.collect.testing.MinimalCollection;
029import com.google.common.collect.testing.WrongType;
030import com.google.common.collect.testing.features.CollectionFeature;
031import com.google.common.collect.testing.features.CollectionSize;
032import java.util.Collections;
033import java.util.ConcurrentModificationException;
034import java.util.Iterator;
035import org.junit.Ignore;
036
037/**
038 * A generic JUnit test which tests {@code removeAll} operations on a collection. Can't be invoked
039 * directly; please see {@link com.google.common.collect.testing.CollectionTestSuiteBuilder}.
040 *
041 * @author George van den Driessche
042 * @author Chris Povirk
043 */
044@SuppressWarnings("unchecked") // too many "unchecked generic array creations"
045@GwtCompatible
046@Ignore // Affects only Android test runner, which respects JUnit 4 annotations on JUnit 3 tests.
047public class CollectionRemoveAllTester<E> extends AbstractCollectionTester<E> {
048  @CollectionFeature.Require(SUPPORTS_REMOVE)
049  public void testRemoveAll_emptyCollection() {
050    assertFalse(
051        "removeAll(emptyCollection) should return false",
052        collection.removeAll(MinimalCollection.of()));
053    expectUnchanged();
054  }
055
056  @CollectionFeature.Require(SUPPORTS_REMOVE)
057  public void testRemoveAll_nonePresent() {
058    assertFalse(
059        "removeAll(disjointCollection) should return false",
060        collection.removeAll(MinimalCollection.of(e3())));
061    expectUnchanged();
062  }
063
064  @CollectionFeature.Require(SUPPORTS_REMOVE)
065  @CollectionSize.Require(absent = ZERO)
066  public void testRemoveAll_allPresent() {
067    assertTrue(
068        "removeAll(intersectingCollection) should return true",
069        collection.removeAll(MinimalCollection.of(e0())));
070    expectMissing(e0());
071  }
072
073  @CollectionFeature.Require(SUPPORTS_REMOVE)
074  @CollectionSize.Require(absent = ZERO)
075  public void testRemoveAll_somePresent() {
076    assertTrue(
077        "removeAll(intersectingCollection) should return true",
078        collection.removeAll(MinimalCollection.of(e0(), e3())));
079    expectMissing(e0());
080  }
081
082  @CollectionFeature.Require({SUPPORTS_REMOVE, FAILS_FAST_ON_CONCURRENT_MODIFICATION})
083  @CollectionSize.Require(SEVERAL)
084  public void testRemoveAllSomePresentConcurrentWithIteration() {
085    try {
086      Iterator<E> iterator = collection.iterator();
087      assertTrue(collection.removeAll(MinimalCollection.of(e0(), e3())));
088      iterator.next();
089      fail("Expected ConcurrentModificationException");
090    } catch (ConcurrentModificationException expected) {
091      // success
092    }
093  }
094
095  /** Trigger the {@code other.size() >= this.size()} case in {@link AbstractSet#removeAll()}. */
096  @CollectionFeature.Require(SUPPORTS_REMOVE)
097  @CollectionSize.Require(absent = ZERO)
098  public void testRemoveAll_somePresentLargeCollectionToRemove() {
099    assertTrue(
100        "removeAll(largeIntersectingCollection) should return true",
101        collection.removeAll(MinimalCollection.of(e0(), e0(), e0(), e3(), e3(), e3())));
102    expectMissing(e0());
103  }
104
105  @CollectionFeature.Require(absent = SUPPORTS_REMOVE)
106  public void testRemoveAll_unsupportedEmptyCollection() {
107    try {
108      assertFalse(
109          "removeAll(emptyCollection) should return false or throw "
110              + "UnsupportedOperationException",
111          collection.removeAll(MinimalCollection.of()));
112    } catch (UnsupportedOperationException tolerated) {
113    }
114    expectUnchanged();
115  }
116
117  @CollectionFeature.Require(absent = SUPPORTS_REMOVE)
118  public void testRemoveAll_unsupportedNonePresent() {
119    try {
120      assertFalse(
121          "removeAll(disjointCollection) should return false or throw "
122              + "UnsupportedOperationException",
123          collection.removeAll(MinimalCollection.of(e3())));
124    } catch (UnsupportedOperationException tolerated) {
125    }
126    expectUnchanged();
127  }
128
129  @CollectionFeature.Require(absent = SUPPORTS_REMOVE)
130  @CollectionSize.Require(absent = ZERO)
131  public void testRemoveAll_unsupportedPresent() {
132    try {
133      collection.removeAll(MinimalCollection.of(e0()));
134      fail("removeAll(intersectingCollection) should throw UnsupportedOperationException");
135    } catch (UnsupportedOperationException expected) {
136    }
137    expectUnchanged();
138    assertTrue(collection.contains(e0()));
139  }
140
141  /*
142   * AbstractCollection fails the removeAll(null) test when the subject
143   * collection is empty, but we'd still like to test removeAll(null) when we
144   * can. We split the test into empty and non-empty cases. This allows us to
145   * suppress only the former.
146   */
147
148  @CollectionFeature.Require(SUPPORTS_REMOVE)
149  @CollectionSize.Require(ZERO)
150  public void testRemoveAll_nullCollectionReferenceEmptySubject() {
151    try {
152      collection.removeAll(null);
153      // Returning successfully is not ideal, but tolerated.
154    } catch (NullPointerException tolerated) {
155    }
156  }
157
158  @CollectionFeature.Require(SUPPORTS_REMOVE)
159  @CollectionSize.Require(absent = ZERO)
160  public void testRemoveAll_nullCollectionReferenceNonEmptySubject() {
161    try {
162      collection.removeAll(null);
163      fail("removeAll(null) should throw NullPointerException");
164    } catch (NullPointerException expected) {
165    }
166  }
167
168  @CollectionFeature.Require(value = SUPPORTS_REMOVE, absent = ALLOWS_NULL_QUERIES)
169  public void testRemoveAll_containsNullNo() {
170    MinimalCollection<?> containsNull = MinimalCollection.of((Object) null);
171    try {
172      assertFalse(
173          "removeAll(containsNull) should return false or throw",
174          collection.removeAll(containsNull));
175    } catch (NullPointerException tolerated) {
176    }
177    expectUnchanged();
178  }
179
180  @CollectionFeature.Require({SUPPORTS_REMOVE, ALLOWS_NULL_QUERIES})
181  public void testRemoveAll_containsNullNoButAllowed() {
182    MinimalCollection<?> containsNull = MinimalCollection.of((Object) null);
183    assertFalse("removeAll(containsNull) should return false", 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(
192        "removeAll(containsNull) should return true",
193        collection.removeAll(Collections.singleton(null)));
194    // TODO: make this work with MinimalCollection
195  }
196
197  @CollectionFeature.Require(SUPPORTS_REMOVE)
198  public void testRemoveAll_containsWrongType() {
199    try {
200      assertFalse(
201          "removeAll(containsWrongType) should return false or throw",
202          collection.removeAll(MinimalCollection.of(WrongType.VALUE)));
203    } catch (ClassCastException tolerated) {
204    }
205    expectUnchanged();
206  }
207}