Home | History | Annotate | Download | only in testers
      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_RETAIN_ALL;
     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.collect.testing.AbstractCollectionTester;
     25 import com.google.common.collect.testing.MinimalCollection;
     26 import com.google.common.collect.testing.features.CollectionFeature;
     27 import com.google.common.collect.testing.features.CollectionSize;
     28 
     29 import java.util.Arrays;
     30 import java.util.Collection;
     31 import java.util.Collections;
     32 import java.util.List;
     33 
     34 /**
     35  * A generic JUnit test which tests {@code retainAll} operations on a
     36  * collection. Can't be invoked directly; please see
     37  * {@link com.google.common.collect.testing.CollectionTestSuiteBuilder}.
     38  *
     39  * <p>This class is GWT compatible.
     40  *
     41  * @author Chris Povirk
     42  */
     43 @SuppressWarnings("unchecked") // too many "unchecked generic array creations"
     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 
     54     private Target(Collection<E> toRetain, String description) {
     55       this.toRetain = toRetain;
     56       this.description = description;
     57     }
     58 
     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 
     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_RETAIN_ALL)
    107   @CollectionSize.Require(ZERO)
    108   public void testRetainAll_emptyPreviouslyEmpty() {
    109     expectReturnsFalse(empty);
    110     expectUnchanged();
    111   }
    112 
    113   @CollectionFeature.Require(absent = SUPPORTS_RETAIN_ALL)
    114   @CollectionSize.Require(ZERO)
    115   public void testRetainAll_emptyPreviouslyEmptyUnsupported() {
    116     expectReturnsFalseOrThrows(empty);
    117     expectUnchanged();
    118   }
    119 
    120   @CollectionFeature.Require(SUPPORTS_RETAIN_ALL)
    121   @CollectionSize.Require(absent = ZERO)
    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_RETAIN_ALL)
    129   @CollectionSize.Require(absent = ZERO)
    130   public void testRetainAll_emptyPreviouslyNonEmptyUnsupported() {
    131     expectThrows(empty);
    132     expectUnchanged();
    133   }
    134 
    135   // retainAll(disjoint)
    136 
    137   @CollectionFeature.Require(SUPPORTS_RETAIN_ALL)
    138   @CollectionSize.Require(ZERO)
    139   public void testRetainAll_disjointPreviouslyEmpty() {
    140     expectReturnsFalse(disjoint);
    141     expectUnchanged();
    142   }
    143 
    144   @CollectionFeature.Require(absent = SUPPORTS_RETAIN_ALL)
    145   @CollectionSize.Require(ZERO)
    146   public void testRetainAll_disjointPreviouslyEmptyUnsupported() {
    147     expectReturnsFalseOrThrows(disjoint);
    148     expectUnchanged();
    149   }
    150 
    151   @CollectionFeature.Require(SUPPORTS_RETAIN_ALL)
    152   @CollectionSize.Require(absent = ZERO)
    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_RETAIN_ALL)
    160   @CollectionSize.Require(absent = ZERO)
    161   public void testRetainAll_disjointPreviouslyNonEmptyUnsupported() {
    162     expectThrows(disjoint);
    163     expectUnchanged();
    164   }
    165 
    166   // retainAll(superset)
    167 
    168   @CollectionFeature.Require(SUPPORTS_RETAIN_ALL)
    169   public void testRetainAll_superset() {
    170     expectReturnsFalse(superset);
    171     expectUnchanged();
    172   }
    173 
    174   @CollectionFeature.Require(absent = SUPPORTS_RETAIN_ALL)
    175   public void testRetainAll_supersetUnsupported() {
    176     expectReturnsFalseOrThrows(superset);
    177     expectUnchanged();
    178   }
    179 
    180   // retainAll(subset)
    181 
    182   @CollectionFeature.Require(SUPPORTS_RETAIN_ALL)
    183   @CollectionSize.Require(absent = {ZERO, ONE})
    184   public void testRetainAll_subset() {
    185     expectReturnsTrue(nonEmptyProperSubset);
    186     expectContents(nonEmptyProperSubset.toRetain);
    187   }
    188 
    189   @CollectionFeature.Require(absent = SUPPORTS_RETAIN_ALL)
    190   @CollectionSize.Require(absent = {ZERO, ONE})
    191   public void testRetainAll_subsetUnsupported() {
    192     expectThrows(nonEmptyProperSubset);
    193     expectUnchanged();
    194   }
    195 
    196   // retainAll(sameElements)
    197 
    198   @CollectionFeature.Require(SUPPORTS_RETAIN_ALL)
    199   public void testRetainAll_sameElements() {
    200     expectReturnsFalse(sameElements);
    201     expectUnchanged();
    202   }
    203 
    204   @CollectionFeature.Require(absent = SUPPORTS_RETAIN_ALL)
    205   public void testRetainAll_sameElementsUnsupported() {
    206     expectReturnsFalseOrThrows(sameElements);
    207     expectUnchanged();
    208   }
    209 
    210   // retainAll(partialOverlap)
    211 
    212   @CollectionFeature.Require(SUPPORTS_RETAIN_ALL)
    213   @CollectionSize.Require(absent = {ZERO, ONE})
    214   public void testRetainAll_partialOverlap() {
    215     expectReturnsTrue(partialOverlap);
    216     expectContents(samples.e2);
    217   }
    218 
    219   @CollectionFeature.Require(absent = SUPPORTS_RETAIN_ALL)
    220   @CollectionSize.Require(absent = {ZERO, ONE})
    221   public void testRetainAll_partialOverlapUnsupported() {
    222     expectThrows(partialOverlap);
    223     expectUnchanged();
    224   }
    225 
    226   // retainAll(containsDuplicates)
    227 
    228   @CollectionFeature.Require(SUPPORTS_RETAIN_ALL)
    229   @CollectionSize.Require(ONE)
    230   public void testRetainAll_containsDuplicatesSizeOne() {
    231     expectReturnsFalse(containsDuplicates);
    232     expectContents(samples.e0);
    233   }
    234 
    235   @CollectionFeature.Require(SUPPORTS_RETAIN_ALL)
    236   @CollectionSize.Require(absent = {ZERO, ONE})
    237   public void testRetainAll_containsDuplicatesSizeSeveral() {
    238     expectReturnsTrue(containsDuplicates);
    239     expectContents(samples.e0);
    240   }
    241 
    242   // retainAll(nullSingleton)
    243 
    244   @CollectionFeature.Require(SUPPORTS_RETAIN_ALL)
    245   @CollectionSize.Require(ZERO)
    246   public void testRetainAll_nullSingletonPreviouslyEmpty() {
    247     expectReturnsFalse(nullSingleton);
    248     expectUnchanged();
    249   }
    250 
    251   @CollectionFeature.Require(SUPPORTS_RETAIN_ALL)
    252   @CollectionSize.Require(absent = ZERO)
    253   public void testRetainAll_nullSingletonPreviouslyNonEmpty() {
    254     expectReturnsTrue(nullSingleton);
    255     expectContents();
    256   }
    257 
    258   @CollectionFeature.Require({SUPPORTS_RETAIN_ALL, ALLOWS_NULL_VALUES})
    259   @CollectionSize.Require(ONE)
    260   public void testRetainAll_nullSingletonPreviouslySingletonWithNull() {
    261     initCollectionWithNullElement();
    262     expectReturnsFalse(nullSingleton);
    263     expectContents(createArrayWithNullElement());
    264   }
    265 
    266   @CollectionFeature.Require({SUPPORTS_RETAIN_ALL, ALLOWS_NULL_VALUES})
    267   @CollectionSize.Require(absent = {ZERO, ONE})
    268   public void testRetainAll_nullSingletonPreviouslySeveralWithNull() {
    269     initCollectionWithNullElement();
    270     expectReturnsTrue(nullSingleton);
    271     expectContents(nullSingleton.toRetain);
    272   }
    273 
    274   // nullSingleton.retainAll()
    275 
    276   @CollectionFeature.Require({SUPPORTS_RETAIN_ALL, ALLOWS_NULL_VALUES})
    277   @CollectionSize.Require(absent = ZERO)
    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_RETAIN_ALL)
    294   @CollectionSize.Require(ZERO)
    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_RETAIN_ALL)
    304   @CollectionSize.Require(absent = ZERO)
    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 
    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 
    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 
    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 
    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