001package org.junit.rules;
002
003import static org.junit.Assert.assertThat;
004
005import java.util.ArrayList;
006import java.util.List;
007import java.util.concurrent.Callable;
008
009import org.hamcrest.Matcher;
010import org.junit.runners.model.MultipleFailureException;
011
012/**
013 * The ErrorCollector rule allows execution of a test to continue after the
014 * first problem is found (for example, to collect _all_ the incorrect rows in a
015 * table, and report them all at once):
016 *
017 * <pre>
018 * public static class UsesErrorCollectorTwice {
019 *      &#064;Rule
020 *      public ErrorCollector collector= new ErrorCollector();
021 *
022 * &#064;Test
023 * public void example() {
024 *      collector.addError(new Throwable(&quot;first thing went wrong&quot;));
025 *      collector.addError(new Throwable(&quot;second thing went wrong&quot;));
026 *      collector.checkThat(getResult(), not(containsString(&quot;ERROR!&quot;)));
027 *      // all lines will run, and then a combined failure logged at the end.
028 *     }
029 * }
030 * </pre>
031 *
032 * @since 4.7
033 */
034public class ErrorCollector extends Verifier {
035    private List<Throwable> errors = new ArrayList<Throwable>();
036
037    @Override
038    protected void verify() throws Throwable {
039        MultipleFailureException.assertEmpty(errors);
040    }
041
042    /**
043     * Adds a Throwable to the table.  Execution continues, but the test will fail at the end.
044     */
045    public void addError(Throwable error) {
046        errors.add(error);
047    }
048
049    /**
050     * Adds a failure to the table if {@code matcher} does not match {@code value}.
051     * Execution continues, but the test will fail at the end if the match fails.
052     */
053    public <T> void checkThat(final T value, final Matcher<T> matcher) {
054        checkThat("", value, matcher);
055    }
056
057    /**
058     * Adds a failure with the given {@code reason}
059     * to the table if {@code matcher} does not match {@code value}.
060     * Execution continues, but the test will fail at the end if the match fails.
061     */
062    public <T> void checkThat(final String reason, final T value, final Matcher<T> matcher) {
063        checkSucceeds(new Callable<Object>() {
064            public Object call() throws Exception {
065                assertThat(reason, value, matcher);
066                return value;
067            }
068        });
069    }
070
071    /**
072     * Adds to the table the exception, if any, thrown from {@code callable}.
073     * Execution continues, but the test will fail at the end if
074     * {@code callable} threw an exception.
075     */
076    public Object checkSucceeds(Callable<Object> callable) {
077        try {
078            return callable.call();
079        } catch (Throwable e) {
080            addError(e);
081            return null;
082        }
083    }
084}