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