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.collect.testing.features.CollectionFeature; 20 import com.google.common.collect.testing.features.CollectionSize; 21 import com.google.common.collect.testing.features.SetFeature; 22 23 import junit.framework.Test; 24 import junit.framework.TestSuite; 25 26 import java.lang.reflect.Method; 27 import java.util.AbstractSet; 28 import java.util.Collection; 29 import java.util.Collections; 30 import java.util.Comparator; 31 import java.util.EnumSet; 32 import java.util.HashSet; 33 import java.util.Iterator; 34 import java.util.LinkedHashSet; 35 import java.util.Set; 36 import java.util.SortedSet; 37 import java.util.TreeSet; 38 import 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 */ 47 public class TestsForSetsInJavaUtil { suite()48 public static Test suite() { 49 return new TestsForSetsInJavaUtil().allTests(); 50 } 51 allTests()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 suppressForEmptySet()70 protected Collection<Method> suppressForEmptySet() { 71 return Collections.emptySet(); 72 } suppressForSingletonSet()73 protected Collection<Method> suppressForSingletonSet() { 74 return Collections.emptySet(); 75 } suppressForHashSet()76 protected Collection<Method> suppressForHashSet() { 77 return Collections.emptySet(); 78 } suppressForLinkedHashSet()79 protected Collection<Method> suppressForLinkedHashSet() { 80 return Collections.emptySet(); 81 } suppressForEnumSet()82 protected Collection<Method> suppressForEnumSet() { 83 return Collections.emptySet(); 84 } suppressForTreeSetNatural()85 protected Collection<Method> suppressForTreeSetNatural() { 86 return Collections.emptySet(); 87 } suppressForTreeSetWithComparator()88 protected Collection<Method> suppressForTreeSetWithComparator() { 89 return Collections.emptySet(); 90 } suppressForCopyOnWriteArraySet()91 protected Collection<Method> suppressForCopyOnWriteArraySet() { 92 return Collections.emptySet(); 93 } suppressForUnmodifiableSet()94 protected Collection<Method> suppressForUnmodifiableSet() { 95 return Collections.emptySet(); 96 } suppressForCheckedSet()97 protected Collection<Method> suppressForCheckedSet() { 98 return Collections.emptySet(); 99 } suppressForAbstractSet()100 protected Collection<Method> suppressForAbstractSet() { 101 return Collections.emptySet(); 102 } 103 testsForEmptySet()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