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
28 private OldTestClassAdaptingListener(RunNotifier notifier) {
29 this.notifier = notifier;
30 }
31
32 public void endTest(Test test) {
33 notifier.fireTestFinished(asDescription(test));
34 }
35
36 public void startTest(Test test) {
37 notifier.fireTestStarted(asDescription(test));
38 }
39
40
41 public void addError(Test test, Throwable e) {
42 Failure failure = new Failure(asDescription(test), e);
43 notifier.fireTestFailure(failure);
44 }
45
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
54 private Class<? extends Test> getEffectiveClass(Test test) {
55 return test.getClass();
56 }
57
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
66 public void addFailure(Test test, AssertionFailedError t) {
67 addError(test, t);
68 }
69 }
70
71 private volatile Test test;
72
73 public JUnit38ClassRunner(Class<?> klass) {
74 this(new TestSuite(klass.asSubclass(TestCase.class)));
75 }
76
77 public JUnit38ClassRunner(Test test) {
78 super();
79 setTest(test);
80 }
81
82 @Override
83 public void run(RunNotifier notifier) {
84 TestResult result = new TestResult();
85 result.addListener(createAdaptingListener(notifier));
86 getTest().run(result);
87 }
88
89 public TestListener createAdaptingListener(final RunNotifier notifier) {
90 return new OldTestClassAdaptingListener(notifier);
91 }
92
93 @Override
94 public Description getDescription() {
95 return makeDescription(getTest());
96 }
97
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
121 return Description.createSuiteDescription(test.getClass());
122 }
123 }
124
125
126
127
128
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
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
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
166 public void sort(Sorter sorter) {
167 if (getTest() instanceof Sortable) {
168 Sortable adapter = (Sortable) getTest();
169 adapter.sort(sorter);
170 }
171 }
172
173 private void setTest(Test test) {
174 this.test = test;
175 }
176
177 private Test getTest() {
178 return test;
179 }
180 }