diff options
Diffstat (limited to 'src/main/java/org/junit/runners/BlockJUnit4ClassRunner.java')
-rw-r--r-- | src/main/java/org/junit/runners/BlockJUnit4ClassRunner.java | 172 |
1 files changed, 68 insertions, 104 deletions
diff --git a/src/main/java/org/junit/runners/BlockJUnit4ClassRunner.java b/src/main/java/org/junit/runners/BlockJUnit4ClassRunner.java index 455341a..4d06199 100644 --- a/src/main/java/org/junit/runners/BlockJUnit4ClassRunner.java +++ b/src/main/java/org/junit/runners/BlockJUnit4ClassRunner.java @@ -3,10 +3,8 @@ package org.junit.runners; import static org.junit.internal.runners.rules.RuleMemberValidator.RULE_METHOD_VALIDATOR; import static org.junit.internal.runners.rules.RuleMemberValidator.RULE_VALIDATOR; -import java.util.ArrayList; import java.util.List; import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; import java.util.concurrent.TimeUnit; import org.junit.After; @@ -23,18 +21,14 @@ import org.junit.internal.runners.statements.InvokeMethod; import org.junit.internal.runners.statements.RunAfters; import org.junit.internal.runners.statements.RunBefores; import org.junit.rules.MethodRule; +import org.junit.rules.RunRules; import org.junit.rules.TestRule; import org.junit.runner.Description; import org.junit.runner.notification.RunNotifier; -import org.junit.runners.model.FrameworkMember; import org.junit.runners.model.FrameworkMethod; import org.junit.runners.model.InitializationError; -import org.junit.runners.model.MemberValueConsumer; import org.junit.runners.model.MultipleFailureException; import org.junit.runners.model.Statement; -import org.junit.runners.model.TestClass; -import org.junit.validator.PublicClassValidator; -import org.junit.validator.TestClassValidator; /** * Implements the JUnit 4 standard test case class model, as defined by the @@ -61,27 +55,14 @@ import org.junit.validator.TestClassValidator; * @since 4.5 */ public class BlockJUnit4ClassRunner extends ParentRunner<FrameworkMethod> { - private static TestClassValidator PUBLIC_CLASS_VALIDATOR = new PublicClassValidator(); - - private final ConcurrentMap<FrameworkMethod, Description> methodDescriptions = new ConcurrentHashMap<FrameworkMethod, Description>(); - - /** - * Creates a BlockJUnit4ClassRunner to run {@code testClass} - * - * @throws InitializationError if the test class is malformed. - */ - public BlockJUnit4ClassRunner(Class<?> testClass) throws InitializationError { - super(testClass); - } - + private final ConcurrentHashMap<FrameworkMethod, Description> methodDescriptions = new ConcurrentHashMap<FrameworkMethod, Description>(); /** - * Creates a BlockJUnit4ClassRunner to run {@code testClass}. + * Creates a BlockJUnit4ClassRunner to run {@code klass} * * @throws InitializationError if the test class is malformed. - * @since 4.13 */ - protected BlockJUnit4ClassRunner(TestClass testClass) throws InitializationError { - super(testClass); + public BlockJUnit4ClassRunner(Class<?> klass) throws InitializationError { + super(klass); } // @@ -94,16 +75,10 @@ public class BlockJUnit4ClassRunner extends ParentRunner<FrameworkMethod> { if (isIgnored(method)) { notifier.fireTestIgnored(description); } else { - Statement statement = new Statement() { - @Override - public void evaluate() throws Throwable { - methodBlock(method).evaluate(); - } - }; - runLeaf(statement, description, notifier); + runLeaf(methodBlock(method), description, notifier); } } - + /** * Evaluates whether {@link FrameworkMethod}s are ignored based on the * {@link Ignore} annotation. @@ -148,7 +123,6 @@ public class BlockJUnit4ClassRunner extends ParentRunner<FrameworkMethod> { protected void collectInitializationErrors(List<Throwable> errors) { super.collectInitializationErrors(errors); - validatePublicConstructor(errors); validateNoNonStaticInnerClass(errors); validateConstructor(errors); validateInstanceMethods(errors); @@ -156,12 +130,6 @@ public class BlockJUnit4ClassRunner extends ParentRunner<FrameworkMethod> { validateMethods(errors); } - private void validatePublicConstructor(List<Throwable> errors) { - if (getTestClass().getJavaClass() != null) { - errors.addAll(PUBLIC_CLASS_VALIDATOR.validateTestClass(getTestClass())); - } - } - protected void validateNoNonStaticInnerClass(List<Throwable> errors) { if (getTestClass().isANonStaticInnerClass()) { String gripe = "The inner class " + getTestClass().getName() @@ -212,7 +180,6 @@ public class BlockJUnit4ClassRunner extends ParentRunner<FrameworkMethod> { * Adds to {@code errors} for each method annotated with {@code @Test}, * {@code @Before}, or {@code @After} that is not a public, void instance * method with no arguments. - * @deprecated */ @Deprecated protected void validateInstanceMethods(List<Throwable> errors) { @@ -220,7 +187,7 @@ public class BlockJUnit4ClassRunner extends ParentRunner<FrameworkMethod> { validatePublicVoidNoArgMethods(Before.class, false, errors); validateTestMethods(errors); - if (computeTestMethods().isEmpty()) { + if (computeTestMethods().size() == 0) { errors.add(new Exception("No runnable methods")); } } @@ -251,16 +218,6 @@ public class BlockJUnit4ClassRunner extends ParentRunner<FrameworkMethod> { } /** - * Returns a new fixture to run a particular test {@code method} against. - * Default implementation executes the no-argument {@link #createTest()} method. - * - * @since 4.13 - */ - protected Object createTest(FrameworkMethod method) throws Exception { - return createTest(); - } - - /** * Returns the name that describes {@code method} for {@link Description}s. * Default implementation is the method's name */ @@ -275,10 +232,10 @@ public class BlockJUnit4ClassRunner extends ParentRunner<FrameworkMethod> { * Here is an outline of the default implementation: * * <ul> - * <li>Invoke {@code method} on the result of {@link #createTest(org.junit.runners.model.FrameworkMethod)}, and + * <li>Invoke {@code method} on the result of {@code createTest()}, and * throw any exceptions thrown by either operation. - * <li>HOWEVER, if {@code method}'s {@code @Test} annotation has the {@link Test#expected()} - * attribute, return normally only if the previous step threw an + * <li>HOWEVER, if {@code method}'s {@code @Test} annotation has the {@code + * expecting} attribute, return normally only if the previous step threw an * exception of the correct type, and throw an exception otherwise. * <li>HOWEVER, if {@code method}'s {@code @Test} annotation has the {@code * timeout} attribute, throw an exception if the previous step takes more @@ -300,13 +257,13 @@ public class BlockJUnit4ClassRunner extends ParentRunner<FrameworkMethod> { * This can be overridden in subclasses, either by overriding this method, * or the implementations creating each sub-statement. */ - protected Statement methodBlock(final FrameworkMethod method) { + protected Statement methodBlock(FrameworkMethod method) { Object test; try { test = new ReflectiveCallable() { @Override protected Object runReflectiveCall() throws Throwable { - return createTest(method); + return createTest(); } }.run(); } catch (Throwable e) { @@ -319,7 +276,6 @@ public class BlockJUnit4ClassRunner extends ParentRunner<FrameworkMethod> { statement = withBefores(method, test, statement); statement = withAfters(method, test, statement); statement = withRules(method, test, statement); - statement = withInterruptIsolation(statement); return statement; } @@ -336,22 +292,21 @@ public class BlockJUnit4ClassRunner extends ParentRunner<FrameworkMethod> { /** * Returns a {@link Statement}: if {@code method}'s {@code @Test} annotation - * has the {@link Test#expected()} attribute, return normally only if {@code next} + * has the {@code expecting} attribute, return normally only if {@code next} * throws an exception of the correct type, and throw an exception * otherwise. */ protected Statement possiblyExpectingExceptions(FrameworkMethod method, Object test, Statement next) { Test annotation = method.getAnnotation(Test.class); - Class<? extends Throwable> expectedExceptionClass = getExpectedException(annotation); - return expectedExceptionClass != null ? new ExpectException(next, expectedExceptionClass) : next; + return expectsException(annotation) ? new ExpectException(next, + getExpectedException(annotation)) : next; } /** * Returns a {@link Statement}: if {@code method}'s {@code @Test} annotation * has the {@code timeout} attribute, throw an exception if {@code next} * takes more than the specified number of milliseconds. - * @deprecated */ @Deprecated protected Statement withPotentialTimeout(FrameworkMethod method, @@ -393,23 +348,28 @@ public class BlockJUnit4ClassRunner extends ParentRunner<FrameworkMethod> { target); } - private Statement withRules(FrameworkMethod method, Object target, Statement statement) { - RuleContainer ruleContainer = new RuleContainer(); - CURRENT_RULE_CONTAINER.set(ruleContainer); - try { - List<TestRule> testRules = getTestRules(target); - for (MethodRule each : rules(target)) { - if (!(each instanceof TestRule && testRules.contains(each))) { - ruleContainer.add(each); - } - } - for (TestRule rule : testRules) { - ruleContainer.add(rule); + private Statement withRules(FrameworkMethod method, Object target, + Statement statement) { + List<TestRule> testRules = getTestRules(target); + Statement result = statement; + result = withMethodRules(method, testRules, target, result); + result = withTestRules(method, testRules, result); + + return result; + } + + private Statement withMethodRules(FrameworkMethod method, List<TestRule> testRules, + Object target, Statement result) { + for (org.junit.rules.MethodRule each : getMethodRules(target)) { + if (!testRules.contains(each)) { + result = each.apply(result, method, target); } - } finally { - CURRENT_RULE_CONTAINER.remove(); } - return ruleContainer.apply(method, describeChild(method), target, statement); + return result; + } + + private List<org.junit.rules.MethodRule> getMethodRules(Object target) { + return rules(target); } /** @@ -418,12 +378,27 @@ public class BlockJUnit4ClassRunner extends ParentRunner<FrameworkMethod> { * test */ protected List<MethodRule> rules(Object target) { - RuleCollector<MethodRule> collector = new RuleCollector<MethodRule>(); - getTestClass().collectAnnotatedMethodValues(target, Rule.class, MethodRule.class, - collector); - getTestClass().collectAnnotatedFieldValues(target, Rule.class, MethodRule.class, - collector); - return collector.result; + List<MethodRule> rules = getTestClass().getAnnotatedMethodValues(target, + Rule.class, MethodRule.class); + + rules.addAll(getTestClass().getAnnotatedFieldValues(target, + Rule.class, MethodRule.class)); + + return rules; + } + + /** + * Returns a {@link Statement}: apply all non-static fields + * annotated with {@link Rule}. + * + * @param statement The base statement + * @return a RunRules statement if any class-level {@link Rule}s are + * found, or the base statement + */ + private Statement withTestRules(FrameworkMethod method, List<TestRule> testRules, + Statement statement) { + return testRules.isEmpty() ? statement : + new RunRules(statement, testRules, describeChild(method)); } /** @@ -432,10 +407,13 @@ public class BlockJUnit4ClassRunner extends ParentRunner<FrameworkMethod> { * test */ protected List<TestRule> getTestRules(Object target) { - RuleCollector<TestRule> collector = new RuleCollector<TestRule>(); - getTestClass().collectAnnotatedMethodValues(target, Rule.class, TestRule.class, collector); - getTestClass().collectAnnotatedFieldValues(target, Rule.class, TestRule.class, collector); - return collector.result; + List<TestRule> result = getTestClass().getAnnotatedMethodValues(target, + Rule.class, TestRule.class); + + result.addAll(getTestClass().getAnnotatedFieldValues(target, + Rule.class, TestRule.class)); + + return result; } private Class<? extends Throwable> getExpectedException(Test annotation) { @@ -446,28 +424,14 @@ public class BlockJUnit4ClassRunner extends ParentRunner<FrameworkMethod> { } } + private boolean expectsException(Test annotation) { + return getExpectedException(annotation) != null; + } + private long getTimeout(Test annotation) { if (annotation == null) { return 0; } return annotation.timeout(); } - - private static final ThreadLocal<RuleContainer> CURRENT_RULE_CONTAINER = - new ThreadLocal<RuleContainer>(); - - private static class RuleCollector<T> implements MemberValueConsumer<T> { - final List<T> result = new ArrayList<T>(); - - public void accept(FrameworkMember<?> member, T value) { - Rule rule = member.getAnnotation(Rule.class); - if (rule != null) { - RuleContainer container = CURRENT_RULE_CONTAINER.get(); - if (container != null) { - container.setOrder(value, rule.order()); - } - } - result.add(value); - } - } } |