forked from junit-team/junit4
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fixes junit-teamgh-193 (allow explicit ordering of Rules).
Add a class RuleChain, which allows ordering of TestRules. Usage: @rule public TestRule chain= RuleChain .outerRule(new LoggingRule("outer rule") .around(new LoggingRule("middle rule") .around(new LoggingRule("inner rule"); A test with such a rule chain creates the following log: starting outer rule starting middle rule starting inner rule finished inner rule finished middle rule finished outer rule
- Loading branch information
1 parent
96df21c
commit e8349c5
Showing
3 changed files
with
161 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
60 changes: 60 additions & 0 deletions
60
src/test/java/org/junit/tests/experimental/rules/RuleChainTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
package org.junit.tests.experimental.rules; | ||
|
||
import static java.util.Arrays.asList; | ||
import static org.junit.Assert.assertEquals; | ||
import static org.junit.Assert.assertTrue; | ||
import static org.junit.experimental.results.PrintableResult.testResult; | ||
import static org.junit.rules.RuleChain.outerRule; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
import org.junit.Rule; | ||
import org.junit.Test; | ||
import org.junit.rules.RuleChain; | ||
import org.junit.rules.TestWatcher; | ||
import org.junit.runner.Description; | ||
|
||
public class RuleChainTest { | ||
private static final List<String> LOG= new ArrayList<String>(); | ||
|
||
private static class LoggingRule extends TestWatcher { | ||
private final String label; | ||
|
||
public LoggingRule(String label) { | ||
this.label= label; | ||
} | ||
|
||
@Override | ||
protected void starting(Description description) { | ||
LOG.add("starting " + label); | ||
} | ||
|
||
@Override | ||
protected void finished(Description description) { | ||
LOG.add("finished " + label); | ||
} | ||
} | ||
|
||
public static class UseRuleChain { | ||
@Rule | ||
public final RuleChain chain= outerRule(new LoggingRule("outer rule")) | ||
.around(new LoggingRule("middle rule")).around( | ||
new LoggingRule("inner rule")); | ||
|
||
@Test | ||
public void example() { | ||
assertTrue(true); | ||
} | ||
} | ||
|
||
@Test | ||
public void executeRulesInCorrectOrder() throws Exception { | ||
testResult(UseRuleChain.class); | ||
List<String> expectedLog= asList("starting outer rule", | ||
"starting middle rule", "starting inner rule", | ||
"finished inner rule", "finished middle rule", | ||
"finished outer rule"); | ||
assertEquals(expectedLog, LOG); | ||
} | ||
} |