1 package junitparams.internal; 2 3 import java.lang.annotation.Annotation; 4 import java.lang.reflect.Method; 5 import java.util.ArrayList; 6 import java.util.Arrays; 7 import java.util.List; 8 9 import org.junit.Ignore; 10 import org.junit.Test; 11 import org.junit.runner.Description; 12 import org.junit.runners.model.FrameworkMethod; 13 import org.junit.runners.model.TestClass; 14 15 import junitparams.internal.annotation.FrameworkMethodAnnotations; 16 import junitparams.internal.parameters.ParametersReader; 17 import junitparams.naming.MacroSubstitutionNamingStrategy; 18 import junitparams.naming.TestCaseNamingStrategy; 19 20 /** 21 * A wrapper for a test method 22 * 23 * @author Pawel Lipinski 24 */ 25 public class TestMethod { 26 private FrameworkMethod frameworkMethod; 27 private FrameworkMethodAnnotations frameworkMethodAnnotations; 28 private Class<?> testClass; 29 private ParametersReader parametersReader; 30 private Object[] cachedParameters; 31 private TestCaseNamingStrategy namingStrategy; 32 private DescribableFrameworkMethod describableFrameworkMethod; 33 TestMethod(FrameworkMethod method, TestClass testClass)34 public TestMethod(FrameworkMethod method, TestClass testClass) { 35 this.frameworkMethod = method; 36 this.testClass = testClass.getJavaClass(); 37 frameworkMethodAnnotations = new FrameworkMethodAnnotations(method); 38 parametersReader = new ParametersReader(testClass(), frameworkMethod); 39 40 namingStrategy = new MacroSubstitutionNamingStrategy(this); 41 } 42 name()43 public String name() { 44 return frameworkMethod.getName(); 45 } 46 listFrom(TestClass testClass)47 public static List<FrameworkMethod> listFrom(TestClass testClass) { 48 List<FrameworkMethod> methods = new ArrayList<FrameworkMethod>(); 49 50 for (FrameworkMethod frameworkMethod : testClass.getAnnotatedMethods(Test.class)) { 51 TestMethod testMethod = new TestMethod(frameworkMethod, testClass); 52 methods.add(testMethod.describableFrameworkMethod()); 53 } 54 55 return methods; 56 } 57 58 @Override hashCode()59 public int hashCode() { 60 return frameworkMethod.hashCode(); 61 } 62 63 @Override equals(Object obj)64 public boolean equals(Object obj) { 65 return (obj instanceof TestMethod) 66 && hasTheSameNameAsFrameworkMethod((TestMethod) obj) 67 && hasTheSameParameterTypesAsFrameworkMethod((TestMethod) obj); 68 } 69 hasTheSameNameAsFrameworkMethod(TestMethod testMethod)70 private boolean hasTheSameNameAsFrameworkMethod(TestMethod testMethod) { 71 return frameworkMethod.getName().equals(testMethod.frameworkMethod.getName()); 72 } 73 hasTheSameParameterTypesAsFrameworkMethod(TestMethod testMethod)74 private boolean hasTheSameParameterTypesAsFrameworkMethod(TestMethod testMethod) { 75 Class<?>[] frameworkMethodParameterTypes = frameworkMethod.getMethod().getParameterTypes(); 76 Class<?>[] testMethodParameterTypes = testMethod.frameworkMethod.getMethod().getParameterTypes(); 77 return Arrays.equals(frameworkMethodParameterTypes, testMethodParameterTypes); 78 } 79 testClass()80 private Class<?> testClass() { 81 return testClass; 82 } 83 isIgnored()84 private boolean isIgnored() { 85 return hasIgnoredAnnotation() || hasNoParameters(); 86 } 87 hasIgnoredAnnotation()88 private boolean hasIgnoredAnnotation() { 89 return frameworkMethodAnnotations.hasAnnotation(Ignore.class); 90 } 91 hasNoParameters()92 private boolean hasNoParameters() { 93 return isParameterised() && parametersSets().length == 0; 94 } 95 isNotIgnored()96 private boolean isNotIgnored() { 97 return !isIgnored(); 98 } 99 getAnnotation(Class<T> annotationType)100 public <T extends Annotation> T getAnnotation(Class<T> annotationType) { 101 return frameworkMethodAnnotations.getAnnotation(annotationType); 102 } 103 getDescription(Object[] params, int i)104 private Description getDescription(Object[] params, int i) { 105 Object paramSet = params[i]; 106 String name = namingStrategy.getTestCaseName(i, paramSet); 107 String uniqueMethodId = Utils.uniqueMethodId(i, paramSet, name()); 108 109 return Description.createTestDescription(testClass().getName(), name, uniqueMethodId); 110 } 111 describableFrameworkMethod()112 DescribableFrameworkMethod describableFrameworkMethod() { 113 if (describableFrameworkMethod == null) { 114 Description baseDescription = Description.createTestDescription( 115 testClass, name(), frameworkMethodAnnotations.allAnnotations()); 116 Method method = frameworkMethod.getMethod(); 117 try { 118 describableFrameworkMethod = 119 createDescribableFrameworkMethod(method, baseDescription); 120 } catch (IllegalStateException e) { 121 // Defer error until running. 122 describableFrameworkMethod = 123 new DeferredErrorFrameworkMethod(method, baseDescription, e); 124 } 125 } 126 127 return describableFrameworkMethod; 128 } 129 createDescribableFrameworkMethod(Method method, Description baseDescription)130 private DescribableFrameworkMethod createDescribableFrameworkMethod(Method method, Description baseDescription) { 131 if (isParameterised()) { 132 if (isNotIgnored()) { 133 Object[] parametersSets = parametersSets(); 134 List<InstanceFrameworkMethod> methods 135 = new ArrayList<InstanceFrameworkMethod>(); 136 for (int i = 0; i < parametersSets.length; i++) { 137 Object parametersSet = parametersSets[i]; 138 Description description = getDescription(parametersSets, i); 139 methods.add(new InstanceFrameworkMethod( 140 method, baseDescription.childlessCopy(), 141 description, parametersSet)); 142 } 143 144 return new ParameterisedFrameworkMethod(method, baseDescription, methods); 145 } 146 147 warnIfNoParamsGiven(); 148 } else { 149 verifyMethodCanBeRunByStandardRunner(frameworkMethod); 150 } 151 152 // The method to use if it was ignored or was parameterized but had no parameters. 153 return new NonParameterisedFrameworkMethod(method, baseDescription, isIgnored()); 154 } 155 verifyMethodCanBeRunByStandardRunner(FrameworkMethod method)156 private void verifyMethodCanBeRunByStandardRunner(FrameworkMethod method) { 157 List<Throwable> errors = new ArrayList<Throwable>(); 158 method.validatePublicVoidNoArg(false, errors); 159 if (!errors.isEmpty()) { 160 throw new RuntimeException(errors.get(0)); 161 } 162 } 163 parametersSets()164 public Object[] parametersSets() { 165 if (cachedParameters == null) { 166 cachedParameters = parametersReader.read(); 167 } 168 return cachedParameters; 169 } 170 warnIfNoParamsGiven()171 private void warnIfNoParamsGiven() { 172 if (isNotIgnored() && isParameterised() && parametersSets().length == 0) 173 System.err.println("Method " + name() + " gets empty list of parameters, so it's being ignored!"); 174 } 175 frameworkMethod()176 public FrameworkMethod frameworkMethod() { 177 return frameworkMethod; 178 } 179 isParameterised()180 boolean isParameterised() { 181 return frameworkMethodAnnotations.isParametrised(); 182 } 183 } 184