blob: e01a2b0a72aaa1e3727544b99df62dfe9e8902aa [file] [log] [blame]
package junit.framework;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
/**
* A <code>TestResult</code> collects the results of executing
* a test case. It is an instance of the Collecting Parameter pattern.
* The test framework distinguishes between <i>failures</i> and <i>errors</i>.
* A failure is anticipated and checked for with assertions. Errors are
* unanticipated problems like an {@link ArrayIndexOutOfBoundsException}.
*
* @see Test
*/
public class TestResult {
protected List<TestFailure> fFailures;
protected List<TestFailure> fErrors;
protected List<TestListener> fListeners;
protected int fRunTests;
private boolean fStop;
public TestResult() {
fFailures = new ArrayList<TestFailure>();
fErrors = new ArrayList<TestFailure>();
fListeners = new ArrayList<TestListener>();
fRunTests = 0;
fStop = false;
}
/**
* Adds an error to the list of errors. The passed in exception
* caused the error.
*/
public synchronized void addError(Test test, Throwable e) {
fErrors.add(new TestFailure(test, e));
for (TestListener each : cloneListeners()) {
each.addError(test, e);
}
}
/**
* Adds a failure to the list of failures. The passed in exception
* caused the failure.
*/
public synchronized void addFailure(Test test, AssertionFailedError e) {
fFailures.add(new TestFailure(test, e));
for (TestListener each : cloneListeners()) {
each.addFailure(test, e);
}
}
/**
* Registers a TestListener.
*/
public synchronized void addListener(TestListener listener) {
fListeners.add(listener);
}
/**
* Unregisters a TestListener.
*/
public synchronized void removeListener(TestListener listener) {
fListeners.remove(listener);
}
/**
* Returns a copy of the listeners.
*/
private synchronized List<TestListener> cloneListeners() {
List<TestListener> result = new ArrayList<TestListener>();
result.addAll(fListeners);
return result;
}
/**
* Informs the result that a test was completed.
*/
public void endTest(Test test) {
for (TestListener each : cloneListeners()) {
each.endTest(test);
}
}
/**
* Gets the number of detected errors.
*/
public synchronized int errorCount() {
return fErrors.size();
}
/**
* Returns an Enumeration for the errors.
*/
public synchronized Enumeration<TestFailure> errors() {
return Collections.enumeration(fErrors);
}
/**
* Gets the number of detected failures.
*/
public synchronized int failureCount() {
return fFailures.size();
}
/**
* Returns an Enumeration for the failures.
*/
public synchronized Enumeration<TestFailure> failures() {
return Collections.enumeration(fFailures);
}
/**
* Runs a TestCase.
*/
protected void run(final TestCase test) {
startTest(test);
Protectable p = new Protectable() {
public void protect() throws Throwable {
test.runBare();
}
};
runProtected(test, p);
endTest(test);
}
/**
* Gets the number of run tests.
*/
public synchronized int runCount() {
return fRunTests;
}
/**
* Runs a TestCase.
*/
public void runProtected(final Test test, Protectable p) {
try {
p.protect();
} catch (AssertionFailedError e) {
addFailure(test, e);
} catch (ThreadDeath e) { // don't catch ThreadDeath by accident
throw e;
} catch (Throwable e) {
addError(test, e);
}
}
/**
* Checks whether the test run should stop.
*/
public synchronized boolean shouldStop() {
return fStop;
}
/**
* Informs the result that a test will be started.
*/
public void startTest(Test test) {
final int count = test.countTestCases();
synchronized (this) {
fRunTests += count;
}
for (TestListener each : cloneListeners()) {
each.startTest(test);
}
}
/**
* Marks that the test run should stop.
*/
public synchronized void stop() {
fStop = true;
}
/**
* Returns whether the entire test was successful or not.
*/
public synchronized boolean wasSuccessful() {
return failureCount() == 0 && errorCount() == 0;
}
}