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