• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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