1 /* 2 * Copyright (C) 2008 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.CollectionSize; 20 import com.google.common.collect.testing.features.Feature; 21 import com.google.common.collect.testing.features.FeatureUtil; 22 23 import junit.framework.TestSuite; 24 25 import java.lang.reflect.Method; 26 import java.util.ArrayList; 27 import java.util.Arrays; 28 import java.util.List; 29 import java.util.Set; 30 import java.util.logging.Logger; 31 32 /** 33 * This builder creates a composite test suite, containing a separate test suite 34 * for each {@link CollectionSize} present in the features specified 35 * by {@link #withFeatures(Feature...)}. 36 * 37 * @param <B> The concrete type of this builder (the 'self-type'). All the 38 * Builder methods of this class (such as {@link #named(String)}) return this 39 * type, so that Builder methods of more derived classes can be chained onto 40 * them without casting. 41 * @param <G> The type of the generator to be passed to testers in the 42 * generated test suite. An instance of G should somehow provide an 43 * instance of the class under test, plus any other information required 44 * to parameterize the test. 45 * 46 * @see FeatureSpecificTestSuiteBuilder 47 * 48 * @author George van den Driessche 49 */ 50 public abstract class PerCollectionSizeTestSuiteBuilder< 51 B extends PerCollectionSizeTestSuiteBuilder<B, G, T, E>, 52 G extends TestContainerGenerator<T, E>, 53 T, 54 E> 55 extends FeatureSpecificTestSuiteBuilder<B, G> { 56 private static final Logger logger = Logger.getLogger( 57 PerCollectionSizeTestSuiteBuilder.class.getName()); 58 59 /** 60 * Creates a runnable JUnit test suite based on the criteria already given. 61 */ 62 @Override public TestSuite createTestSuite() { 63 checkCanCreate(); 64 65 String name = getName(); 66 // Copy this set, so we can modify it. 67 Set<Feature<?>> features = Helpers.copyToSet(getFeatures()); 68 List<Class<? extends AbstractTester>> testers = getTesters(); 69 70 logger.fine(" Testing: " + name); 71 72 // Split out all the specified sizes. 73 Set<Feature<?>> sizesToTest = 74 Helpers.<Feature<?>>copyToSet(CollectionSize.values()); 75 sizesToTest.retainAll(features); 76 features.removeAll(sizesToTest); 77 78 FeatureUtil.addImpliedFeatures(sizesToTest); 79 sizesToTest.retainAll(Arrays.asList( 80 CollectionSize.ZERO, CollectionSize.ONE, CollectionSize.SEVERAL)); 81 82 logger.fine(" Sizes: " + formatFeatureSet(sizesToTest)); 83 84 if (sizesToTest.isEmpty()) { 85 throw new IllegalStateException(name 86 + ": no CollectionSizes specified (check the argument to " 87 + "FeatureSpecificTestSuiteBuilder.withFeatures().)"); 88 } 89 90 TestSuite suite = new TestSuite(name); 91 for (Feature<?> collectionSize : sizesToTest) { 92 String oneSizeName = Platform.format("%s [collection size: %s]", 93 name, collectionSize.toString().toLowerCase()); 94 OneSizeGenerator<T, E> oneSizeGenerator = new OneSizeGenerator<T, E>( 95 getSubjectGenerator(), (CollectionSize) collectionSize); 96 Set<Feature<?>> oneSizeFeatures = Helpers.copyToSet(features); 97 oneSizeFeatures.add(collectionSize); 98 Set<Method> oneSizeSuppressedTests = getSuppressedTests(); 99 100 OneSizeTestSuiteBuilder<T, E> oneSizeBuilder = 101 new OneSizeTestSuiteBuilder<T, E>(testers) 102 .named(oneSizeName) 103 .usingGenerator(oneSizeGenerator) 104 .withFeatures(oneSizeFeatures) 105 .withSetUp(getSetUp()) 106 .withTearDown(getTearDown()) 107 .suppressing(oneSizeSuppressedTests); 108 TestSuite oneSizeSuite = oneSizeBuilder.createTestSuite(); 109 suite.addTest(oneSizeSuite); 110 111 for (TestSuite derivedSuite : createDerivedSuites(oneSizeBuilder)) { 112 oneSizeSuite.addTest(derivedSuite); 113 } 114 } 115 return suite; 116 } 117 118 List<TestSuite> createDerivedSuites(FeatureSpecificTestSuiteBuilder< 119 ?, ? extends OneSizeTestContainerGenerator<T, E>> parentBuilder) { 120 return new ArrayList<TestSuite>(); 121 } 122 123 /** Builds a test suite for one particular {@link CollectionSize}. */ 124 private static final class OneSizeTestSuiteBuilder<T, E> extends 125 FeatureSpecificTestSuiteBuilder< 126 OneSizeTestSuiteBuilder<T, E>, OneSizeGenerator<T, E>> { 127 private final List<Class<? extends AbstractTester>> testers; 128 129 public OneSizeTestSuiteBuilder( 130 List<Class<? extends AbstractTester>> testers) { 131 this.testers = testers; 132 } 133 134 @Override protected List<Class<? extends AbstractTester>> getTesters() { 135 return testers; 136 } 137 } 138 } 139