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