1 package junit.framework;
2
3 import java.util.Vector;
4 import java.util.Enumeration;
5
6 /***
7 * A <code>TestResult</code> collects the results of executing
8 * a test case. It is an instance of the Collecting Parameter pattern.
9 * The test framework distinguishes between <i>failures</i> and <i>errors</i>.
10 * A failure is anticipated and checked for with assertions. Errors are
11 * unanticipated problems like an <code>ArrayIndexOutOfBoundsException</code>.
12 *
13 * @see Test
14 */
15 public class TestResult extends Object {
16 protected Vector fFailures;
17 protected Vector fErrors;
18 protected Vector fListeners;
19 protected int fRunTests;
20 private boolean fStop;
21
22 public TestResult() {
23 fFailures= new Vector();
24 fErrors= new Vector();
25 fListeners= new Vector();
26 fRunTests= 0;
27 fStop= false;
28 }
29 /***
30 * Adds an error to the list of errors. The passed in exception
31 * caused the error.
32 */
33 public synchronized void addError(Test test, Throwable t) {
34 fErrors.addElement(new TestFailure(test, t));
35 for (Enumeration e= cloneListeners().elements(); e.hasMoreElements(); ) {
36 ((TestListener)e.nextElement()).addError(test, t);
37 }
38 }
39 /***
40 * Adds a failure to the list of failures. The passed in exception
41 * caused the failure.
42 */
43 public synchronized void addFailure(Test test, AssertionFailedError t) {
44 fFailures.addElement(new TestFailure(test, t));
45 for (Enumeration e= cloneListeners().elements(); e.hasMoreElements(); ) {
46 ((TestListener)e.nextElement()).addFailure(test, t);
47 }
48 }
49 /***
50 * Registers a TestListener
51 */
52 public synchronized void addListener(TestListener listener) {
53 fListeners.addElement(listener);
54 }
55 /***
56 * Unregisters a TestListener
57 */
58 public synchronized void removeListener(TestListener listener) {
59 fListeners.removeElement(listener);
60 }
61 /***
62 * Returns a copy of the listeners.
63 */
64 private synchronized Vector cloneListeners() {
65 return (Vector)fListeners.clone();
66 }
67 /***
68 * Informs the result that a test was completed.
69 */
70 public void endTest(Test test) {
71 for (Enumeration e= cloneListeners().elements(); e.hasMoreElements(); ) {
72 ((TestListener)e.nextElement()).endTest(test);
73 }
74 }
75 /***
76 * Gets the number of detected errors.
77 */
78 public synchronized int errorCount() {
79 return fErrors.size();
80 }
81 /***
82 * Returns an Enumeration for the errors
83 */
84 public synchronized Enumeration errors() {
85 return fErrors.elements();
86 }
87 /***
88 * Gets the number of detected failures.
89 */
90 public synchronized int failureCount() {
91 return fFailures.size();
92 }
93 /***
94 * Returns an Enumeration for the failures
95 */
96 public synchronized Enumeration failures() {
97 return fFailures.elements();
98 }
99 /***
100 * Runs a TestCase.
101 */
102 protected void run(final TestCase test) {
103 startTest(test);
104 Protectable p= new Protectable() {
105 public void protect() throws Throwable {
106 test.runBare();
107 }
108 };
109 runProtected(test, p);
110
111 endTest(test);
112 }
113 /***
114 * Gets the number of run tests.
115 */
116 public synchronized int runCount() {
117 return fRunTests;
118 }
119 /***
120 * Runs a TestCase.
121 */
122 public void runProtected(final Test test, Protectable p) {
123 try {
124 p.protect();
125 }
126 catch (AssertionFailedError e) {
127 addFailure(test, e);
128 }
129 catch (ThreadDeath e) {
130 throw e;
131 }
132 catch (Throwable e) {
133 addError(test, e);
134 }
135 }
136 /***
137 * Checks whether the test run should stop
138 */
139 public synchronized boolean shouldStop() {
140 return fStop;
141 }
142 /***
143 * Informs the result that a test will be started.
144 */
145 public void startTest(Test test) {
146 final int count= test.countTestCases();
147 synchronized(this) {
148 fRunTests+= count;
149 }
150 for (Enumeration e= cloneListeners().elements(); e.hasMoreElements(); ) {
151 ((TestListener)e.nextElement()).startTest(test);
152 }
153 }
154 /***
155 * Marks that the test run should stop.
156 */
157 public synchronized void stop() {
158 fStop= true;
159 }
160 /***
161 * Returns whether the entire test was successful or not.
162 */
163 public synchronized boolean wasSuccessful() {
164 return failureCount() == 0 && errorCount() == 0;
165 }
166 }