package junitparams.internal; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import org.junit.Ignore; import org.junit.Test; import org.junit.runner.Description; import org.junit.runners.model.FrameworkMethod; import org.junit.runners.model.TestClass; import junitparams.internal.annotation.FrameworkMethodAnnotations; import junitparams.internal.parameters.ParametersReader; import junitparams.naming.MacroSubstitutionNamingStrategy; import junitparams.naming.TestCaseNamingStrategy; /** * A wrapper for a test method * * @author Pawel Lipinski */ public class TestMethod { private FrameworkMethod frameworkMethod; private FrameworkMethodAnnotations frameworkMethodAnnotations; private Class testClass; private ParametersReader parametersReader; private Object[] cachedParameters; private TestCaseNamingStrategy namingStrategy; private DescribableFrameworkMethod describableFrameworkMethod; public TestMethod(FrameworkMethod method, TestClass testClass) { this.frameworkMethod = method; this.testClass = testClass.getJavaClass(); frameworkMethodAnnotations = new FrameworkMethodAnnotations(method); parametersReader = new ParametersReader(testClass(), frameworkMethod); namingStrategy = new MacroSubstitutionNamingStrategy(this); } public String name() { return frameworkMethod.getName(); } public static List listFrom(TestClass testClass) { List methods = new ArrayList(); for (FrameworkMethod frameworkMethod : testClass.getAnnotatedMethods(Test.class)) { TestMethod testMethod = new TestMethod(frameworkMethod, testClass); methods.add(testMethod.describableFrameworkMethod()); } return methods; } @Override public int hashCode() { return frameworkMethod.hashCode(); } @Override public boolean equals(Object obj) { return (obj instanceof TestMethod) && hasTheSameNameAsFrameworkMethod((TestMethod) obj) && hasTheSameParameterTypesAsFrameworkMethod((TestMethod) obj); } private boolean hasTheSameNameAsFrameworkMethod(TestMethod testMethod) { return frameworkMethod.getName().equals(testMethod.frameworkMethod.getName()); } private boolean hasTheSameParameterTypesAsFrameworkMethod(TestMethod testMethod) { Class[] frameworkMethodParameterTypes = frameworkMethod.getMethod().getParameterTypes(); Class[] testMethodParameterTypes = testMethod.frameworkMethod.getMethod().getParameterTypes(); return Arrays.equals(frameworkMethodParameterTypes, testMethodParameterTypes); } private Class testClass() { return testClass; } private boolean isIgnored() { return hasIgnoredAnnotation() || hasNoParameters(); } private boolean hasIgnoredAnnotation() { return frameworkMethodAnnotations.hasAnnotation(Ignore.class); } private boolean hasNoParameters() { return isParameterised() && parametersSets().length == 0; } private boolean isNotIgnored() { return !isIgnored(); } public T getAnnotation(Class annotationType) { return frameworkMethodAnnotations.getAnnotation(annotationType); } private Description getDescription(Object[] params, int i) { Object paramSet = params[i]; String name = namingStrategy.getTestCaseName(i, paramSet); String uniqueMethodId = Utils.uniqueMethodId(i, paramSet, name()); return Description.createTestDescription(testClass().getName(), name, uniqueMethodId); } DescribableFrameworkMethod describableFrameworkMethod() { if (describableFrameworkMethod == null) { Description baseDescription = Description.createTestDescription( testClass, name(), frameworkMethodAnnotations.allAnnotations()); Method method = frameworkMethod.getMethod(); try { describableFrameworkMethod = createDescribableFrameworkMethod(method, baseDescription); } catch (IllegalStateException e) { // Defer error until running. describableFrameworkMethod = new DeferredErrorFrameworkMethod(method, baseDescription, e); } } return describableFrameworkMethod; } private DescribableFrameworkMethod createDescribableFrameworkMethod(Method method, Description baseDescription) { if (isParameterised()) { if (isNotIgnored()) { Object[] parametersSets = parametersSets(); List methods = new ArrayList(); for (int i = 0; i < parametersSets.length; i++) { Object parametersSet = parametersSets[i]; Description description = getDescription(parametersSets, i); methods.add(new InstanceFrameworkMethod( method, baseDescription.childlessCopy(), description, parametersSet)); } return new ParameterisedFrameworkMethod(method, baseDescription, methods); } warnIfNoParamsGiven(); } else { verifyMethodCanBeRunByStandardRunner(frameworkMethod); } // The method to use if it was ignored or was parameterized but had no parameters. return new NonParameterisedFrameworkMethod(method, baseDescription, isIgnored()); } private void verifyMethodCanBeRunByStandardRunner(FrameworkMethod method) { List errors = new ArrayList(); method.validatePublicVoidNoArg(false, errors); if (!errors.isEmpty()) { throw new RuntimeException(errors.get(0)); } } public Object[] parametersSets() { if (cachedParameters == null) { cachedParameters = parametersReader.read(); } return cachedParameters; } private void warnIfNoParamsGiven() { if (isNotIgnored() && isParameterised() && parametersSets().length == 0) System.err.println("Method " + name() + " gets empty list of parameters, so it's being ignored!"); } public FrameworkMethod frameworkMethod() { return frameworkMethod; } boolean isParameterised() { return frameworkMethodAnnotations.isParametrised(); } }