1
|
1 |
package org.junit.runner.notification;
|
|
2 |
|
|
3 |
import java.util.ArrayList;
|
|
4 |
import java.util.Iterator;
|
|
5 |
import java.util.List;
|
|
6 |
|
|
7 |
import org.junit.runner.Description;
|
|
8 |
import org.junit.runner.Result;
|
|
9 |
|
|
10 |
/**
|
|
11 |
* If you write custom runners, you may need to notify JUnit of your progress running tests.
|
|
12 |
* Do this by invoking the <code>RunNotifier</code> passed to your implementation of
|
|
13 |
* {@link org.junit.runner.Runner#run(RunNotifier)}. Future evolution of this class is likely to
|
|
14 |
* move {@link #fireTestRunStarted(Description)} and {@link #fireTestRunFinished(Result)}
|
|
15 |
* to a separate class since they should only be called once per run.
|
|
16 |
*/
|
|
17 |
public class RunNotifier {
|
|
18 |
private List<RunListener> fListeners= new ArrayList<RunListener>();
|
|
19 |
private boolean fPleaseStop= false;
|
|
20 |
|
|
21 |
/** Internal use only
|
|
22 |
*/
|
|
23 |
public void addListener(RunListener listener) {
|
|
24 |
fListeners.add(listener);
|
|
25 |
}
|
|
26 |
|
|
27 |
/** Internal use only
|
|
28 |
*/
|
|
29 |
public void removeListener(RunListener listener) {
|
|
30 |
fListeners.remove(listener);
|
|
31 |
}
|
|
32 |
|
|
33 |
private abstract class SafeNotifier {
|
|
34 |
void run() {
|
|
35 |
for (Iterator<RunListener> all= fListeners.iterator(); all.hasNext();) {
|
|
36 |
try {
|
|
37 |
notifyListener(all.next());
|
|
38 |
} catch (Exception e) {
|
|
39 |
all.remove(); // Remove the offending listener first to avoid an infinite loop
|
|
40 |
fireTestFailure(new Failure(Description.TEST_MECHANISM, e));
|
|
41 |
}
|
|
42 |
}
|
|
43 |
}
|
|
44 |
|
|
45 |
abstract protected void notifyListener(RunListener each) throws Exception;
|
|
46 |
}
|
|
47 |
|
|
48 |
/**
|
|
49 |
* Do not invoke.
|
|
50 |
*/
|
|
51 |
public void fireTestRunStarted(final Description description) {
|
|
52 |
new SafeNotifier() {
|
|
53 |
@Override
|
|
54 |
protected void notifyListener(RunListener each) throws Exception {
|
|
55 |
each.testRunStarted(description);
|
|
56 |
};
|
|
57 |
}.run();
|
|
58 |
}
|
|
59 |
|
|
60 |
/**
|
|
61 |
* Do not invoke.
|
|
62 |
*/
|
|
63 |
public void fireTestRunFinished(final Result result) {
|
|
64 |
new SafeNotifier() {
|
|
65 |
@Override
|
|
66 |
protected void notifyListener(RunListener each) throws Exception {
|
|
67 |
each.testRunFinished(result);
|
|
68 |
};
|
|
69 |
}.run();
|
|
70 |
}
|
|
71 |
|
|
72 |
/**
|
|
73 |
* Invoke to tell listeners that an atomic test is about to start.
|
|
74 |
* @param description the description of the atomic test (generally a class and method name)
|
|
75 |
* @throws StoppedByUserException thrown if a user has requested that the test run stop
|
|
76 |
*/
|
|
77 |
public void fireTestStarted(final Description description) throws StoppedByUserException {
|
|
78 |
if (fPleaseStop)
|
|
79 |
throw new StoppedByUserException();
|
|
80 |
new SafeNotifier() {
|
|
81 |
@Override
|
|
82 |
protected void notifyListener(RunListener each) throws Exception {
|
|
83 |
each.testStarted(description);
|
|
84 |
};
|
|
85 |
}.run();
|
|
86 |
}
|
|
87 |
|
|
88 |
/**
|
|
89 |
* Invoke to tell listeners that an atomic test failed.
|
|
90 |
* @param failure the description of the test that failed and the exception thrown
|
|
91 |
*/
|
|
92 |
public void fireTestFailure(final Failure failure) {
|
|
93 |
new SafeNotifier() {
|
|
94 |
@Override
|
|
95 |
protected void notifyListener(RunListener each) throws Exception {
|
|
96 |
each.testFailure(failure);
|
|
97 |
};
|
|
98 |
}.run();
|
|
99 |
}
|
|
100 |
|
|
101 |
/**
|
|
102 |
* Invoke to tell listeners that an atomic test was ignored.
|
|
103 |
* @param description the description of the ignored test
|
|
104 |
*/
|
|
105 |
public void fireTestIgnored(final Description description) {
|
|
106 |
new SafeNotifier() {
|
|
107 |
@Override
|
|
108 |
protected void notifyListener(RunListener each) throws Exception {
|
|
109 |
each.testIgnored(description);
|
|
110 |
};
|
|
111 |
}.run();
|
|
112 |
}
|
|
113 |
|
|
114 |
/**
|
|
115 |
* Invoke to tell listeners that an atomic test finished. Always invoke
|
|
116 |
* {@link #fireTestFinished(Description)} if you invoke {@link #fireTestStarted(Description)}
|
|
117 |
* as listeners are likely to expect them to come in pairs.
|
|
118 |
* @param description the description of the test that finished
|
|
119 |
*/
|
|
120 |
public void fireTestFinished(final Description description) {
|
|
121 |
new SafeNotifier() {
|
|
122 |
@Override
|
|
123 |
protected void notifyListener(RunListener each) throws Exception {
|
|
124 |
each.testFinished(description);
|
|
125 |
};
|
|
126 |
}.run();
|
|
127 |
}
|
|
128 |
|
|
129 |
/**
|
|
130 |
* Ask that the tests run stop before starting the next test. Phrased politely because
|
|
131 |
* the test currently running will not be interrupted. It seems a little odd to put this
|
|
132 |
* functionality here, but the <code>RunNotifier</code> is the only object guaranteed
|
|
133 |
* to be shared amongst the many runners involved.
|
|
134 |
*/
|
|
135 |
public void pleaseStop() {
|
|
136 |
fPleaseStop= true;
|
|
137 |
}
|
|
138 |
|
|
139 |
/**
|
|
140 |
* Internal use only. The Result's listener must be first.
|
|
141 |
*/
|
|
142 |
public void addFirstListener(RunListener listener) {
|
|
143 |
fListeners.add(0, listener);
|
|
144 |
}
|
|
145 |
|
|
146 |
public void testAborted(Description description, Throwable cause) {
|
|
147 |
fireTestStarted(description);
|
|
148 |
fireTestFailure(new Failure(description, cause));
|
|
149 |
fireTestFinished(description);
|
|
150 |
}
|
|
151 |
} |