Home | History | Annotate | Download | only in junit3
      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 
     49     public TestCaseTransformer(TestCaseFactory<S, T> factory, Comparator<? super T> comparator) {
     50         this.comparator = comparator;
     51         this.factory = factory;
     52     }
     53 
     54     public S createSuite(Class<? extends TestCase> testClass) {
     55         List<T> tests = testsFromTestCase(testClass);
     56         return factory.createSuite(testClass, tests);
     57     }
     58 
     59     private T createTest(
     60             Class<? extends TestCase> testClass, String methodName, Annotation[] annotations) {
     61         return factory.createTest(testClass, methodName, annotations);
     62     }
     63 
     64     private T createWarning(Class<? extends Test> testClass, String name, Throwable throwable) {
     65         return factory.createFailingTest(testClass, name, throwable);
     66     }
     67 
     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 
     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 
    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