PerCollectionSizeTestSuiteBuilder.java revision 7dd252788645e940eada959bdde927426e2531c9
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
17package com.google.common.collect.testing;
18
19import com.google.common.collect.testing.features.CollectionSize;
20import com.google.common.collect.testing.features.Feature;
21import com.google.common.collect.testing.features.FeatureUtil;
22
23import junit.framework.TestSuite;
24
25import java.lang.reflect.Method;
26import java.util.ArrayList;
27import java.util.Arrays;
28import java.util.List;
29import java.util.Set;
30import 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 */
50public 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  protected 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