Home | History | Annotate | Download | only in suitebuilder
      1 /*
      2  * Copyright (C) 2008 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 android.test.suitebuilder;
     18 
     19 import junit.framework.TestCase;
     20 
     21 import java.lang.annotation.Annotation;
     22 import java.lang.reflect.Constructor;
     23 import java.lang.reflect.InvocationTargetException;
     24 import java.lang.reflect.Method;
     25 
     26 /**
     27  * Represents a test to be run. Can be constructed without instantiating the TestCase or even
     28  * loading the class.
     29  */
     30 public class TestMethod {
     31 
     32     private final String enclosingClassname;
     33     private final String testMethodName;
     34     private final Class<? extends TestCase> enclosingClass;
     35 
     36     public TestMethod(Method method, Class<? extends TestCase> enclosingClass) {
     37         this(method.getName(), enclosingClass);
     38     }
     39 
     40     public TestMethod(String methodName, Class<? extends TestCase> enclosingClass) {
     41         this.enclosingClass = enclosingClass;
     42         this.enclosingClassname = enclosingClass.getName();
     43         this.testMethodName = methodName;
     44     }
     45 
     46     public TestMethod(TestCase testCase) {
     47         this(testCase.getName(), testCase.getClass());
     48     }
     49 
     50     public String getName() {
     51         return testMethodName;
     52     }
     53 
     54     public String getEnclosingClassname() {
     55         return enclosingClassname;
     56     }
     57 
     58     public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
     59         try {
     60             return getEnclosingClass().getMethod(getName()).getAnnotation(annotationClass);
     61         } catch (NoSuchMethodException e) {
     62             return null;
     63         }
     64     }
     65 
     66     @SuppressWarnings("unchecked")
     67     public Class<? extends TestCase> getEnclosingClass() {
     68         return enclosingClass;
     69     }
     70 
     71     public TestCase createTest()
     72             throws InvocationTargetException, IllegalAccessException, InstantiationException {
     73         return instantiateTest(enclosingClass, testMethodName);
     74     }
     75 
     76     @SuppressWarnings("unchecked")
     77     private TestCase instantiateTest(Class testCaseClass, String testName)
     78             throws InvocationTargetException, IllegalAccessException, InstantiationException {
     79         Constructor[] constructors = testCaseClass.getConstructors();
     80 
     81         if (constructors.length == 0) {
     82             return instantiateTest(testCaseClass.getSuperclass(), testName);
     83         } else {
     84             for (Constructor constructor : constructors) {
     85                 Class[] params = constructor.getParameterTypes();
     86                 if (noargsConstructor(params)) {
     87                     TestCase test = ((Constructor<? extends TestCase>) constructor).newInstance();
     88                     // JUnit will run just the one test if you call
     89                     // {@link TestCase#setName(String)}
     90                     test.setName(testName);
     91                     return test;
     92                 } else if (singleStringConstructor(params)) {
     93                     return ((Constructor<? extends TestCase>) constructor)
     94                             .newInstance(testName);
     95                 }
     96             }
     97         }
     98         throw new RuntimeException("Unable to locate a constructor for "
     99                 + testCaseClass.getName());
    100     }
    101 
    102     private boolean singleStringConstructor(Class[] params) {
    103         return (params.length == 1) && (params[0].equals(String.class));
    104     }
    105 
    106     private boolean noargsConstructor(Class[] params) {
    107         return params.length == 0;
    108     }
    109 
    110     @Override
    111     public boolean equals(Object o) {
    112         if (this == o) {
    113             return true;
    114         }
    115         if (o == null || getClass() != o.getClass()) {
    116             return false;
    117         }
    118 
    119         TestMethod that = (TestMethod) o;
    120 
    121         if (enclosingClassname != null
    122                 ? !enclosingClassname.equals(that.enclosingClassname)
    123                 : that.enclosingClassname != null) {
    124             return false;
    125         }
    126         if (testMethodName != null
    127                 ? !testMethodName.equals(that.testMethodName)
    128                 : that.testMethodName != null) {
    129             return false;
    130         }
    131         return true;
    132     }
    133 
    134     @Override
    135     public int hashCode() {
    136         int result;
    137         result = (enclosingClassname != null ? enclosingClassname.hashCode() : 0);
    138         result = 31 * result + (testMethodName != null ? testMethodName.hashCode() : 0);
    139         return result;
    140     }
    141 
    142     @Override
    143     public String toString() {
    144         return enclosingClassname + "." + testMethodName;
    145     }
    146 }
    147