    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 {
    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 e) {
    037            fErrors.add(new TestFailure(test, e));
    038            for (TestListener each : cloneListeners()) {
    039                each.addError(test, e);
    040            }
    041        }
    042
    043        /**
    044         * Adds a failure to the list of failures. The passed in exception
    045         * caused the failure.
    046         */
    047        public synchronized void addFailure(Test test, AssertionFailedError e) {
    048            fFailures.add(new TestFailure(test, e));
    049            for (TestListener each : cloneListeners()) {
    050                each.addFailure(test, e);
    051            }
    052        }
    053
    054        /**
    055         * Registers a TestListener.
    056         */
    057        public synchronized void addListener(TestListener listener) {
    058            fListeners.add(listener);
    059        }
    060
    061        /**
    062         * Unregisters a TestListener.
    063         */
    064        public synchronized void removeListener(TestListener listener) {
    065            fListeners.remove(listener);
    066        }
    067
    068        /**
    069         * Returns a copy of the listeners.
    070         */
    071        private synchronized List<TestListener> cloneListeners() {
    072            List<TestListener> result = new ArrayList<TestListener>();
    073            result.addAll(fListeners);
    074            return result;
    075        }
    076
    077        /**
    078         * Informs the result that a test was completed.
    079         */
    080        public void endTest(Test test) {
    081            for (TestListener each : cloneListeners()) {
    082                each.endTest(test);
    083            }
    084        }
    085
    086        /**
    087         * Gets the number of detected errors.
    088         */
    089        public synchronized int errorCount() {
    090            return fErrors.size();
    091        }
    092
    093        /**
    094         * Returns an Enumeration for the errors.
    095         */
    096        public synchronized Enumeration<TestFailure> errors() {
    097            return Collections.enumeration(fErrors);
    098        }
    099
    100
    101        /**
    102         * Gets the number of detected failures.
    103         */
    104        public synchronized int failureCount() {
    105            return fFailures.size();
    106        }
    107
    108        /**
    109         * Returns an Enumeration for the failures.
    110         */
    111        public synchronized Enumeration<TestFailure> failures() {
    112            return Collections.enumeration(fFailures);
    113        }
    114
    115        /**
    116         * Runs a TestCase.
    117         */
    118        protected void run(final TestCase test) {
    119            startTest(test);
    120            Protectable p = new Protectable() {
    121                public void protect() throws Throwable {
    122                    test.runBare();
    123                }
    124            };
    125            runProtected(test, p);
    126
    127            endTest(test);
    128        }
    129
    130        /**
    131         * Gets the number of run tests.
    132         */
    133        public synchronized int runCount() {
    134            return fRunTests;
    135        }
    136
    137        /**
    138         * Runs a TestCase.
    139         */
    140        public void runProtected(final Test test, Protectable p) {
    141            try {
    142                p.protect();
    143            } catch (AssertionFailedError e) {
    144                addFailure(test, e);
    145            } catch (ThreadDeath e) { // don't catch ThreadDeath by accident
    146                throw e;
    147            } catch (Throwable e) {
    148                addError(test, e);
    149            }
    150        }
    151
    152        /**
    153         * Checks whether the test run should stop.
    154         */
    155        public synchronized boolean shouldStop() {
    156            return fStop;
    157        }
    158
    159        /**
    160         * Informs the result that a test will be started.
    161         */
    162        public void startTest(Test test) {
    163            final int count = test.countTestCases();
    164            synchronized (this) {
    165                fRunTests += count;
    166            }
    167            for (TestListener each : cloneListeners()) {
    168                each.startTest(test);
    169            }
    170        }
    171
    172        /**
    173         * Marks that the test run should stop.
    174         */
    175        public synchronized void stop() {
    176            fStop = true;
    177        }
    178
    179        /**
    180         * Returns whether the entire test was successful or not.
    181         */
    182        public synchronized boolean wasSuccessful() {
    183            return failureCount() == 0 && errorCount() == 0;
    184        }
    185    }