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