    001    package org.junit.rules;
    002
    003    import static org.junit.Assert.assertThat;
    004    import static org.junit.Assert.assertThrows;
    005
    006    import java.util.ArrayList;
    007    import java.util.List;
    008    import java.util.concurrent.Callable;
    009
    010    import org.junit.function.ThrowingRunnable;
    011    import org.junit.internal.AssumptionViolatedException;
    012    import org.hamcrest.Matcher;
    013    import org.junit.runners.model.MultipleFailureException;
    014
    015    /**
    016     * The ErrorCollector rule allows execution of a test to continue after the
    017     * first problem is found (for example, to collect _all_ the incorrect rows in a
    018     * table, and report them all at once):
    019     *
    020     * <pre>
    021     * public static class UsesErrorCollectorTwice {
    022     *      &#064;Rule
    023     *      public ErrorCollector collector= new ErrorCollector();
    024     *
    025     * &#064;Test
    026     * public void example() {
    027     *      collector.addError(new Throwable(&quot;first thing went wrong&quot;));
    028     *      collector.addError(new Throwable(&quot;second thing went wrong&quot;));
    029     *      collector.checkThat(getResult(), not(containsString(&quot;ERROR!&quot;)));
    030     *      // all lines will run, and then a combined failure logged at the end.
    031     *     }
    032     * }
    033     * </pre>
    034     *
    035     * @since 4.7
    036     */
    037    public class ErrorCollector extends Verifier {
    038        private List<Throwable> errors = new ArrayList<Throwable>();
    039
    040        @Override
    041        protected void verify() throws Throwable {
    042            MultipleFailureException.assertEmpty(errors);
    043        }
    044
    045        /**
    046         * Adds a Throwable to the table.  Execution continues, but the test will fail at the end.
    047         */
    048        public void addError(Throwable error) {
    049            if (error == null) {
    050                throw new NullPointerException("Error cannot be null");
    051            }
    052            if (error instanceof AssumptionViolatedException) {
    053                AssertionError e = new AssertionError(error.getMessage());
    054                e.initCause(error);
    055                errors.add(e);
    056            } else {
    057                errors.add(error);
    058            }
    059        }
    060
    061        /**
    062         * Adds a failure to the table if {@code matcher} does not match {@code value}.
    063         * Execution continues, but the test will fail at the end if the match fails.
    064         */
    065        public <T> void checkThat(final T value, final Matcher<T> matcher) {
    066            checkThat("", value, matcher);
    067        }
    068
    069        /**
    070         * Adds a failure with the given {@code reason}
    071         * to the table if {@code matcher} does not match {@code value}.
    072         * Execution continues, but the test will fail at the end if the match fails.
    073         */
    074        public <T> void checkThat(final String reason, final T value, final Matcher<T> matcher) {
    075            checkSucceeds(new Callable<Object>() {
    076                public Object call() throws Exception {
    077                    assertThat(reason, value, matcher);
    078                    return value;
    079                }
    080            });
    081        }
    082
    083        /**
    084         * Adds to the table the exception, if any, thrown from {@code callable}.
    085         * Execution continues, but the test will fail at the end if
    086         * {@code callable} threw an exception.
    087         */
    088        public <T> T checkSucceeds(Callable<T> callable) {
    089            try {
    090                return callable.call();
    091            } catch (AssumptionViolatedException e) {
    092                AssertionError error = new AssertionError("Callable threw AssumptionViolatedException");
    093                error.initCause(e);
    094                addError(error);
    095                return null;
    096            } catch (Throwable e) {
    097                addError(e);
    098                return null;
    099            }
    100        }
    101
    102        /**
    103         * Adds a failure to the table if {@code runnable} does not throw an
    104         * exception of type {@code expectedThrowable} when executed.
    105         * Execution continues, but the test will fail at the end if the runnable
    106         * does not throw an exception, or if it throws a different exception.
    107         *
    108         * @param expectedThrowable the expected type of the exception
    109         * @param runnable       a function that is expected to throw an exception when executed
    110         * @since 4.13
    111         */
    112        public void checkThrows(Class<? extends Throwable> expectedThrowable, ThrowingRunnable runnable) {
    113            try {
    114                assertThrows(expectedThrowable, runnable);
    115            } catch (AssertionError e) {
    116                addError(e);
    117            }
    118        }
    119
    120    }