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