001/* 002 * Copyright (C) 2008 The Guava Authors 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package com.google.common.collect.testing; 018 019import static com.google.common.collect.testing.Helpers.copyToSet; 020import static com.google.common.collect.testing.features.FeatureUtil.addImpliedFeatures; 021import static java.util.Arrays.asList; 022 023import com.google.common.annotations.GwtIncompatible; 024import com.google.common.collect.testing.features.CollectionSize; 025import com.google.common.collect.testing.features.Feature; 026import java.lang.reflect.Method; 027import java.util.ArrayList; 028import java.util.List; 029import java.util.Set; 030import java.util.logging.Logger; 031import junit.framework.TestSuite; 032 033/** 034 * This builder creates a composite test suite, containing a separate test suite for each {@link 035 * CollectionSize} present in the features specified by {@link #withFeatures(Feature...)}. 036 * 037 * @param <B> The concrete type of this builder (the 'self-type'). All the Builder methods of this 038 * class (such as {@link #named(String)}) return this type, so that Builder methods of more 039 * derived classes can be chained onto them without casting. 040 * @param <G> The type of the generator to be passed to testers in the generated test suite. An 041 * instance of G should somehow provide an instance of the class under test, plus any other 042 * information required to parameterize the test. 043 * @see FeatureSpecificTestSuiteBuilder 044 * @author George van den Driessche 045 */ 046@GwtIncompatible 047public abstract class PerCollectionSizeTestSuiteBuilder< 048 B extends PerCollectionSizeTestSuiteBuilder<B, G, T, E>, 049 G extends TestContainerGenerator<T, E>, 050 T, 051 E> 052 extends FeatureSpecificTestSuiteBuilder<B, G> { 053 private static final Logger logger = 054 Logger.getLogger(PerCollectionSizeTestSuiteBuilder.class.getName()); 055 056 /** Creates a runnable JUnit test suite based on the criteria already given. */ 057 @Override 058 public TestSuite createTestSuite() { 059 checkCanCreate(); 060 061 String name = getName(); 062 // Copy this set, so we can modify it. 063 Set<Feature<?>> features = copyToSet(getFeatures()); 064 @SuppressWarnings("rawtypes") // class literals 065 List<Class<? extends AbstractTester>> testers = getTesters(); 066 067 logger.fine(" Testing: " + name); 068 069 // Split out all the specified sizes. 070 Set<Feature<?>> sizesToTest = Helpers.<Feature<?>>copyToSet(CollectionSize.values()); 071 sizesToTest.retainAll(features); 072 features.removeAll(sizesToTest); 073 074 addImpliedFeatures(sizesToTest); 075 sizesToTest.retainAll(asList(CollectionSize.ZERO, CollectionSize.ONE, CollectionSize.SEVERAL)); 076 077 logger.fine(" Sizes: " + formatFeatureSet(sizesToTest)); 078 079 if (sizesToTest.isEmpty()) { 080 throw new IllegalStateException( 081 name 082 + ": no CollectionSizes specified (check the argument to " 083 + "FeatureSpecificTestSuiteBuilder.withFeatures().)"); 084 } 085 086 TestSuite suite = new TestSuite(name); 087 for (Feature<?> collectionSize : sizesToTest) { 088 String oneSizeName = 089 Platform.format( 090 "%s [collection size: %s]", name, collectionSize.toString().toLowerCase()); 091 OneSizeGenerator<T, E> oneSizeGenerator = 092 new OneSizeGenerator<>(getSubjectGenerator(), (CollectionSize) collectionSize); 093 Set<Feature<?>> oneSizeFeatures = copyToSet(features); 094 oneSizeFeatures.add(collectionSize); 095 Set<Method> oneSizeSuppressedTests = getSuppressedTests(); 096 097 OneSizeTestSuiteBuilder<T, E> oneSizeBuilder = 098 new OneSizeTestSuiteBuilder<T, E>(testers) 099 .named(oneSizeName) 100 .usingGenerator(oneSizeGenerator) 101 .withFeatures(oneSizeFeatures) 102 .withSetUp(getSetUp()) 103 .withTearDown(getTearDown()) 104 .suppressing(oneSizeSuppressedTests); 105 TestSuite oneSizeSuite = oneSizeBuilder.createTestSuite(); 106 suite.addTest(oneSizeSuite); 107 108 for (TestSuite derivedSuite : createDerivedSuites(oneSizeBuilder)) { 109 oneSizeSuite.addTest(derivedSuite); 110 } 111 } 112 return suite; 113 } 114 115 protected List<TestSuite> createDerivedSuites( 116 FeatureSpecificTestSuiteBuilder<?, ? extends OneSizeTestContainerGenerator<T, E>> 117 parentBuilder) { 118 return new ArrayList<>(); 119 } 120 121 /** Builds a test suite for one particular {@link CollectionSize}. */ 122 private static final class OneSizeTestSuiteBuilder<T, E> 123 extends FeatureSpecificTestSuiteBuilder< 124 OneSizeTestSuiteBuilder<T, E>, OneSizeGenerator<T, E>> { 125 @SuppressWarnings("rawtypes") // class literals 126 private final List<Class<? extends AbstractTester>> testers; 127 128 @SuppressWarnings("rawtypes") // class literals 129 public OneSizeTestSuiteBuilder(List<Class<? extends AbstractTester>> testers) { 130 this.testers = testers; 131 } 132 133 @SuppressWarnings("rawtypes") // class literals 134 @Override 135 protected List<Class<? extends AbstractTester>> getTesters() { 136 return testers; 137 } 138 } 139}