Home | History | Annotate | Download | only in rules
      1 /**
      2  *
      3  */
      4 package org.junit.rules;
      5 
      6 import static org.junit.Assert.assertThat;
      7 
      8 import java.util.ArrayList;
      9 import java.util.List;
     10 import java.util.concurrent.Callable;
     11 
     12 import org.hamcrest.Matcher;
     13 import 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  */
     35 public 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 }