/** * */ package org.junit.rules; import java.util.ArrayList; import java.util.Collections; import java.util.List; import org.junit.runner.Description; import org.junit.runners.model.Statement; /** * The RuleChain rule allows ordering of TestRules. You create a * {@code RuleChain} with {@link #outerRule(TestRule)} and subsequent calls of * {@link #around(TestRule)}: * *
 * public static class UseRuleChain {
 * 	@Rule
 * 	public TestRule chain= RuleChain
 * 	                       .outerRule(new LoggingRule("outer rule")
 * 	                       .around(new LoggingRule("middle rule")
 * 	                       .around(new LoggingRule("inner rule");
 * 
 * 	@Test
 * 	public void example() {
 * 		assertTrue(true);
 * 	}
 * }
 * 
* * writes the log * *
 * starting outer rule
 * starting middle rule
 * starting inner rule
 * finished inner rule
 * finished middle rule
 * finished outer rule
 * 
*/ public class RuleChain implements TestRule { private static final RuleChain EMPTY_CHAIN= new RuleChain( Collections. emptyList()); private List rulesStartingWithInnerMost; /** * Returns a {@code RuleChain} without a {@link TestRule}. This method may * be the starting point of a {@code RuleChain}. * * @return a {@code RuleChain} without a {@link TestRule}. */ public static RuleChain emptyRuleChain() { return EMPTY_CHAIN; } /** * Returns a {@code RuleChain} with a single {@link TestRule}. This method * is the usual starting point of a {@code RuleChain}. * * @param outerRule * the outer rule of the {@code RuleChain}. * @return a {@code RuleChain} with a single {@link TestRule}. */ public static RuleChain outerRule(TestRule outerRule) { return emptyRuleChain().around(outerRule); } private RuleChain(List rules) { this.rulesStartingWithInnerMost= rules; } /** * Create a new {@code RuleChain}, which encloses the {@code nextRule} with * the rules of the current {@code RuleChain}. * * @param enclosedRule * the rule to enclose. * @return a new {@code RuleChain}. */ public RuleChain around(TestRule enclosedRule) { List rulesOfNewChain= new ArrayList(); rulesOfNewChain.add(enclosedRule); rulesOfNewChain.addAll(rulesStartingWithInnerMost); return new RuleChain(rulesOfNewChain); } /** * {@inheritDoc} */ public Statement apply(Statement base, Description description) { for (TestRule each : rulesStartingWithInnerMost) base= each.apply(base, description); return base; } }