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