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