• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.lang.annotation.Annotation;
20 import java.lang.reflect.Method;
21 import java.lang.reflect.Modifier;
22 import java.util.ArrayList;
23 import java.util.Collections;
24 import java.util.Comparator;
25 import java.util.List;
26 import junit.framework.AssertionFailedError;
27 import junit.framework.Test;
28 import junit.framework.TestCase;
29 import junit.framework.TestSuite;
30 
31 /**
32  * Transforms a {@link TestCase} based test into another representation.
33  *
34  * <p>This delegates the work of constructing tests and a suite (collection of tests) to a
35  * {@link TestCaseFactory}.
36  *
37  * <p>Separates the scanning of the {@link TestCase} derived class from the construction of the
38  * objects representing the 'suite' and 'test' allowing it to be more easily reused.
39  *
40  * @param <S> the type of the 'suite' component
41  * @param <T> the type of the 'test' component
42  */
43 public class TestCaseTransformer<S,T> {
44 
45     private final TestCaseFactory<S, T> factory;
46 
47     private final Comparator<? super T> comparator;
48 
TestCaseTransformer(TestCaseFactory<S, T> factory, Comparator<? super T> comparator)49     public TestCaseTransformer(TestCaseFactory<S, T> factory, Comparator<? super T> comparator) {
50         this.comparator = comparator;
51         this.factory = factory;
52     }
53 
createSuite(Class<? extends TestCase> testClass)54     public S createSuite(Class<? extends TestCase> testClass) {
55         List<T> tests = testsFromTestCase(testClass);
56         return factory.createSuite(testClass, tests);
57     }
58 
createTest( Class<? extends TestCase> testClass, String methodName, Annotation[] annotations)59     private T createTest(
60             Class<? extends TestCase> testClass, String methodName, Annotation[] annotations) {
61         return factory.createTest(testClass, methodName, annotations);
62     }
63 
createWarning(Class<? extends Test> testClass, String name, Throwable throwable)64     private T createWarning(Class<? extends Test> testClass, String name, Throwable throwable) {
65         return factory.createFailingTest(testClass, name, throwable);
66     }
67 
testsFromTestCase(final Class<? extends TestCase> testClass)68     private List<T> testsFromTestCase(final Class<? extends TestCase> testClass) {
69         List<T> tests = new ArrayList<>();
70 
71         // Check as much as possible in advance to avoid generating multiple error messages for the
72         // same failure.
73         if (factory.eagerClassValidation()) {
74             try {
75                 validateTestClass(testClass);
76             } catch (AssertionFailedError e) {
77                 tests.add(createWarning(testClass, "warning", e));
78                 return tests;
79             }
80         }
81 
82         for (Method method : testClass.getMethods()) {
83             if (!isTestMethod(method)) {
84                 continue;
85             }
86 
87             tests.add(createTest(testClass, method.getName(), method.getAnnotations()));
88         }
89 
90         Collections.sort(tests, comparator);
91 
92         return tests;
93     }
94 
isTestMethod(Method m)95     private static boolean isTestMethod(Method m) {
96         return m.getParameterTypes().length == 0
97                 && m.getName().startsWith("test")
98                 && m.getReturnType().equals(Void.TYPE);
99     }
100 
validateTestClass(Class<?> testClass)101     public static void validateTestClass(Class<?> testClass) {
102         try {
103             TestSuite.getTestConstructor(testClass);
104         } catch (NoSuchMethodException e) {
105             throw new AssertionFailedError(
106                     "Class " + testClass.getName()
107                             + " has no public constructor TestCase(String name) or TestCase()");
108         }
109 
110         if (!Modifier.isPublic(testClass.getModifiers())) {
111             throw new AssertionFailedError("Class " + testClass.getName() + " is not public");
112         }
113     }
114 }
115