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.AbstractSet;
033import java.util.Collections;
034import java.util.ConcurrentModificationException;
035import java.util.Iterator;
036import org.junit.Ignore;
037
038/**
039 * A generic JUnit test which tests {@code removeAll} operations on a collection. Can't be invoked
040 * directly; please see {@link com.google.common.collect.testing.CollectionTestSuiteBuilder}.
041 *
042 * @author George van den Driessche
043 * @author Chris Povirk
044 */
045@SuppressWarnings("unchecked") // too many "unchecked generic array creations"
046@GwtCompatible
047@Ignore // Affects only Android test runner, which respects JUnit 4 annotations on JUnit 3 tests.
048public class CollectionRemoveAllTester<E> extends AbstractCollectionTester<E> {
049  @CollectionFeature.Require(SUPPORTS_REMOVE)
050  public void testRemoveAll_emptyCollection() {
051    assertFalse(
052        "removeAll(emptyCollection) should return false",
053        collection.removeAll(MinimalCollection.of()));
054    expectUnchanged();
055  }
056
057  @CollectionFeature.Require(SUPPORTS_REMOVE)
058  public void testRemoveAll_nonePresent() {
059    assertFalse(
060        "removeAll(disjointCollection) should return false",
061        collection.removeAll(MinimalCollection.of(e3())));
062    expectUnchanged();
063  }
064
065  @CollectionFeature.Require(SUPPORTS_REMOVE)
066  @CollectionSize.Require(absent = ZERO)
067  public void testRemoveAll_allPresent() {
068    assertTrue(
069        "removeAll(intersectingCollection) should return true",
070        collection.removeAll(MinimalCollection.of(e0())));
071    expectMissing(e0());
072  }
073
074  @CollectionFeature.Require(SUPPORTS_REMOVE)
075  @CollectionSize.Require(absent = ZERO)
076  public void testRemoveAll_somePresent() {
077    assertTrue(
078        "removeAll(intersectingCollection) should return true",
079        collection.removeAll(MinimalCollection.of(e0(), e3())));
080    expectMissing(e0());
081  }
082
083  @CollectionFeature.Require({SUPPORTS_REMOVE, FAILS_FAST_ON_CONCURRENT_MODIFICATION})
084  @CollectionSize.Require(SEVERAL)
085  public void testRemoveAllSomePresentConcurrentWithIteration() {
086    try {
087      Iterator<E> iterator = collection.iterator();
088      assertTrue(collection.removeAll(MinimalCollection.of(e0(), e3())));
089      iterator.next();
090      fail("Expected ConcurrentModificationException");
091    } catch (ConcurrentModificationException expected) {
092      // success
093    }
094  }
095
096  /** Trigger the {@code other.size() >= this.size()} case in {@link AbstractSet#removeAll}. */
097  @CollectionFeature.Require(SUPPORTS_REMOVE)
098  @CollectionSize.Require(absent = ZERO)
099  public void testRemoveAll_somePresentLargeCollectionToRemove() {
100    assertTrue(
101        "removeAll(largeIntersectingCollection) should return true",
102        collection.removeAll(MinimalCollection.of(e0(), e0(), e0(), e3(), e3(), e3())));
103    expectMissing(e0());
104  }
105
106  @CollectionFeature.Require(absent = SUPPORTS_REMOVE)
107  public void testRemoveAll_unsupportedEmptyCollection() {
108    try {
109      assertFalse(
110          "removeAll(emptyCollection) should return false or throw "
111              + "UnsupportedOperationException",
112          collection.removeAll(MinimalCollection.of()));
113    } catch (UnsupportedOperationException tolerated) {
114    }
115    expectUnchanged();
116  }
117
118  @CollectionFeature.Require(absent = SUPPORTS_REMOVE)
119  public void testRemoveAll_unsupportedNonePresent() {
120    try {
121      assertFalse(
122          "removeAll(disjointCollection) should return false or throw "
123              + "UnsupportedOperationException",
124          collection.removeAll(MinimalCollection.of(e3())));
125    } catch (UnsupportedOperationException tolerated) {
126    }
127    expectUnchanged();
128  }
129
130  @CollectionFeature.Require(absent = SUPPORTS_REMOVE)
131  @CollectionSize.Require(absent = ZERO)
132  public void testRemoveAll_unsupportedPresent() {
133    try {
134      collection.removeAll(MinimalCollection.of(e0()));
135      fail("removeAll(intersectingCollection) should throw UnsupportedOperationException");
136    } catch (UnsupportedOperationException expected) {
137    }
138    expectUnchanged();
139    assertTrue(collection.contains(e0()));
140  }
141
142  /*
143   * AbstractCollection fails the removeAll(null) test when the subject
144   * collection is empty, but we'd still like to test removeAll(null) when we
145   * can. We split the test into empty and non-empty cases. This allows us to
146   * suppress only the former.
147   */
148
149  @CollectionFeature.Require(SUPPORTS_REMOVE)
150  @CollectionSize.Require(ZERO)
151  public void testRemoveAll_nullCollectionReferenceEmptySubject() {
152    try {
153      collection.removeAll(null);
154      // Returning successfully is not ideal, but tolerated.
155    } catch (NullPointerException tolerated) {
156    }
157  }
158
159  @CollectionFeature.Require(SUPPORTS_REMOVE)
160  @CollectionSize.Require(absent = ZERO)
161  public void testRemoveAll_nullCollectionReferenceNonEmptySubject() {
162    try {
163      collection.removeAll(null);
164      fail("removeAll(null) should throw NullPointerException");
165    } catch (NullPointerException expected) {
166    }
167  }
168
169  @CollectionFeature.Require(value = SUPPORTS_REMOVE, absent = ALLOWS_NULL_QUERIES)
170  public void testRemoveAll_containsNullNo() {
171    MinimalCollection<?> containsNull = MinimalCollection.of((Object) null);
172    try {
173      assertFalse(
174          "removeAll(containsNull) should return false or throw",
175          collection.removeAll(containsNull));
176    } catch (NullPointerException tolerated) {
177    }
178    expectUnchanged();
179  }
180
181  @CollectionFeature.Require({SUPPORTS_REMOVE, ALLOWS_NULL_QUERIES})
182  public void testRemoveAll_containsNullNoButAllowed() {
183    MinimalCollection<?> containsNull = MinimalCollection.of((Object) null);
184    assertFalse("removeAll(containsNull) should return false", collection.removeAll(containsNull));
185    expectUnchanged();
186  }
187
188  @CollectionFeature.Require({SUPPORTS_REMOVE, ALLOWS_NULL_VALUES})
189  @CollectionSize.Require(absent = ZERO)
190  public void testRemoveAll_containsNullYes() {
191    initCollectionWithNullElement();
192    assertTrue(
193        "removeAll(containsNull) should return true",
194        collection.removeAll(Collections.singleton(null)));
195    // TODO: make this work with MinimalCollection
196  }
197
198  @CollectionFeature.Require(SUPPORTS_REMOVE)
199  public void testRemoveAll_containsWrongType() {
200    try {
201      assertFalse(
202          "removeAll(containsWrongType) should return false or throw",
203          collection.removeAll(MinimalCollection.of(WrongType.VALUE)));
204    } catch (ClassCastException tolerated) {
205    }
206    expectUnchanged();
207  }
208}