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