Home | History | Annotate | Download | only in testing
      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