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