aboutsummaryrefslogtreecommitdiffstats
path: root/src/main/java/junitparams/internal/ParameterisedTestClassRunner.java
blob: 23daf88367392d69917dd3b481b57a01d3e9dcc1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
package junitparams.internal;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.junit.Test;
import org.junit.runner.Description;
import org.junit.runner.notification.RunNotifier;
import org.junit.runners.model.FrameworkMethod;
import org.junit.runners.model.Statement;
import org.junit.runners.model.TestClass;

/**
 * Testclass-level functionalities to handle parameters from a JUnit runner
 * class.
 *
 * @author Pawel Lipinski
 */
public class ParameterisedTestClassRunner {

    protected Map<TestMethod, ParameterisedTestMethodRunner> parameterisedMethods = new HashMap<TestMethod, ParameterisedTestMethodRunner>();
    protected Map<FrameworkMethod, TestMethod> testMethods = new HashMap<FrameworkMethod, TestMethod>();
    protected List<TestMethod> testMethodsList;

    /**
     * Creates a runner for a given test class. Computes all the test methods
     * that are annotated as tests. Retrieves and caches all parameter values.
     *
     * @param testClass
     */
    public ParameterisedTestClassRunner(TestClass testClass) {
        computeTestMethods(testClass);
        fillTestMethodsMap();
        computeFrameworkMethods();
    }

    protected void computeTestMethods(TestClass testClass) {
        testMethodsList = TestMethod.listFrom(testClass.getAnnotatedMethods(Test.class), testClass);
    }

    private void fillTestMethodsMap() {
        for (TestMethod testMethod : testMethodsList)
            testMethods.put(testMethod.frameworkMethod(), testMethod);
    }

    /**
     * Returns a list of <code>FrameworkMethod</code>s. Handles both
     * parameterised methods (counts them as many times as many paramsets they
     * have) and nonparameterised methods (just counts them once).
     *
     * @return a list of FrameworkMethod objects
     */
    public List<FrameworkMethod> computeFrameworkMethods() {
        List<FrameworkMethod> resultMethods = new ArrayList<FrameworkMethod>();

        for (TestMethod testMethod : testMethodsList) {
            if (testMethod.isParameterised())
                addTestMethodForEachParamSet(resultMethods, testMethod);
            else
                addTestMethodOnce(resultMethods, testMethod);
        }

        return resultMethods;
    }

    /**
     * Returns a list of <code>FrameworkMethod</code>s - once per method, like
     * there were no parameters.
     * For JUnit to build names for IDE.
     */
    public List<FrameworkMethod> returnListOfMethods() {
        List<FrameworkMethod> resultMethods = new ArrayList<FrameworkMethod>();

        for (TestMethod testMethod : testMethodsList) {
            addTestMethodOnce(resultMethods, testMethod);
            cacheMethodRunner(testMethod);
            testMethod.warnIfNoParamsGiven();
        }

        return resultMethods;
    }

    private void addTestMethodForEachParamSet(List<FrameworkMethod> resultMethods, TestMethod testMethod) {
        if (testMethod.isNotIgnored()) {
            int paramSetSize = testMethod.parametersSets().length;
            for (int i = 0; i < paramSetSize; i++)
                addTestMethodOnce(resultMethods, testMethod);
        } else {
            addTestMethodOnce(resultMethods, testMethod);
        }
    }

    private void addTestMethodOnce(List<FrameworkMethod> resultMethods, TestMethod testMethod) {
        resultMethods.add(testMethod.frameworkMethod());
    }

    private void cacheMethodRunner(TestMethod testMethod) {
        if (!parameterisedMethods.containsKey(testMethod))
            parameterisedMethods.put(testMethod, new ParameterisedTestMethodRunner(testMethod));
    }

    /**
     * Returns a InvokeParameterisedMethod for parameterised methods and null
     * for nonparameterised
     *
     * @param method    Test method
     * @param testClass
     * @return a Statement with the invoker for the parameterised method
     */
    public Statement parameterisedMethodInvoker(FrameworkMethod method, Object testClass) {
        TestMethod testMethod = testMethods.get(method);

        if (!testMethod.isParameterised())
            return null;

        return buildMethodInvoker(method, testClass, testMethod);
    }

    private Statement buildMethodInvoker(FrameworkMethod method, Object testClass, TestMethod testMethod) {
        ParameterisedTestMethodRunner parameterisedMethod = parameterisedMethods.get(testMethod);

        return new InvokeParameterisedMethod(
                method, testClass, parameterisedMethod.currentParamsFromAnnotation(), parameterisedMethod.count());
    }

    /**
     * Tells if method should be run by this runner.
     *
     * @param testMethod
     * @return true, iff testMethod should be run by this runner.
     */
    public boolean shouldRun(TestMethod testMethod) {
        return testMethod.isParameterised();
    }

    /**
     * Executes parameterised method.
     *
     * @param method
     * @param methodInvoker
     * @param notifier
     */
    public void runParameterisedTest(TestMethod method, Statement methodInvoker, RunNotifier notifier) {
        parameterisedMethods.get(method).runTestMethod(methodInvoker, notifier);
    }

    /**
     * Returns description of a parameterised method.
     *
     * @param method TODO
     * @return Description of a method or null if it's not parameterised.
     */
    public Description describeParameterisedMethod(FrameworkMethod method) {
        TestMethod testMethod = testMethods.get(method);

        if (!testMethod.isParameterised())
            return null;

        return testMethod.describe();
    }

    /**
     * Returns a cached TestMethod object related to the given FrameworkMethod.
     * This object has all the params already retrieved, so use this one and not
     * TestMethod's constructor if you want to have everything retrieved once
     * and cached.
     *
     * @param method
     * @return a cached TestMethod instance
     */
    public TestMethod testMethodFor(FrameworkMethod method) {
        return testMethods.get(method);
    }

}