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