/* * Copyright 2010 Henry Coles * * 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 org.pitest.simpletest; import static org.pitest.util.Unchecked.translateCheckedException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collection; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; import org.pitest.functional.F; import org.pitest.functional.FCollection; import org.pitest.functional.Option; import org.pitest.functional.SideEffect1; import org.pitest.reflection.Reflection; import org.pitest.simpletest.steps.CallStep; import org.pitest.testapi.Description; import org.pitest.testapi.TestUnit; import org.pitest.testapi.TestUnitFinder; import org.pitest.util.PitError; public class BasicTestUnitFinder implements TestUnitFinder { private final Set<InstantiationStrategy> instantiationStrategies = new LinkedHashSet<InstantiationStrategy>(); private final Set<MethodFinder> testMethodFinders = new LinkedHashSet<MethodFinder>(); public BasicTestUnitFinder( final Collection<InstantiationStrategy> instantiationStrategies, final Collection<MethodFinder> testMethodFinders) { this.instantiationStrategies.addAll(instantiationStrategies); this.testMethodFinders.addAll(testMethodFinders); } @Override public List<TestUnit> findTestUnits(final Class<?> testClass) { try { final List<TestUnit> units = new ArrayList<TestUnit>(); final InstantiationStrategy instantiationStrategy = findInstantiationStrategy(testClass); final List<TestStep> instantiations = instantiationStrategy .instantiations(testClass); for (int instantiation = 0; instantiation != instantiations.size(); instantiation++) { for (final TestMethod m : findTestMethods(testClass)) { final TestStep step = instantiations.get(instantiation); units .add(createTestUnitForInstantiation(step, getNamePrefix(instantiations.size(), instantiation), testClass, m)); } } return units; } catch (final Exception ex) { throw translateCheckedException(ex); } } private String getNamePrefix(final int size, final int i) { if (size == 1) { return ""; } else { return "[" + i + "] "; } } private TestUnit createTestUnitForInstantiation( final TestStep instantiationStep, final String namePrefix, final Class<?> testClass, final TestMethod testMethod) { final List<TestStep> steps = new ArrayList<TestStep>(); steps.add(instantiationStep); steps.add(new CallStep(testMethod)); final TestUnit unit = new SteppedTestUnit(new Description(namePrefix + testMethod.getName(), testClass), steps, testMethod.getExpected()); return unit; } private InstantiationStrategy findInstantiationStrategy(final Class<?> clazz) { final List<InstantiationStrategy> strategies = FCollection.filter( this.instantiationStrategies, canInstantiate(clazz)); if (strategies.isEmpty()) { throw new PitError("Cannot instantiate " + clazz); } else { return strategies.get(0); } } private F<InstantiationStrategy, Boolean> canInstantiate(final Class<?> clazz) { return new F<InstantiationStrategy, Boolean>() { @Override public Boolean apply(final InstantiationStrategy a) { return a.canInstantiate(clazz); } }; } private Collection<TestMethod> findTestMethods(final Class<?> clazz) { final EqualitySet<TestMethod> set = new EqualitySet<TestMethod>( new SignatureEqualityStrategy()); final SideEffect1<TestMethod> addToSet = new SideEffect1<TestMethod>() { @Override public void apply(final TestMethod a) { set.add(a); } }; final Collection<Method> methods = Reflection.allMethods(clazz); for (final F<Method, Option<TestMethod>> mf : this.testMethodFinders) { FCollection.flatMap(methods, mf).forEach(addToSet); } return set.toCollection(); } }