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_VALUES; 020import static com.google.common.collect.testing.features.CollectionFeature.SUPPORTS_REMOVE; 021import static com.google.common.collect.testing.features.CollectionSize.ONE; 022import static com.google.common.collect.testing.features.CollectionSize.ZERO; 023 024import com.google.common.annotations.GwtCompatible; 025import com.google.common.collect.testing.AbstractCollectionTester; 026import com.google.common.collect.testing.MinimalCollection; 027import com.google.common.collect.testing.features.CollectionFeature; 028import com.google.common.collect.testing.features.CollectionSize; 029import java.util.Arrays; 030import java.util.Collection; 031import java.util.Collections; 032import java.util.List; 033import org.junit.Ignore; 034 035/** 036 * A generic JUnit test which tests {@code retainAll} operations on a collection. Can't be invoked 037 * directly; please see {@link com.google.common.collect.testing.CollectionTestSuiteBuilder}. 038 * 039 * @author Chris Povirk 040 */ 041@SuppressWarnings("unchecked") // too many "unchecked generic array creations" 042@GwtCompatible 043@Ignore // Affects only Android test runner, which respects JUnit 4 annotations on JUnit 3 tests. 044public class CollectionRetainAllTester<E> extends AbstractCollectionTester<E> { 045 046 /** A collection of elements to retain, along with a description for use in failure messages. */ 047 private class Target { 048 private final Collection<E> toRetain; 049 private final String description; 050 051 private Target(Collection<E> toRetain, String description) { 052 this.toRetain = toRetain; 053 this.description = description; 054 } 055 056 @Override 057 public String toString() { 058 return description; 059 } 060 } 061 062 private Target empty; 063 private Target disjoint; 064 private Target superset; 065 private Target nonEmptyProperSubset; 066 private Target sameElements; 067 private Target partialOverlap; 068 private Target containsDuplicates; 069 private Target nullSingleton; 070 071 @Override 072 public void setUp() throws Exception { 073 super.setUp(); 074 075 empty = new Target(emptyCollection(), "empty"); 076 /* 077 * We test that nullSingleton.retainAll(disjointList) does NOT throw a 078 * NullPointerException when disjointList does not, so we can't use 079 * MinimalCollection, which throws NullPointerException on calls to 080 * contains(null). 081 */ 082 List<E> disjointList = Arrays.asList(e3(), e4()); 083 disjoint = new Target(disjointList, "disjoint"); 084 superset = new Target(MinimalCollection.of(e0(), e1(), e2(), e3(), e4()), "superset"); 085 nonEmptyProperSubset = new Target(MinimalCollection.of(e1()), "subset"); 086 sameElements = new Target(Arrays.asList(createSamplesArray()), "sameElements"); 087 containsDuplicates = 088 new Target(MinimalCollection.of(e0(), e0(), e3(), e3()), "containsDuplicates"); 089 partialOverlap = new Target(MinimalCollection.of(e2(), e3()), "partialOverlap"); 090 nullSingleton = new Target(Collections.<E>singleton(null), "nullSingleton"); 091 } 092 093 // retainAll(empty) 094 095 @CollectionFeature.Require(SUPPORTS_REMOVE) 096 @CollectionSize.Require(ZERO) 097 public void testRetainAll_emptyPreviouslyEmpty() { 098 expectReturnsFalse(empty); 099 expectUnchanged(); 100 } 101 102 @CollectionFeature.Require(absent = SUPPORTS_REMOVE) 103 @CollectionSize.Require(ZERO) 104 public void testRetainAll_emptyPreviouslyEmptyUnsupported() { 105 expectReturnsFalseOrThrows(empty); 106 expectUnchanged(); 107 } 108 109 @CollectionFeature.Require(SUPPORTS_REMOVE) 110 @CollectionSize.Require(absent = ZERO) 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) 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) 128 public void testRetainAll_disjointPreviouslyEmpty() { 129 expectReturnsFalse(disjoint); 130 expectUnchanged(); 131 } 132 133 @CollectionFeature.Require(absent = SUPPORTS_REMOVE) 134 @CollectionSize.Require(ZERO) 135 public void testRetainAll_disjointPreviouslyEmptyUnsupported() { 136 expectReturnsFalseOrThrows(disjoint); 137 expectUnchanged(); 138 } 139 140 @CollectionFeature.Require(SUPPORTS_REMOVE) 141 @CollectionSize.Require(absent = ZERO) 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) 150 public void testRetainAll_disjointPreviouslyNonEmptyUnsupported() { 151 expectThrows(disjoint); 152 expectUnchanged(); 153 } 154 155 // retainAll(superset) 156 157 @CollectionFeature.Require(SUPPORTS_REMOVE) 158 public void testRetainAll_superset() { 159 expectReturnsFalse(superset); 160 expectUnchanged(); 161 } 162 163 @CollectionFeature.Require(absent = SUPPORTS_REMOVE) 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}) 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}) 180 public void testRetainAll_subsetUnsupported() { 181 expectThrows(nonEmptyProperSubset); 182 expectUnchanged(); 183 } 184 185 // retainAll(sameElements) 186 187 @CollectionFeature.Require(SUPPORTS_REMOVE) 188 public void testRetainAll_sameElements() { 189 expectReturnsFalse(sameElements); 190 expectUnchanged(); 191 } 192 193 @CollectionFeature.Require(absent = SUPPORTS_REMOVE) 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}) 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}) 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) 219 public void testRetainAll_containsDuplicatesSizeOne() { 220 expectReturnsFalse(containsDuplicates); 221 expectContents(e0()); 222 } 223 224 @CollectionFeature.Require(SUPPORTS_REMOVE) 225 @CollectionSize.Require(absent = {ZERO, ONE}) 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) 235 public void testRetainAll_nullSingletonPreviouslyEmpty() { 236 expectReturnsFalse(nullSingleton); 237 expectUnchanged(); 238 } 239 240 @CollectionFeature.Require(SUPPORTS_REMOVE) 241 @CollectionSize.Require(absent = ZERO) 242 public void testRetainAll_nullSingletonPreviouslyNonEmpty() { 243 expectReturnsTrue(nullSingleton); 244 expectContents(); 245 } 246 247 @CollectionFeature.Require({SUPPORTS_REMOVE, ALLOWS_NULL_VALUES}) 248 @CollectionSize.Require(ONE) 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}) 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) 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) 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) 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 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 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 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 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}