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