diff options
Diffstat (limited to 'src/main/java/org/junit/rules/RuleChain.java')
-rw-r--r-- | src/main/java/org/junit/rules/RuleChain.java | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/src/main/java/org/junit/rules/RuleChain.java b/src/main/java/org/junit/rules/RuleChain.java new file mode 100644 index 0000000..8af3c05 --- /dev/null +++ b/src/main/java/org/junit/rules/RuleChain.java @@ -0,0 +1,99 @@ +/** + * + */ +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)}: + * + * <pre> + * 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); + * } + * } + * </pre> + * + * writes the log + * + * <pre> + * starting outer rule + * starting middle rule + * starting inner rule + * finished inner rule + * finished middle rule + * finished outer rule + * </pre> + */ +public class RuleChain implements TestRule { + private static final RuleChain EMPTY_CHAIN= new RuleChain( + Collections.<TestRule> emptyList()); + + private List<TestRule> 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<TestRule> 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<TestRule> rulesOfNewChain= new ArrayList<TestRule>(); + 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; + } +}
\ No newline at end of file |