001: package junit.framework;
002:
003: import java.util.ArrayList;
004: import java.util.Collections;
005: import java.util.Enumeration;
006: import java.util.List;
007:
008: /**
009: * A <code>TestResult</code> collects the results of executing
010: * a test case. It is an instance of the Collecting Parameter pattern.
011: * The test framework distinguishes between <i>failures</i> and <i>errors</i>.
012: * A failure is anticipated and checked for with assertions. Errors are
013: * unanticipated problems like an {@link ArrayIndexOutOfBoundsException}.
014: *
015: * @see Test
016: */
017: public class TestResult extends Object {
018: protected List<TestFailure> fFailures;
019: protected List<TestFailure> fErrors;
020: protected List<TestListener> fListeners;
021: protected int fRunTests;
022: private boolean fStop;
023:
024: public TestResult() {
025: fFailures = new ArrayList<TestFailure>();
026: fErrors = new ArrayList<TestFailure>();
027: fListeners = new ArrayList<TestListener>();
028: fRunTests = 0;
029: fStop = false;
030: }
031:
032: /**
033: * Adds an error to the list of errors. The passed in exception
034: * caused the error.
035: */
036: public synchronized void addError(Test test, Throwable t) {
037: fErrors.add(new TestFailure(test, t));
038: for (TestListener each : cloneListeners())
039: each.addError(test, t);
040: }
041:
042: /**
043: * Adds a failure to the list of failures. The passed in exception
044: * caused the failure.
045: */
046: public synchronized void addFailure(Test test,
047: AssertionFailedError t) {
048: fFailures.add(new TestFailure(test, t));
049: for (TestListener each : cloneListeners())
050: each.addFailure(test, t);
051: }
052:
053: /**
054: * Registers a TestListener
055: */
056: public synchronized void addListener(TestListener listener) {
057: fListeners.add(listener);
058: }
059:
060: /**
061: * Unregisters a TestListener
062: */
063: public synchronized void removeListener(TestListener listener) {
064: fListeners.remove(listener);
065: }
066:
067: /**
068: * Returns a copy of the listeners.
069: */
070: private synchronized List<TestListener> cloneListeners() {
071: List<TestListener> result = new ArrayList<TestListener>();
072: result.addAll(fListeners);
073: return result;
074: }
075:
076: /**
077: * Informs the result that a test was completed.
078: */
079: public void endTest(Test test) {
080: for (TestListener each : cloneListeners())
081: each.endTest(test);
082: }
083:
084: /**
085: * Gets the number of detected errors.
086: */
087: public synchronized int errorCount() {
088: return fErrors.size();
089: }
090:
091: /**
092: * Returns an Enumeration for the errors
093: */
094: public synchronized Enumeration<TestFailure> errors() {
095: return Collections.enumeration(fErrors);
096: }
097:
098: /**
099: * Gets the number of detected failures.
100: */
101: public synchronized int failureCount() {
102: return fFailures.size();
103: }
104:
105: /**
106: * Returns an Enumeration for the failures
107: */
108: public synchronized Enumeration<TestFailure> failures() {
109: return Collections.enumeration(fFailures);
110: }
111:
112: /**
113: * Runs a TestCase.
114: */
115: protected void run(final TestCase test) {
116: startTest(test);
117: Protectable p = new Protectable() {
118: public void protect() throws Throwable {
119: test.runBare();
120: }
121: };
122: runProtected(test, p);
123:
124: endTest(test);
125: }
126:
127: /**
128: * Gets the number of run tests.
129: */
130: public synchronized int runCount() {
131: return fRunTests;
132: }
133:
134: /**
135: * Runs a TestCase.
136: */
137: public void runProtected(final Test test, Protectable p) {
138: try {
139: p.protect();
140: } catch (AssertionFailedError e) {
141: addFailure(test, e);
142: } catch (ThreadDeath e) { // don't catch ThreadDeath by accident
143: throw e;
144: } catch (Throwable e) {
145: addError(test, e);
146: }
147: }
148:
149: /**
150: * Checks whether the test run should stop
151: */
152: public synchronized boolean shouldStop() {
153: return fStop;
154: }
155:
156: /**
157: * Informs the result that a test will be started.
158: */
159: public void startTest(Test test) {
160: final int count = test.countTestCases();
161: synchronized (this ) {
162: fRunTests += count;
163: }
164: for (TestListener each : cloneListeners())
165: each.startTest(test);
166: }
167:
168: /**
169: * Marks that the test run should stop.
170: */
171: public synchronized void stop() {
172: fStop = true;
173: }
174:
175: /**
176: * Returns whether the entire test was successful or not.
177: */
178: public synchronized boolean wasSuccessful() {
179: return failureCount() == 0 && errorCount() == 0;
180: }
181: }
|