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 com.google.common.annotations.GwtIncompatible; 020import com.google.common.collect.testing.features.CollectionSize; 021import com.google.common.collect.testing.features.Feature; 022import com.google.common.collect.testing.features.FeatureUtil; 023import java.lang.reflect.Method; 024import java.util.ArrayList; 025import java.util.Arrays; 026import java.util.List; 027import java.util.Set; 028import java.util.logging.Logger; 029import junit.framework.TestSuite; 030 031/** 032 * This builder creates a composite test suite, containing a separate test suite for each {@link 033 * CollectionSize} present in the features specified by {@link #withFeatures(Feature...)}. 034 * 035 * @param <B> The concrete type of this builder (the 'self-type'). All the Builder methods of this 036 * class (such as {@link #named(String)}) return this type, so that Builder methods of more 037 * derived classes can be chained onto them without casting. 038 * @param <G> The type of the generator to be passed to testers in the generated test suite. An 039 * instance of G should somehow provide an instance of the class under test, plus any other 040 * information required to parameterize the test. 041 * @see FeatureSpecificTestSuiteBuilder 042 * @author George van den Driessche 043 */ 044@GwtIncompatible 045public abstract class PerCollectionSizeTestSuiteBuilder< 046 B extends PerCollectionSizeTestSuiteBuilder<B, G, T, E>, 047 G extends TestContainerGenerator<T, E>, 048 T, 049 E> 050 extends FeatureSpecificTestSuiteBuilder<B, G> { 051 private static final Logger logger = 052 Logger.getLogger(PerCollectionSizeTestSuiteBuilder.class.getName()); 053 054 /** Creates a runnable JUnit test suite based on the criteria already given. */ 055 @Override 056 public TestSuite createTestSuite() { 057 checkCanCreate(); 058 059 String name = getName(); 060 // Copy this set, so we can modify it. 061 Set<Feature<?>> features = Helpers.copyToSet(getFeatures()); 062 List<Class<? extends AbstractTester>> testers = getTesters(); 063 064 logger.fine(" Testing: " + name); 065 066 // Split out all the specified sizes. 067 Set<Feature<?>> sizesToTest = Helpers.<Feature<?>>copyToSet(CollectionSize.values()); 068 sizesToTest.retainAll(features); 069 features.removeAll(sizesToTest); 070 071 FeatureUtil.addImpliedFeatures(sizesToTest); 072 sizesToTest.retainAll( 073 Arrays.asList(CollectionSize.ZERO, CollectionSize.ONE, CollectionSize.SEVERAL)); 074 075 logger.fine(" Sizes: " + formatFeatureSet(sizesToTest)); 076 077 if (sizesToTest.isEmpty()) { 078 throw new IllegalStateException( 079 name 080 + ": no CollectionSizes specified (check the argument to " 081 + "FeatureSpecificTestSuiteBuilder.withFeatures().)"); 082 } 083 084 TestSuite suite = new TestSuite(name); 085 for (Feature<?> collectionSize : sizesToTest) { 086 String oneSizeName = 087 Platform.format( 088 "%s [collection size: %s]", name, collectionSize.toString().toLowerCase()); 089 OneSizeGenerator<T, E> oneSizeGenerator = 090 new OneSizeGenerator<>(getSubjectGenerator(), (CollectionSize) collectionSize); 091 Set<Feature<?>> oneSizeFeatures = Helpers.copyToSet(features); 092 oneSizeFeatures.add(collectionSize); 093 Set<Method> oneSizeSuppressedTests = getSuppressedTests(); 094 095 OneSizeTestSuiteBuilder<T, E> oneSizeBuilder = 096 new OneSizeTestSuiteBuilder<T, E>(testers) 097 .named(oneSizeName) 098 .usingGenerator(oneSizeGenerator) 099 .withFeatures(oneSizeFeatures) 100 .withSetUp(getSetUp()) 101 .withTearDown(getTearDown()) 102 .suppressing(oneSizeSuppressedTests); 103 TestSuite oneSizeSuite = oneSizeBuilder.createTestSuite(); 104 suite.addTest(oneSizeSuite); 105 106 for (TestSuite derivedSuite : createDerivedSuites(oneSizeBuilder)) { 107 oneSizeSuite.addTest(derivedSuite); 108 } 109 } 110 return suite; 111 } 112 113 protected List<TestSuite> createDerivedSuites( 114 FeatureSpecificTestSuiteBuilder<?, ? extends OneSizeTestContainerGenerator<T, E>> 115 parentBuilder) { 116 return new ArrayList<>(); 117 } 118 119 /** Builds a test suite for one particular {@link CollectionSize}. */ 120 private static final class OneSizeTestSuiteBuilder<T, E> 121 extends FeatureSpecificTestSuiteBuilder< 122 OneSizeTestSuiteBuilder<T, E>, OneSizeGenerator<T, E>> { 123 private final List<Class<? extends AbstractTester>> testers; 124 125 public OneSizeTestSuiteBuilder(List<Class<? extends AbstractTester>> testers) { 126 this.testers = testers; 127 } 128 129 @Override 130 protected List<Class<? extends AbstractTester>> getTesters() { 131 return testers; 132 } 133 } 134}