/* * Copyright (C) 2008 The Guava Authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.google.common.collect.testing; import com.google.common.collect.testing.features.CollectionSize; import com.google.common.collect.testing.features.Feature; import com.google.common.collect.testing.features.FeatureUtil; import junit.framework.TestSuite; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Set; import java.util.logging.Logger; /** * This builder creates a composite test suite, containing a separate test suite * for each {@link CollectionSize} present in the features specified * by {@link #withFeatures(Feature...)}. * * @param <B> The concrete type of this builder (the 'self-type'). All the * Builder methods of this class (such as {@link #named(String)}) return this * type, so that Builder methods of more derived classes can be chained onto * them without casting. * @param <G> The type of the generator to be passed to testers in the * generated test suite. An instance of G should somehow provide an * instance of the class under test, plus any other information required * to parameterize the test. * * @see FeatureSpecificTestSuiteBuilder * * @author George van den Driessche */ public abstract class PerCollectionSizeTestSuiteBuilder< B extends PerCollectionSizeTestSuiteBuilder<B, G, T, E>, G extends TestContainerGenerator<T, E>, T, E> extends FeatureSpecificTestSuiteBuilder<B, G> { private static final Logger logger = Logger.getLogger( PerCollectionSizeTestSuiteBuilder.class.getName()); /** * Creates a runnable JUnit test suite based on the criteria already given. */ @Override public TestSuite createTestSuite() { checkCanCreate(); String name = getName(); // Copy this set, so we can modify it. Set<Feature<?>> features = Helpers.copyToSet(getFeatures()); List<Class<? extends AbstractTester>> testers = getTesters(); logger.fine(" Testing: " + name); // Split out all the specified sizes. Set<Feature<?>> sizesToTest = Helpers.<Feature<?>>copyToSet(CollectionSize.values()); sizesToTest.retainAll(features); features.removeAll(sizesToTest); FeatureUtil.addImpliedFeatures(sizesToTest); sizesToTest.retainAll(Arrays.asList( CollectionSize.ZERO, CollectionSize.ONE, CollectionSize.SEVERAL)); logger.fine(" Sizes: " + formatFeatureSet(sizesToTest)); if (sizesToTest.isEmpty()) { throw new IllegalStateException(name + ": no CollectionSizes specified (check the argument to " + "FeatureSpecificTestSuiteBuilder.withFeatures().)"); } TestSuite suite = new TestSuite(name); for (Feature<?> collectionSize : sizesToTest) { String oneSizeName = Platform.format("%s [collection size: %s]", name, collectionSize.toString().toLowerCase()); OneSizeGenerator<T, E> oneSizeGenerator = new OneSizeGenerator<T, E>( getSubjectGenerator(), (CollectionSize) collectionSize); Set<Feature<?>> oneSizeFeatures = Helpers.copyToSet(features); oneSizeFeatures.add(collectionSize); Set<Method> oneSizeSuppressedTests = getSuppressedTests(); OneSizeTestSuiteBuilder<T, E> oneSizeBuilder = new OneSizeTestSuiteBuilder<T, E>(testers) .named(oneSizeName) .usingGenerator(oneSizeGenerator) .withFeatures(oneSizeFeatures) .withSetUp(getSetUp()) .withTearDown(getTearDown()) .suppressing(oneSizeSuppressedTests); TestSuite oneSizeSuite = oneSizeBuilder.createTestSuite(); suite.addTest(oneSizeSuite); for (TestSuite derivedSuite : createDerivedSuites(oneSizeBuilder)) { oneSizeSuite.addTest(derivedSuite); } } return suite; } protected List<TestSuite> createDerivedSuites(FeatureSpecificTestSuiteBuilder< ?, ? extends OneSizeTestContainerGenerator<T, E>> parentBuilder) { return new ArrayList<TestSuite>(); } /** Builds a test suite for one particular {@link CollectionSize}. */ private static final class OneSizeTestSuiteBuilder<T, E> extends FeatureSpecificTestSuiteBuilder< OneSizeTestSuiteBuilder<T, E>, OneSizeGenerator<T, E>> { private final List<Class<? extends AbstractTester>> testers; public OneSizeTestSuiteBuilder( List<Class<? extends AbstractTester>> testers) { this.testers = testers; } @Override protected List<Class<? extends AbstractTester>> getTesters() { return testers; } } }