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 {
suite()49   public static Test suite() {
50     return new TestsForSetsInJavaUtil().allTests();
51   }
52 
allTests()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 
suppressForEmptySet()71   protected Collection<Method> suppressForEmptySet() {
72     return Collections.emptySet();
73   }
suppressForSingletonSet()74   protected Collection<Method> suppressForSingletonSet() {
75     return Collections.emptySet();
76   }
suppressForHashSet()77   protected Collection<Method> suppressForHashSet() {
78     return Collections.emptySet();
79   }
suppressForLinkedHashSet()80   protected Collection<Method> suppressForLinkedHashSet() {
81     return Collections.emptySet();
82   }
suppressForEnumSet()83   protected Collection<Method> suppressForEnumSet() {
84     return Collections.emptySet();
85   }
suppressForTreeSetNatural()86   protected Collection<Method> suppressForTreeSetNatural() {
87     return Collections.emptySet();
88   }
suppressForTreeSetWithComparator()89   protected Collection<Method> suppressForTreeSetWithComparator() {
90     return Collections.emptySet();
91   }
suppressForCopyOnWriteArraySet()92   protected Collection<Method> suppressForCopyOnWriteArraySet() {
93     return Collections.emptySet();
94   }
suppressForUnmodifiableSet()95   protected Collection<Method> suppressForUnmodifiableSet() {
96     return Collections.emptySet();
97   }
suppressForCheckedSet()98   protected Collection<Method> suppressForCheckedSet() {
99     return Collections.emptySet();
100   }
suppressForAbstractSet()101   protected Collection<Method> suppressForAbstractSet() {
102     return Collections.emptySet();
103   }
suppressForConcurrentSkipListSetNatural()104   protected Collection<Method> suppressForConcurrentSkipListSetNatural() {
105     return Collections.emptySet();
106   }
suppressForConcurrentSkipListSetWithComparator()107   protected Collection<Method> suppressForConcurrentSkipListSetWithComparator() {
108     return Collections.emptySet();
109   }
110 
testsForEmptySet()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