1/**
2 *
3 */
4package org.junit.rules;
5
6import static org.junit.Assert.assertThat;
7
8import java.util.ArrayList;
9import java.util.List;
10import java.util.concurrent.Callable;
11
12import org.hamcrest.Matcher;
13import org.junit.runners.model.MultipleFailureException;
14
15/**
16 * The ErrorCollector rule allows execution of a test to continue after the
17 * first problem is found (for example, to collect _all_ the incorrect rows in a
18 * table, and report them all at once):
19 *
20 * <pre>
21 * public static class UsesErrorCollectorTwice {
22 * 	&#064;Rule
23 * 	public ErrorCollector collector= new ErrorCollector();
24 *
25 * 	&#064;Test
26 * 	public void example() {
27 * 		collector.addError(new Throwable(&quot;first thing went wrong&quot;));
28 * 		collector.addError(new Throwable(&quot;second thing went wrong&quot;));
29 * 		collector.checkThat(getResult(), not(containsString(&quot;ERROR!&quot;)));
30 * 		// all lines will run, and then a combined failure logged at the end.
31 * 	}
32 * }
33 * </pre>
34 */
35public class ErrorCollector extends Verifier {
36	private List<Throwable> errors= new ArrayList<Throwable>();
37
38	@Override
39	protected void verify() throws Throwable {
40		MultipleFailureException.assertEmpty(errors);
41	}
42
43	/**
44	 * Adds a Throwable to the table.  Execution continues, but the test will fail at the end.
45	 */
46	public void addError(Throwable error) {
47		errors.add(error);
48	}
49
50	/**
51	 * Adds a failure to the table if {@code matcher} does not match {@code value}.
52	 * Execution continues, but the test will fail at the end if the match fails.
53	 */
54	public <T> void checkThat(final T value, final Matcher<T> matcher) {
55		checkThat("", value, matcher);
56	}
57
58	/**
59	 * Adds a failure with the given {@code reason}
60	 * to the table if {@code matcher} does not match {@code value}.
61	 * Execution continues, but the test will fail at the end if the match fails.
62	 */
63	public <T> void checkThat(final String reason, final T value, final Matcher<T> matcher) {
64		checkSucceeds(new Callable<Object>() {
65			public Object call() throws Exception {
66				assertThat(reason, value, matcher);
67				return value;
68			}
69		});
70	}
71
72	/**
73	 * Adds to the table the exception, if any, thrown from {@code callable}.
74	 * Execution continues, but the test will fail at the end if
75	 * {@code callable} threw an exception.
76	 */
77	public Object checkSucceeds(Callable<Object> callable) {
78		try {
79			return callable.call();
80		} catch (Throwable e) {
81			addError(e);
82			return null;
83		}
84	}
85}