1 package android.support.test.internal.runner.junit3; 2 3 import junit.extensions.TestDecorator; 4 import junit.framework.AssertionFailedError; 5 import junit.framework.Test; 6 import junit.framework.TestCase; 7 import junit.framework.TestListener; 8 import junit.framework.TestResult; 9 import junit.framework.TestSuite; 10 11 import org.junit.runner.Describable; 12 import org.junit.runner.Description; 13 import org.junit.runner.Runner; 14 import org.junit.runner.manipulation.Filter; 15 import org.junit.runner.manipulation.Filterable; 16 import org.junit.runner.manipulation.NoTestsRemainException; 17 import org.junit.runner.manipulation.Sortable; 18 import org.junit.runner.manipulation.Sorter; 19 import org.junit.runner.notification.Failure; 20 import org.junit.runner.notification.RunNotifier; 21 22 import java.lang.annotation.Annotation; 23 import java.lang.reflect.Method; 24 25 // this is a virtually identical copy of org.junit.internal.runner.JUnit38ClassRunner 26 // from junit 4.12-snapshot. Copied here so android.support.test can work 27 // with JUnit 4.10+ and pick up the annotation filtering fixes made in 4.12. 28 public class JUnit38ClassRunner extends Runner implements Filterable, Sortable { 29 private static final class OldTestClassAdaptingListener implements 30 TestListener { 31 private final RunNotifier fNotifier; 32 33 private OldTestClassAdaptingListener(RunNotifier notifier) { 34 fNotifier = notifier; 35 } 36 37 @Override 38 public void endTest(Test test) { 39 fNotifier.fireTestFinished(asDescription(test)); 40 } 41 42 @Override 43 public void startTest(Test test) { 44 fNotifier.fireTestStarted(asDescription(test)); 45 } 46 47 // Implement junit.framework.TestListener 48 @Override 49 public void addError(Test test, Throwable t) { 50 Failure failure = new Failure(asDescription(test), t); 51 fNotifier.fireTestFailure(failure); 52 } 53 54 private Description asDescription(Test test) { 55 if (test instanceof Describable) { 56 Describable facade = (Describable) test; 57 return facade.getDescription(); 58 } 59 if (test instanceof TestCase) { 60 return makeDescription(test); 61 } 62 return Description.createTestDescription(getEffectiveClass(test), test.toString()); 63 } 64 65 private Class<? extends Test> getEffectiveClass(Test test) { 66 return test.getClass(); 67 } 68 69 @Override 70 public void addFailure(Test test, AssertionFailedError t) { 71 addError(test, t); 72 } 73 } 74 75 private volatile Test fTest; 76 77 public JUnit38ClassRunner(Class<?> klass) { 78 this(new TestSuite(klass.asSubclass(TestCase.class))); 79 } 80 81 public JUnit38ClassRunner(Test test) { 82 super(); 83 setTest(test); 84 } 85 86 @Override 87 public void run(RunNotifier notifier) { 88 TestResult result = new TestResult(); 89 result.addListener(createAdaptingListener(notifier)); 90 getTest().run(result); 91 } 92 93 public TestListener createAdaptingListener(final RunNotifier notifier) { 94 return new OldTestClassAdaptingListener(notifier); 95 } 96 97 @Override 98 public Description getDescription() { 99 return makeDescription(getTest()); 100 } 101 102 // android-changed - change from private so it can be accessed when filtering AndroidTestSuites 103 static Description makeDescription(Test test) { 104 if (test instanceof TestCase) { 105 TestCase tc = (TestCase) test; 106 return Description.createTestDescription(tc.getClass(), tc.getName(), 107 getAnnotations(tc)); 108 } else if (test instanceof TestSuite) { 109 TestSuite ts = (TestSuite) test; 110 String name = ts.getName() == null ? createSuiteDescription(ts) : ts.getName(); 111 Description description = Description.createSuiteDescription(name); 112 int n = ts.testCount(); 113 for (int i = 0; i < n; i++) { 114 Description made = makeDescription(ts.testAt(i)); 115 description.addChild(made); 116 } 117 return description; 118 } else if (test instanceof Describable) { 119 Describable adapter = (Describable) test; 120 return adapter.getDescription(); 121 } else if (test instanceof TestDecorator) { 122 TestDecorator decorator = (TestDecorator) test; 123 return makeDescription(decorator.getTest()); 124 } else { 125 // This is the best we can do in this case 126 return Description.createSuiteDescription(test.getClass()); 127 } 128 } 129 130 /** 131 * Get the annotations associated with given TestCase. 132 * @param test the TestCase. 133 */ 134 private static Annotation[] getAnnotations(TestCase test) { 135 try { 136 Method m = test.getClass().getMethod(test.getName()); 137 return m.getDeclaredAnnotations(); 138 } catch (SecurityException e) { 139 } catch (NoSuchMethodException e) { 140 } 141 return new Annotation[0]; 142 } 143 144 private static String createSuiteDescription(TestSuite ts) { 145 int count = ts.countTestCases(); 146 String example = count == 0 ? "" : String.format(" [example: %s]", ts.testAt(0)); 147 return String.format("TestSuite with %s tests%s", count, example); 148 } 149 150 @Override 151 public void filter(Filter filter) throws NoTestsRemainException { 152 if (getTest() instanceof Filterable) { 153 Filterable adapter = (Filterable) getTest(); 154 adapter.filter(filter); 155 } else if (getTest() instanceof TestSuite) { 156 TestSuite suite = (TestSuite) getTest(); 157 TestSuite filtered = new TestSuite(suite.getName()); 158 int n = suite.testCount(); 159 for (int i = 0; i < n; i++) { 160 Test test = suite.testAt(i); 161 if (filter.shouldRun(makeDescription(test))) { 162 filtered.addTest(test); 163 } 164 } 165 setTest(filtered); 166 if (filtered.testCount() == 0) { 167 throw new NoTestsRemainException(); 168 } 169 } 170 } 171 172 @Override 173 public void sort(Sorter sorter) { 174 if (getTest() instanceof Sortable) { 175 Sortable adapter = (Sortable) getTest(); 176 adapter.sort(sorter); 177 } 178 } 179 180 private void setTest(Test test) { 181 fTest = test; 182 } 183 184 private Test getTest() { 185 return fTest; 186 } 187 } 188