Home | History | Annotate | Download | only in testing
      1 /*
      2  * Copyright (C) 2009 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;
     18 
     19 import com.google.common.collect.testing.features.CollectionFeature;
     20 import com.google.common.collect.testing.features.CollectionSize;
     21 import com.google.common.collect.testing.features.SetFeature;
     22 
     23 import junit.framework.Test;
     24 import junit.framework.TestSuite;
     25 
     26 import java.io.Serializable;
     27 import java.lang.reflect.Method;
     28 import java.util.AbstractSet;
     29 import java.util.Collection;
     30 import java.util.Collections;
     31 import java.util.Comparator;
     32 import java.util.EnumSet;
     33 import java.util.HashSet;
     34 import java.util.Iterator;
     35 import java.util.LinkedHashSet;
     36 import java.util.Set;
     37 import java.util.SortedSet;
     38 import java.util.TreeSet;
     39 import java.util.concurrent.ConcurrentSkipListSet;
     40 import java.util.concurrent.CopyOnWriteArraySet;
     41 
     42 /**
     43  * Generates a test suite covering the {@link Set} implementations in the
     44  * {@link java.util} package. Can be subclassed to specify tests that should
     45  * be suppressed.
     46  *
     47  * @author Kevin Bourrillion
     48  */
     49 public class TestsForSetsInJavaUtil {
     50   public static Test suite() {
     51     return new TestsForSetsInJavaUtil().allTests();
     52   }
     53 
     54   public Test allTests() {
     55     TestSuite suite = new TestSuite("java.util Sets");
     56     suite.addTest(testsForEmptySet());
     57     suite.addTest(testsForSingletonSet());
     58     suite.addTest(testsForHashSet());
     59     suite.addTest(testsForLinkedHashSet());
     60     suite.addTest(testsForEnumSet());
     61     suite.addTest(testsForTreeSetNatural());
     62     suite.addTest(testsForTreeSetWithComparator());
     63     suite.addTest(testsForCopyOnWriteArraySet());
     64     suite.addTest(testsForUnmodifiableSet());
     65     suite.addTest(testsForCheckedSet());
     66     suite.addTest(testsForAbstractSet());
     67     suite.addTest(testsForBadlyCollidingHashSet());
     68     suite.addTest(testsForConcurrentSkipListSetNatural());
     69     suite.addTest(testsForConcurrentSkipListSetWithComparator());
     70 
     71     return suite;
     72   }
     73 
     74   protected Collection<Method> suppressForEmptySet() {
     75     return Collections.emptySet();
     76   }
     77   protected Collection<Method> suppressForSingletonSet() {
     78     return Collections.emptySet();
     79   }
     80   protected Collection<Method> suppressForHashSet() {
     81     return Collections.emptySet();
     82   }
     83   protected Collection<Method> suppressForLinkedHashSet() {
     84     return Collections.emptySet();
     85   }
     86   protected Collection<Method> suppressForEnumSet() {
     87     return Collections.emptySet();
     88   }
     89   protected Collection<Method> suppressForTreeSetNatural() {
     90     return Collections.emptySet();
     91   }
     92   protected Collection<Method> suppressForTreeSetWithComparator() {
     93     return Collections.emptySet();
     94   }
     95   protected Collection<Method> suppressForCopyOnWriteArraySet() {
     96     return Collections.emptySet();
     97   }
     98   protected Collection<Method> suppressForUnmodifiableSet() {
     99     return Collections.emptySet();
    100   }
    101   protected Collection<Method> suppressForCheckedSet() {
    102     return Collections.emptySet();
    103   }
    104   protected Collection<Method> suppressForAbstractSet() {
    105     return Collections.emptySet();
    106   }
    107   protected Collection<Method> suppressForConcurrentSkipListSetNatural() {
    108     return Collections.emptySet();
    109   }
    110   protected Collection<Method> suppressForConcurrentSkipListSetWithComparator() {
    111     return Collections.emptySet();
    112   }
    113 
    114   public Test testsForEmptySet() {
    115     return SetTestSuiteBuilder
    116         .using(new TestStringSetGenerator() {
    117             @Override public Set<String> create(String[] elements) {
    118               return Collections.emptySet();
    119             }
    120           })
    121         .named("emptySet")
    122         .withFeatures(
    123             CollectionFeature.SERIALIZABLE,
    124             CollectionSize.ZERO)
    125         .suppressing(suppressForEmptySet())
    126         .createTestSuite();
    127   }
    128 
    129   public Test testsForSingletonSet() {
    130     return SetTestSuiteBuilder
    131         .using(new TestStringSetGenerator() {
    132             @Override public Set<String> create(String[] elements) {
    133               return Collections.singleton(elements[0]);
    134             }
    135           })
    136         .named("singleton")
    137         .withFeatures(
    138             CollectionFeature.SERIALIZABLE,
    139             CollectionFeature.ALLOWS_NULL_VALUES,
    140             CollectionSize.ONE)
    141         .suppressing(suppressForSingletonSet())
    142         .createTestSuite();
    143   }
    144 
    145   public Test testsForHashSet() {
    146     return SetTestSuiteBuilder
    147         .using(new TestStringSetGenerator() {
    148             @Override public Set<String> create(String[] elements) {
    149               return new HashSet<String>(MinimalCollection.of(elements));
    150             }
    151           })
    152         .named("HashSet")
    153         .withFeatures(
    154             SetFeature.GENERAL_PURPOSE,
    155             CollectionFeature.SERIALIZABLE,
    156             CollectionFeature.ALLOWS_NULL_VALUES,
    157             CollectionFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION,
    158             CollectionSize.ANY)
    159         .suppressing(suppressForHashSet())
    160         .createTestSuite();
    161   }
    162 
    163   public Test testsForLinkedHashSet() {
    164     return SetTestSuiteBuilder
    165         .using(new TestStringSetGenerator() {
    166             @Override public Set<String> create(String[] elements) {
    167               return new LinkedHashSet<String>(MinimalCollection.of(elements));
    168             }
    169           })
    170         .named("LinkedHashSet")
    171         .withFeatures(
    172             SetFeature.GENERAL_PURPOSE,
    173             CollectionFeature.SERIALIZABLE,
    174             CollectionFeature.ALLOWS_NULL_VALUES,
    175             CollectionFeature.KNOWN_ORDER,
    176             CollectionFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION,
    177             CollectionSize.ANY)
    178         .suppressing(suppressForLinkedHashSet())
    179         .createTestSuite();
    180   }
    181 
    182   public Test testsForEnumSet() {
    183     return SetTestSuiteBuilder
    184         .using(new TestEnumSetGenerator() {
    185             @Override public Set<AnEnum> create(AnEnum[] elements) {
    186               return (elements.length == 0)
    187                   ? EnumSet.noneOf(AnEnum.class)
    188                   : EnumSet.copyOf(MinimalCollection.of(elements));
    189             }
    190           })
    191         .named("EnumSet")
    192         .withFeatures(
    193             SetFeature.GENERAL_PURPOSE,
    194             CollectionFeature.SERIALIZABLE,
    195             CollectionFeature.KNOWN_ORDER,
    196             CollectionFeature.RESTRICTS_ELEMENTS,
    197             CollectionSize.ANY)
    198         .suppressing(suppressForEnumSet())
    199         .createTestSuite();
    200   }
    201 
    202   public Test testsForTreeSetNatural() {
    203     return NavigableSetTestSuiteBuilder
    204         .using(new TestStringSortedSetGenerator() {
    205             @Override public SortedSet<String> create(String[] elements) {
    206               return new TreeSet<String>(MinimalCollection.of(elements));
    207             }
    208           })
    209         .named("TreeSet, natural")
    210         .withFeatures(
    211             SetFeature.GENERAL_PURPOSE,
    212             CollectionFeature.SERIALIZABLE,
    213             CollectionFeature.KNOWN_ORDER,
    214             CollectionFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION,
    215             CollectionSize.ANY)
    216         .suppressing(suppressForTreeSetNatural())
    217         .createTestSuite();
    218   }
    219 
    220   public Test testsForTreeSetWithComparator() {
    221     return NavigableSetTestSuiteBuilder
    222         .using(new TestStringSortedSetGenerator() {
    223             @Override public SortedSet<String> create(String[] elements) {
    224               SortedSet<String> set
    225                   = new TreeSet<String>(arbitraryNullFriendlyComparator());
    226               Collections.addAll(set, elements);
    227               return set;
    228             }
    229           })
    230         .named("TreeSet, with comparator")
    231         .withFeatures(
    232             SetFeature.GENERAL_PURPOSE,
    233             CollectionFeature.SERIALIZABLE,
    234             CollectionFeature.ALLOWS_NULL_VALUES,
    235             CollectionFeature.KNOWN_ORDER,
    236             CollectionFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION,
    237             CollectionSize.ANY)
    238         .suppressing(suppressForTreeSetWithComparator())
    239         .createTestSuite();
    240   }
    241 
    242   public Test testsForCopyOnWriteArraySet() {
    243     return SetTestSuiteBuilder
    244         .using(new TestStringSetGenerator() {
    245             @Override public Set<String> create(String[] elements) {
    246               return new CopyOnWriteArraySet<String>(
    247                   MinimalCollection.of(elements));
    248             }
    249           })
    250         .named("CopyOnWriteArraySet")
    251         .withFeatures(
    252             CollectionFeature.SUPPORTS_ADD,
    253             CollectionFeature.SUPPORTS_REMOVE,
    254             CollectionFeature.SERIALIZABLE,
    255             CollectionFeature.ALLOWS_NULL_VALUES,
    256             CollectionFeature.KNOWN_ORDER,
    257             CollectionSize.ANY)
    258         .suppressing(suppressForCopyOnWriteArraySet())
    259         .createTestSuite();
    260   }
    261 
    262   public Test testsForUnmodifiableSet() {
    263     return SetTestSuiteBuilder
    264         .using(new TestStringSetGenerator() {
    265             @Override public Set<String> create(String[] elements) {
    266               Set<String> innerSet = new HashSet<String>();
    267               Collections.addAll(innerSet, elements);
    268               return Collections.unmodifiableSet(innerSet);
    269             }
    270           })
    271         .named("unmodifiableSet/HashSet")
    272         .withFeatures(
    273             CollectionFeature.NONE,
    274             CollectionFeature.SERIALIZABLE,
    275             CollectionFeature.ALLOWS_NULL_VALUES,
    276             CollectionSize.ANY)
    277         .suppressing(suppressForUnmodifiableSet())
    278         .createTestSuite();
    279   }
    280 
    281   public Test testsForCheckedSet() {
    282     return SetTestSuiteBuilder
    283         .using(new TestStringSetGenerator() {
    284             @Override public Set<String> create(String[] elements) {
    285               Set<String> innerSet = new HashSet<String>();
    286               Collections.addAll(innerSet, elements);
    287               return Collections.checkedSet(innerSet, String.class);
    288             }
    289           })
    290         .named("checkedSet/HashSet")
    291         .withFeatures(
    292             SetFeature.GENERAL_PURPOSE,
    293             CollectionFeature.SERIALIZABLE,
    294             CollectionFeature.ALLOWS_NULL_VALUES,
    295             CollectionFeature.RESTRICTS_ELEMENTS,
    296             CollectionSize.ANY)
    297         .suppressing(suppressForCheckedSet())
    298         .createTestSuite();
    299   }
    300 
    301   public Test testsForAbstractSet() {
    302     return SetTestSuiteBuilder
    303         .using(new TestStringSetGenerator () {
    304             @Override protected Set<String> create(String[] elements) {
    305               final String[] deduped = dedupe(elements);
    306               return new AbstractSet<String>() {
    307                 @Override public int size() {
    308                   return deduped.length;
    309                 }
    310                 @Override public Iterator<String> iterator() {
    311                   return MinimalCollection.of(deduped).iterator();
    312                 }
    313               };
    314             }
    315           })
    316         .named("AbstractSet")
    317         .withFeatures(
    318             CollectionFeature.NONE,
    319             CollectionFeature.ALLOWS_NULL_VALUES,
    320             CollectionFeature.KNOWN_ORDER, // in this case, anyway
    321             CollectionSize.ANY)
    322         .suppressing(suppressForAbstractSet())
    323         .createTestSuite();
    324   }
    325 
    326   public Test testsForBadlyCollidingHashSet() {
    327     return SetTestSuiteBuilder
    328         .using(new TestCollidingSetGenerator() {
    329             @Override
    330             public Set<Object> create(Object... elements) {
    331               return new HashSet<Object>(MinimalCollection.of(elements));
    332             }
    333           })
    334         .named("badly colliding HashSet")
    335         .withFeatures(
    336             SetFeature.GENERAL_PURPOSE,
    337             CollectionFeature.ALLOWS_NULL_VALUES,
    338             CollectionSize.SEVERAL)
    339         .suppressing(suppressForHashSet())
    340         .createTestSuite();
    341   }
    342 
    343   public Test testsForConcurrentSkipListSetNatural() {
    344     return SetTestSuiteBuilder
    345         .using(new TestStringSortedSetGenerator() {
    346             @Override public SortedSet<String> create(String[] elements) {
    347               return new ConcurrentSkipListSet<String>(MinimalCollection.of(elements));
    348             }
    349           })
    350         .named("ConcurrentSkipListSet, natural")
    351         .withFeatures(
    352             SetFeature.GENERAL_PURPOSE,
    353             CollectionFeature.SERIALIZABLE,
    354             CollectionFeature.KNOWN_ORDER,
    355             CollectionSize.ANY)
    356         .suppressing(suppressForConcurrentSkipListSetNatural())
    357         .createTestSuite();
    358   }
    359 
    360   public Test testsForConcurrentSkipListSetWithComparator() {
    361     return SetTestSuiteBuilder
    362         .using(new TestStringSortedSetGenerator() {
    363             @Override public SortedSet<String> create(String[] elements) {
    364               SortedSet<String> set
    365                   = new ConcurrentSkipListSet<String>(arbitraryNullFriendlyComparator());
    366               Collections.addAll(set, elements);
    367               return set;
    368             }
    369           })
    370         .named("ConcurrentSkipListSet, with comparator")
    371         .withFeatures(
    372             SetFeature.GENERAL_PURPOSE,
    373             CollectionFeature.SERIALIZABLE,
    374             CollectionFeature.KNOWN_ORDER,
    375             CollectionSize.ANY)
    376         .suppressing(suppressForConcurrentSkipListSetWithComparator())
    377         .createTestSuite();
    378   }
    379 
    380   private static String[] dedupe(String[] elements) {
    381     Set<String> tmp = new LinkedHashSet<String>();
    382     Collections.addAll(tmp, elements);
    383     return tmp.toArray(new String[0]);
    384   }
    385 
    386   static <T> Comparator<T> arbitraryNullFriendlyComparator() {
    387     return new NullFriendlyComparator<T>();
    388   }
    389 
    390   private static final class NullFriendlyComparator<T>
    391       implements Comparator<T>, Serializable {
    392     @Override
    393     public int compare(T left, T right) {
    394       return String.valueOf(left).compareTo(String.valueOf(right));
    395     }
    396   }
    397 }
    398