1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package vogar.target.junit.junit3;
18 
19 import java.util.List;
20 import junit.framework.Test;
21 import junit.framework.TestCase;
22 import junit.framework.TestSuite;
23 import org.junit.internal.runners.JUnit38ClassRunner;
24 import org.junit.runner.Description;
25 import org.junit.runner.Runner;
26 import org.junit.runners.Suite;
27 import org.junit.runners.model.InitializationError;
28 import vogar.target.junit.DescribableStatement;
29 import vogar.target.junit.ErrorRunner;
30 import vogar.target.junit.ExtendedSuiteRunner;
31 import vogar.target.junit.ParentStatementRunner;
32 import vogar.target.junit.RunnerParams;
33 import vogar.target.junit.StatementRunner;
34 
35 /**
36  * Transforms a hierarchy of {@link Test} objects into a hierarchy of {@link Runner} objects.
37  *
38  * <p>This provides some of the functionality provided by {@link JUnit38ClassRunner}; see
39  * {@link TestCaseRunnerFactory} for an overview of that class.
40  *
41  * <p>Just like {@link TestCaseRunnerFactory} this converts the JUnit3 classes into JUnit4
42  * structures and then runs them rather than run them as JUnit3 and adapt the events back into
43  * JUnit4 event model. This traverses the hierarchy of {@link Test} and converts them directly into
44  * {@link Runner} classes.
45  *
46  * <ol>
47  * <li>A {@link TestSuite} is converted into a {@link Suite}. If it contained {@link TestCase}
48  * instances that all had the same class and so were likely created by calling
49  * {@link TestSuite#addTestSuite(Class)} or calling any of the {@link TestSuite} constructors that
50  * take a Class then it should probably be converted to a {@link ParentStatementRunner}</li>
51  * <li>A {@link TestCase} is converted into a {@link StatementRunner}.</li>
52  * <li>No other {@link Test} classes are supported. They could be but they would require something
53  * like {@link JUnit38ClassRunner}.</li>
54  * </ol>
55  */
56 public class TestSuiteRunnerFactory implements TestSuiteFactory<Runner> {
57 
58     private final RunnerParams runnerParams;
59 
TestSuiteRunnerFactory(RunnerParams runnerParams)60     public TestSuiteRunnerFactory(RunnerParams runnerParams) {
61         this.runnerParams = runnerParams;
62     }
63 
64     @Override
createSuite(String name, List<Runner> children)65     public Runner createSuite(String name, List<Runner> children) {
66         try {
67             return new ExtendedSuiteRunner(name, children);
68         } catch (InitializationError e) {
69             throw new IllegalStateException(e);
70         }
71     }
72 
73     @Override
createTestCase(final TestCase testCase, Description description)74     public Runner createTestCase(final TestCase testCase, Description description) {
75         return new StatementRunner(runnerParams,
76                 new DescribableStatement(description) {
77                     @Override
78                     public void evaluate() throws Throwable {
79                         testCase.runBare();
80                     }
81                 });
82     }
83 
84     @Override
85     public Runner createCustomTest(Test test, Description description) {
86         return new ErrorRunner(description,
87                 new IllegalStateException("Unknown suite() result: " + test));
88     }
89 }
90