001 package org.junit.rules;
002
003 import static org.junit.Assert.assertThat;
004
005 import java.util.ArrayList;
006 import java.util.List;
007 import java.util.concurrent.Callable;
008
009 import org.hamcrest.Matcher;
010 import 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 * @Rule
020 * public ErrorCollector collector= new ErrorCollector();
021 *
022 * @Test
023 * public void example() {
024 * collector.addError(new Throwable("first thing went wrong"));
025 * collector.addError(new Throwable("second thing went wrong"));
026 * collector.checkThat(getResult(), not(containsString("ERROR!")));
027 * // all lines will run, and then a combined failure logged at the end.
028 * }
029 * }
030 * </pre>
031 *
032 * @since 4.7
033 */
034 public 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 <T> T checkSucceeds(Callable<T> callable) {
077 try {
078 return callable.call();
079 } catch (Throwable e) {
080 addError(e);
081 return null;
082 }
083 }
084 }