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