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