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    }