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@GwtCompatible 042@Ignore // Affects only Android test runner, which respects JUnit 4 annotations on JUnit 3 tests. 043public class CollectionRetainAllTester<E> extends AbstractCollectionTester<E> { 044 045 /** A collection of elements to retain, along with a description for use in failure messages. */ 046 private class Target { 047 private final Collection<E> toRetain; 048 private final String description; 049 050 private Target(Collection<E> toRetain, String description) { 051 this.toRetain = toRetain; 052 this.description = description; 053 } 054 055 @Override 056 public String toString() { 057 return description; 058 } 059 } 060 061 private Target empty; 062 private Target disjoint; 063 private Target superset; 064 private Target nonEmptyProperSubset; 065 private Target sameElements; 066 private Target partialOverlap; 067 private Target containsDuplicates; 068 private Target nullSingleton; 069 070 @Override 071 public void setUp() throws Exception { 072 super.setUp(); 073 074 empty = new Target(emptyCollection(), "empty"); 075 /* 076 * We test that nullSingleton.retainAll(disjointList) does NOT throw a 077 * NullPointerException when disjointList does not, so we can't use 078 * MinimalCollection, which throws NullPointerException on calls to 079 * contains(null). 080 */ 081 List<E> disjointList = Arrays.asList(e3(), e4()); 082 disjoint = new Target(disjointList, "disjoint"); 083 superset = new Target(MinimalCollection.of(e0(), e1(), e2(), e3(), e4()), "superset"); 084 nonEmptyProperSubset = new Target(MinimalCollection.of(e1()), "subset"); 085 sameElements = new Target(Arrays.asList(createSamplesArray()), "sameElements"); 086 containsDuplicates = 087 new Target(MinimalCollection.of(e0(), e0(), e3(), e3()), "containsDuplicates"); 088 partialOverlap = new Target(MinimalCollection.of(e2(), e3()), "partialOverlap"); 089 nullSingleton = new Target(Collections.<E>singleton(null), "nullSingleton"); 090 } 091 092 // retainAll(empty) 093 094 @CollectionFeature.Require(SUPPORTS_REMOVE) 095 @CollectionSize.Require(ZERO) 096 public void testRetainAll_emptyPreviouslyEmpty() { 097 expectReturnsFalse(empty); 098 expectUnchanged(); 099 } 100 101 @CollectionFeature.Require(absent = SUPPORTS_REMOVE) 102 @CollectionSize.Require(ZERO) 103 public void testRetainAll_emptyPreviouslyEmptyUnsupported() { 104 expectReturnsFalseOrThrows(empty); 105 expectUnchanged(); 106 } 107 108 @CollectionFeature.Require(SUPPORTS_REMOVE) 109 @CollectionSize.Require(absent = ZERO) 110 public void testRetainAll_emptyPreviouslyNonEmpty() { 111 expectReturnsTrue(empty); 112 expectContents(); 113 expectMissing(e0(), e1(), e2()); 114 } 115 116 @CollectionFeature.Require(absent = SUPPORTS_REMOVE) 117 @CollectionSize.Require(absent = ZERO) 118 public void testRetainAll_emptyPreviouslyNonEmptyUnsupported() { 119 expectThrows(empty); 120 expectUnchanged(); 121 } 122 123 // retainAll(disjoint) 124 125 @CollectionFeature.Require(SUPPORTS_REMOVE) 126 @CollectionSize.Require(ZERO) 127 public void testRetainAll_disjointPreviouslyEmpty() { 128 expectReturnsFalse(disjoint); 129 expectUnchanged(); 130 } 131 132 @CollectionFeature.Require(absent = SUPPORTS_REMOVE) 133 @CollectionSize.Require(ZERO) 134 public void testRetainAll_disjointPreviouslyEmptyUnsupported() { 135 expectReturnsFalseOrThrows(disjoint); 136 expectUnchanged(); 137 } 138 139 @CollectionFeature.Require(SUPPORTS_REMOVE) 140 @CollectionSize.Require(absent = ZERO) 141 public void testRetainAll_disjointPreviouslyNonEmpty() { 142 expectReturnsTrue(disjoint); 143 expectContents(); 144 expectMissing(e0(), e1(), e2()); 145 } 146 147 @CollectionFeature.Require(absent = SUPPORTS_REMOVE) 148 @CollectionSize.Require(absent = ZERO) 149 public void testRetainAll_disjointPreviouslyNonEmptyUnsupported() { 150 expectThrows(disjoint); 151 expectUnchanged(); 152 } 153 154 // retainAll(superset) 155 156 @CollectionFeature.Require(SUPPORTS_REMOVE) 157 public void testRetainAll_superset() { 158 expectReturnsFalse(superset); 159 expectUnchanged(); 160 } 161 162 @CollectionFeature.Require(absent = SUPPORTS_REMOVE) 163 public void testRetainAll_supersetUnsupported() { 164 expectReturnsFalseOrThrows(superset); 165 expectUnchanged(); 166 } 167 168 // retainAll(subset) 169 170 @CollectionFeature.Require(SUPPORTS_REMOVE) 171 @CollectionSize.Require(absent = {ZERO, ONE}) 172 public void testRetainAll_subset() { 173 expectReturnsTrue(nonEmptyProperSubset); 174 expectContents(nonEmptyProperSubset.toRetain); 175 } 176 177 @CollectionFeature.Require(absent = SUPPORTS_REMOVE) 178 @CollectionSize.Require(absent = {ZERO, ONE}) 179 public void testRetainAll_subsetUnsupported() { 180 expectThrows(nonEmptyProperSubset); 181 expectUnchanged(); 182 } 183 184 // retainAll(sameElements) 185 186 @CollectionFeature.Require(SUPPORTS_REMOVE) 187 public void testRetainAll_sameElements() { 188 expectReturnsFalse(sameElements); 189 expectUnchanged(); 190 } 191 192 @CollectionFeature.Require(absent = SUPPORTS_REMOVE) 193 public void testRetainAll_sameElementsUnsupported() { 194 expectReturnsFalseOrThrows(sameElements); 195 expectUnchanged(); 196 } 197 198 // retainAll(partialOverlap) 199 200 @CollectionFeature.Require(SUPPORTS_REMOVE) 201 @CollectionSize.Require(absent = {ZERO, ONE}) 202 public void testRetainAll_partialOverlap() { 203 expectReturnsTrue(partialOverlap); 204 expectContents(e2()); 205 } 206 207 @CollectionFeature.Require(absent = SUPPORTS_REMOVE) 208 @CollectionSize.Require(absent = {ZERO, ONE}) 209 public void testRetainAll_partialOverlapUnsupported() { 210 expectThrows(partialOverlap); 211 expectUnchanged(); 212 } 213 214 // retainAll(containsDuplicates) 215 216 @CollectionFeature.Require(SUPPORTS_REMOVE) 217 @CollectionSize.Require(ONE) 218 public void testRetainAll_containsDuplicatesSizeOne() { 219 expectReturnsFalse(containsDuplicates); 220 expectContents(e0()); 221 } 222 223 @CollectionFeature.Require(SUPPORTS_REMOVE) 224 @CollectionSize.Require(absent = {ZERO, ONE}) 225 public void testRetainAll_containsDuplicatesSizeSeveral() { 226 expectReturnsTrue(containsDuplicates); 227 expectContents(e0()); 228 } 229 230 // retainAll(nullSingleton) 231 232 @CollectionFeature.Require(SUPPORTS_REMOVE) 233 @CollectionSize.Require(ZERO) 234 public void testRetainAll_nullSingletonPreviouslyEmpty() { 235 expectReturnsFalse(nullSingleton); 236 expectUnchanged(); 237 } 238 239 @CollectionFeature.Require(SUPPORTS_REMOVE) 240 @CollectionSize.Require(absent = ZERO) 241 public void testRetainAll_nullSingletonPreviouslyNonEmpty() { 242 expectReturnsTrue(nullSingleton); 243 expectContents(); 244 } 245 246 @CollectionFeature.Require({SUPPORTS_REMOVE, ALLOWS_NULL_VALUES}) 247 @CollectionSize.Require(ONE) 248 public void testRetainAll_nullSingletonPreviouslySingletonWithNull() { 249 initCollectionWithNullElement(); 250 expectReturnsFalse(nullSingleton); 251 expectContents(createArrayWithNullElement()); 252 } 253 254 @CollectionFeature.Require({SUPPORTS_REMOVE, ALLOWS_NULL_VALUES}) 255 @CollectionSize.Require(absent = {ZERO, ONE}) 256 public void testRetainAll_nullSingletonPreviouslySeveralWithNull() { 257 initCollectionWithNullElement(); 258 expectReturnsTrue(nullSingleton); 259 expectContents(nullSingleton.toRetain); 260 } 261 262 // nullSingleton.retainAll() 263 264 @CollectionFeature.Require({SUPPORTS_REMOVE, ALLOWS_NULL_VALUES}) 265 @CollectionSize.Require(absent = ZERO) 266 public void testRetainAll_containsNonNullWithNull() { 267 initCollectionWithNullElement(); 268 expectReturnsTrue(disjoint); 269 expectContents(); 270 } 271 272 // retainAll(null) 273 274 /* 275 * AbstractCollection fails the retainAll(null) test when the subject 276 * collection is empty, but we'd still like to test retainAll(null) when we 277 * can. We split the test into empty and non-empty cases. This allows us to 278 * suppress only the former. 279 */ 280 281 @CollectionFeature.Require(SUPPORTS_REMOVE) 282 @CollectionSize.Require(ZERO) 283 public void testRetainAll_nullCollectionReferenceEmptySubject() { 284 try { 285 collection.retainAll(null); 286 // Returning successfully is not ideal, but tolerated. 287 } catch (NullPointerException tolerated) { 288 } 289 } 290 291 @CollectionFeature.Require(SUPPORTS_REMOVE) 292 @CollectionSize.Require(absent = ZERO) 293 public void testRetainAll_nullCollectionReferenceNonEmptySubject() { 294 try { 295 collection.retainAll(null); 296 fail("retainAll(null) should throw NullPointerException"); 297 } catch (NullPointerException expected) { 298 } 299 } 300 301 private void expectReturnsTrue(Target target) { 302 String message = Platform.format("retainAll(%s) should return true", target); 303 assertTrue(message, collection.retainAll(target.toRetain)); 304 } 305 306 private void expectReturnsFalse(Target target) { 307 String message = Platform.format("retainAll(%s) should return false", target); 308 assertFalse(message, collection.retainAll(target.toRetain)); 309 } 310 311 private void expectThrows(Target target) { 312 try { 313 collection.retainAll(target.toRetain); 314 String message = Platform.format("retainAll(%s) should throw", target); 315 fail(message); 316 } catch (UnsupportedOperationException expected) { 317 } 318 } 319 320 private void expectReturnsFalseOrThrows(Target target) { 321 String message = Platform.format("retainAll(%s) should return false or throw", target); 322 try { 323 assertFalse(message, collection.retainAll(target.toRetain)); 324 } catch (UnsupportedOperationException tolerated) { 325 } 326 } 327}