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         * @deprecated use {@code org.hamcrest.junit.ErrorCollector.checkThat()}
066         */
067        @Deprecated
068        public <T> void checkThat(final T value, final Matcher<T> matcher) {
069            checkThat("", value, matcher);
070        }
071    
072        /**
073         * Adds a failure with the given {@code reason}
074         * to the table if {@code matcher} does not match {@code value}.
075         * Execution continues, but the test will fail at the end if the match fails.
076         *
077         * @deprecated use {@code org.hamcrest.junit.ErrorCollector.checkThat()}
078         */
079        @Deprecated
080        public <T> void checkThat(final String reason, final T value, final Matcher<T> matcher) {
081            checkSucceeds(new Callable<Object>() {
082                public Object call() throws Exception {
083                    assertThat(reason, value, matcher);
084                    return value;
085                }
086            });
087        }
088    
089        /**
090         * Adds to the table the exception, if any, thrown from {@code callable}.
091         * Execution continues, but the test will fail at the end if
092         * {@code callable} threw an exception.
093         */
094        public <T> T checkSucceeds(Callable<T> callable) {
095            try {
096                return callable.call();
097            } catch (AssumptionViolatedException e) {
098                AssertionError error = new AssertionError("Callable threw AssumptionViolatedException");
099                error.initCause(e);
100                addError(error);
101                return null;
102            } catch (Throwable e) {
103                addError(e);
104                return null;
105            }
106        }
107    
108        /**
109         * Adds a failure to the table if {@code runnable} does not throw an
110         * exception of type {@code expectedThrowable} when executed.
111         * Execution continues, but the test will fail at the end if the runnable
112         * does not throw an exception, or if it throws a different exception.
113         *
114         * @param expectedThrowable the expected type of the exception
115         * @param runnable       a function that is expected to throw an exception when executed
116         * @since 4.13
117         */
118        public void checkThrows(Class<? extends Throwable> expectedThrowable, ThrowingRunnable runnable) {
119            try {
120                assertThrows(expectedThrowable, runnable);
121            } catch (AssertionError e) {
122                addError(e);
123            }
124        }
125    
126    }