aboutsummaryrefslogtreecommitdiffstats
path: root/guava-testlib/src/com/google/common/collect/testing/PerCollectionSizeTestSuiteBuilder.java
blob: ef3f384cfde139051fb53f501c9966f3ee7b8cc3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/*
 * 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;
    }
  }
}