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 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.SUPPORTS_REMOVE; 21 import static com.google.common.collect.testing.features.CollectionSize.ONE; 22 import static com.google.common.collect.testing.features.CollectionSize.ZERO; 23 24 import com.google.common.annotations.GwtCompatible; 25 import com.google.common.collect.testing.AbstractCollectionTester; 26 import com.google.common.collect.testing.MinimalCollection; 27 import com.google.common.collect.testing.features.CollectionFeature; 28 import com.google.common.collect.testing.features.CollectionSize; 29 import java.util.Arrays; 30 import java.util.Collection; 31 import java.util.Collections; 32 import java.util.List; 33 import org.junit.Ignore; 34 35 /** 36 * A generic JUnit test which tests {@code retainAll} operations on a collection. Can't be invoked 37 * directly; please see {@link com.google.common.collect.testing.CollectionTestSuiteBuilder}. 38 * 39 * @author Chris Povirk 40 */ 41 @GwtCompatible 42 @Ignore // Affects only Android test runner, which respects JUnit 4 annotations on JUnit 3 tests. 43 @SuppressWarnings("JUnit4ClassUsedInJUnit3") 44 public class CollectionRetainAllTester<E> extends AbstractCollectionTester<E> { 45 46 /** A collection of elements to retain, along with a description for use in failure messages. */ 47 private class Target { 48 private final Collection<E> toRetain; 49 private final String description; 50 Target(Collection<E> toRetain, String description)51 private Target(Collection<E> toRetain, String description) { 52 this.toRetain = toRetain; 53 this.description = description; 54 } 55 56 @Override toString()57 public String toString() { 58 return description; 59 } 60 } 61 62 private Target empty; 63 private Target disjoint; 64 private Target superset; 65 private Target nonEmptyProperSubset; 66 private Target sameElements; 67 private Target partialOverlap; 68 private Target containsDuplicates; 69 private Target nullSingleton; 70 71 @Override setUp()72 public void setUp() throws Exception { 73 super.setUp(); 74 75 empty = new Target(emptyCollection(), "empty"); 76 /* 77 * We test that nullSingleton.retainAll(disjointList) does NOT throw a 78 * NullPointerException when disjointList does not, so we can't use 79 * MinimalCollection, which throws NullPointerException on calls to 80 * contains(null). 81 */ 82 List<E> disjointList = Arrays.asList(e3(), e4()); 83 disjoint = new Target(disjointList, "disjoint"); 84 superset = new Target(MinimalCollection.of(e0(), e1(), e2(), e3(), e4()), "superset"); 85 nonEmptyProperSubset = new Target(MinimalCollection.of(e1()), "subset"); 86 sameElements = new Target(Arrays.asList(createSamplesArray()), "sameElements"); 87 containsDuplicates = 88 new Target(MinimalCollection.of(e0(), e0(), e3(), e3()), "containsDuplicates"); 89 partialOverlap = new Target(MinimalCollection.of(e2(), e3()), "partialOverlap"); 90 nullSingleton = new Target(Collections.<E>singleton(null), "nullSingleton"); 91 } 92 93 // retainAll(empty) 94 95 @CollectionFeature.Require(SUPPORTS_REMOVE) 96 @CollectionSize.Require(ZERO) testRetainAll_emptyPreviouslyEmpty()97 public void testRetainAll_emptyPreviouslyEmpty() { 98 expectReturnsFalse(empty); 99 expectUnchanged(); 100 } 101 102 @CollectionFeature.Require(absent = SUPPORTS_REMOVE) 103 @CollectionSize.Require(ZERO) testRetainAll_emptyPreviouslyEmptyUnsupported()104 public void testRetainAll_emptyPreviouslyEmptyUnsupported() { 105 expectReturnsFalseOrThrows(empty); 106 expectUnchanged(); 107 } 108 109 @CollectionFeature.Require(SUPPORTS_REMOVE) 110 @CollectionSize.Require(absent = ZERO) testRetainAll_emptyPreviouslyNonEmpty()111 public void testRetainAll_emptyPreviouslyNonEmpty() { 112 expectReturnsTrue(empty); 113 expectContents(); 114 expectMissing(e0(), e1(), e2()); 115 } 116 117 @CollectionFeature.Require(absent = SUPPORTS_REMOVE) 118 @CollectionSize.Require(absent = ZERO) testRetainAll_emptyPreviouslyNonEmptyUnsupported()119 public void testRetainAll_emptyPreviouslyNonEmptyUnsupported() { 120 expectThrows(empty); 121 expectUnchanged(); 122 } 123 124 // retainAll(disjoint) 125 126 @CollectionFeature.Require(SUPPORTS_REMOVE) 127 @CollectionSize.Require(ZERO) testRetainAll_disjointPreviouslyEmpty()128 public void testRetainAll_disjointPreviouslyEmpty() { 129 expectReturnsFalse(disjoint); 130 expectUnchanged(); 131 } 132 133 @CollectionFeature.Require(absent = SUPPORTS_REMOVE) 134 @CollectionSize.Require(ZERO) testRetainAll_disjointPreviouslyEmptyUnsupported()135 public void testRetainAll_disjointPreviouslyEmptyUnsupported() { 136 expectReturnsFalseOrThrows(disjoint); 137 expectUnchanged(); 138 } 139 140 @CollectionFeature.Require(SUPPORTS_REMOVE) 141 @CollectionSize.Require(absent = ZERO) testRetainAll_disjointPreviouslyNonEmpty()142 public void testRetainAll_disjointPreviouslyNonEmpty() { 143 expectReturnsTrue(disjoint); 144 expectContents(); 145 expectMissing(e0(), e1(), e2()); 146 } 147 148 @CollectionFeature.Require(absent = SUPPORTS_REMOVE) 149 @CollectionSize.Require(absent = ZERO) testRetainAll_disjointPreviouslyNonEmptyUnsupported()150 public void testRetainAll_disjointPreviouslyNonEmptyUnsupported() { 151 expectThrows(disjoint); 152 expectUnchanged(); 153 } 154 155 // retainAll(superset) 156 157 @CollectionFeature.Require(SUPPORTS_REMOVE) testRetainAll_superset()158 public void testRetainAll_superset() { 159 expectReturnsFalse(superset); 160 expectUnchanged(); 161 } 162 163 @CollectionFeature.Require(absent = SUPPORTS_REMOVE) testRetainAll_supersetUnsupported()164 public void testRetainAll_supersetUnsupported() { 165 expectReturnsFalseOrThrows(superset); 166 expectUnchanged(); 167 } 168 169 // retainAll(subset) 170 171 @CollectionFeature.Require(SUPPORTS_REMOVE) 172 @CollectionSize.Require(absent = {ZERO, ONE}) testRetainAll_subset()173 public void testRetainAll_subset() { 174 expectReturnsTrue(nonEmptyProperSubset); 175 expectContents(nonEmptyProperSubset.toRetain); 176 } 177 178 @CollectionFeature.Require(absent = SUPPORTS_REMOVE) 179 @CollectionSize.Require(absent = {ZERO, ONE}) testRetainAll_subsetUnsupported()180 public void testRetainAll_subsetUnsupported() { 181 expectThrows(nonEmptyProperSubset); 182 expectUnchanged(); 183 } 184 185 // retainAll(sameElements) 186 187 @CollectionFeature.Require(SUPPORTS_REMOVE) testRetainAll_sameElements()188 public void testRetainAll_sameElements() { 189 expectReturnsFalse(sameElements); 190 expectUnchanged(); 191 } 192 193 @CollectionFeature.Require(absent = SUPPORTS_REMOVE) testRetainAll_sameElementsUnsupported()194 public void testRetainAll_sameElementsUnsupported() { 195 expectReturnsFalseOrThrows(sameElements); 196 expectUnchanged(); 197 } 198 199 // retainAll(partialOverlap) 200 201 @CollectionFeature.Require(SUPPORTS_REMOVE) 202 @CollectionSize.Require(absent = {ZERO, ONE}) testRetainAll_partialOverlap()203 public void testRetainAll_partialOverlap() { 204 expectReturnsTrue(partialOverlap); 205 expectContents(e2()); 206 } 207 208 @CollectionFeature.Require(absent = SUPPORTS_REMOVE) 209 @CollectionSize.Require(absent = {ZERO, ONE}) testRetainAll_partialOverlapUnsupported()210 public void testRetainAll_partialOverlapUnsupported() { 211 expectThrows(partialOverlap); 212 expectUnchanged(); 213 } 214 215 // retainAll(containsDuplicates) 216 217 @CollectionFeature.Require(SUPPORTS_REMOVE) 218 @CollectionSize.Require(ONE) testRetainAll_containsDuplicatesSizeOne()219 public void testRetainAll_containsDuplicatesSizeOne() { 220 expectReturnsFalse(containsDuplicates); 221 expectContents(e0()); 222 } 223 224 @CollectionFeature.Require(SUPPORTS_REMOVE) 225 @CollectionSize.Require(absent = {ZERO, ONE}) testRetainAll_containsDuplicatesSizeSeveral()226 public void testRetainAll_containsDuplicatesSizeSeveral() { 227 expectReturnsTrue(containsDuplicates); 228 expectContents(e0()); 229 } 230 231 // retainAll(nullSingleton) 232 233 @CollectionFeature.Require(SUPPORTS_REMOVE) 234 @CollectionSize.Require(ZERO) testRetainAll_nullSingletonPreviouslyEmpty()235 public void testRetainAll_nullSingletonPreviouslyEmpty() { 236 expectReturnsFalse(nullSingleton); 237 expectUnchanged(); 238 } 239 240 @CollectionFeature.Require(SUPPORTS_REMOVE) 241 @CollectionSize.Require(absent = ZERO) testRetainAll_nullSingletonPreviouslyNonEmpty()242 public void testRetainAll_nullSingletonPreviouslyNonEmpty() { 243 expectReturnsTrue(nullSingleton); 244 expectContents(); 245 } 246 247 @CollectionFeature.Require({SUPPORTS_REMOVE, ALLOWS_NULL_VALUES}) 248 @CollectionSize.Require(ONE) testRetainAll_nullSingletonPreviouslySingletonWithNull()249 public void testRetainAll_nullSingletonPreviouslySingletonWithNull() { 250 initCollectionWithNullElement(); 251 expectReturnsFalse(nullSingleton); 252 expectContents(createArrayWithNullElement()); 253 } 254 255 @CollectionFeature.Require({SUPPORTS_REMOVE, ALLOWS_NULL_VALUES}) 256 @CollectionSize.Require(absent = {ZERO, ONE}) testRetainAll_nullSingletonPreviouslySeveralWithNull()257 public void testRetainAll_nullSingletonPreviouslySeveralWithNull() { 258 initCollectionWithNullElement(); 259 expectReturnsTrue(nullSingleton); 260 expectContents(nullSingleton.toRetain); 261 } 262 263 // nullSingleton.retainAll() 264 265 @CollectionFeature.Require({SUPPORTS_REMOVE, ALLOWS_NULL_VALUES}) 266 @CollectionSize.Require(absent = ZERO) testRetainAll_containsNonNullWithNull()267 public void testRetainAll_containsNonNullWithNull() { 268 initCollectionWithNullElement(); 269 expectReturnsTrue(disjoint); 270 expectContents(); 271 } 272 273 // retainAll(null) 274 275 /* 276 * AbstractCollection fails the retainAll(null) test when the subject 277 * collection is empty, but we'd still like to test retainAll(null) when we 278 * can. We split the test into empty and non-empty cases. This allows us to 279 * suppress only the former. 280 */ 281 282 @CollectionFeature.Require(SUPPORTS_REMOVE) 283 @CollectionSize.Require(ZERO) testRetainAll_nullCollectionReferenceEmptySubject()284 public void testRetainAll_nullCollectionReferenceEmptySubject() { 285 try { 286 collection.retainAll(null); 287 // Returning successfully is not ideal, but tolerated. 288 } catch (NullPointerException tolerated) { 289 } 290 } 291 292 @CollectionFeature.Require(SUPPORTS_REMOVE) 293 @CollectionSize.Require(absent = ZERO) testRetainAll_nullCollectionReferenceNonEmptySubject()294 public void testRetainAll_nullCollectionReferenceNonEmptySubject() { 295 try { 296 collection.retainAll(null); 297 fail("retainAll(null) should throw NullPointerException"); 298 } catch (NullPointerException expected) { 299 } 300 } 301 expectReturnsTrue(Target target)302 private void expectReturnsTrue(Target target) { 303 String message = Platform.format("retainAll(%s) should return true", target); 304 assertTrue(message, collection.retainAll(target.toRetain)); 305 } 306 expectReturnsFalse(Target target)307 private void expectReturnsFalse(Target target) { 308 String message = Platform.format("retainAll(%s) should return false", target); 309 assertFalse(message, collection.retainAll(target.toRetain)); 310 } 311 expectThrows(Target target)312 private void expectThrows(Target target) { 313 try { 314 collection.retainAll(target.toRetain); 315 String message = Platform.format("retainAll(%s) should throw", target); 316 fail(message); 317 } catch (UnsupportedOperationException expected) { 318 } 319 } 320 expectReturnsFalseOrThrows(Target target)321 private void expectReturnsFalseOrThrows(Target target) { 322 String message = Platform.format("retainAll(%s) should return false or throw", target); 323 try { 324 assertFalse(message, collection.retainAll(target.toRetain)); 325 } catch (UnsupportedOperationException tolerated) { 326 } 327 } 328 } 329