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