001package org.junit.rules;
002
003import static org.junit.Assert.assertThat;
004import static org.junit.Assert.assertThrows;
005
006import java.util.ArrayList;
007import java.util.List;
008import java.util.concurrent.Callable;
009
010import org.junit.function.ThrowingRunnable;
011import org.junit.internal.AssumptionViolatedException;
012import org.hamcrest.Matcher;
013import 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 */
037public 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}