aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/org/junit/runners/ParentRunner.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/org/junit/runners/ParentRunner.java')
-rwxr-xr-x[-rw-r--r--]src/main/java/org/junit/runners/ParentRunner.java176
1 files changed, 23 insertions, 153 deletions
diff --git a/src/main/java/org/junit/runners/ParentRunner.java b/src/main/java/org/junit/runners/ParentRunner.java
index 0a0e7cb..92641bf 100644..100755
--- a/src/main/java/org/junit/runners/ParentRunner.java
+++ b/src/main/java/org/junit/runners/ParentRunner.java
@@ -1,25 +1,21 @@
package org.junit.runners;
-import static org.junit.internal.Checks.notNull;
import static org.junit.internal.runners.rules.RuleMemberValidator.CLASS_RULE_METHOD_VALIDATOR;
import static org.junit.internal.runners.rules.RuleMemberValidator.CLASS_RULE_VALIDATOR;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
-import java.util.LinkedHashMap;
import java.util.List;
-import java.util.Map;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantLock;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.ClassRule;
-import org.junit.FixMethodOrder;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.internal.AssumptionViolatedException;
@@ -32,22 +28,18 @@ import org.junit.runner.Description;
import org.junit.runner.Runner;
import org.junit.runner.manipulation.Filter;
import org.junit.runner.manipulation.Filterable;
-import org.junit.runner.manipulation.Orderer;
-import org.junit.runner.manipulation.InvalidOrderingException;
import org.junit.runner.manipulation.NoTestsRemainException;
-import org.junit.runner.manipulation.Orderable;
+import org.junit.runner.manipulation.Sortable;
import org.junit.runner.manipulation.Sorter;
import org.junit.runner.notification.RunNotifier;
import org.junit.runner.notification.StoppedByUserException;
-import org.junit.runners.model.FrameworkMember;
import org.junit.runners.model.FrameworkMethod;
import org.junit.runners.model.InitializationError;
-import org.junit.runners.model.InvalidTestClassError;
-import org.junit.runners.model.MemberValueConsumer;
import org.junit.runners.model.RunnerScheduler;
import org.junit.runners.model.Statement;
import org.junit.runners.model.TestClass;
import org.junit.validator.AnnotationsValidator;
+import org.junit.validator.PublicClassValidator;
import org.junit.validator.TestClassValidator;
/**
@@ -64,15 +56,15 @@ import org.junit.validator.TestClassValidator;
* @since 4.5
*/
public abstract class ParentRunner<T> extends Runner implements Filterable,
- Orderable {
- private static final List<TestClassValidator> VALIDATORS = Collections.<TestClassValidator>singletonList(
- new AnnotationsValidator());
+ Sortable {
+ private static final List<TestClassValidator> VALIDATORS = Arrays.asList(
+ new AnnotationsValidator(), new PublicClassValidator());
- private final Lock childrenLock = new ReentrantLock();
+ private final Object childrenLock = new Object();
private final TestClass testClass;
// Guarded by childrenLock
- private volatile List<T> filteredChildren = null;
+ private volatile Collection<T> filteredChildren = null;
private volatile RunnerScheduler scheduler = new RunnerScheduler() {
public void schedule(Runnable childStatement) {
@@ -92,21 +84,6 @@ public abstract class ParentRunner<T> extends Runner implements Filterable,
validate();
}
- /**
- * Constructs a new {@code ParentRunner} that will run the {@code TestClass}.
- *
- * @since 4.13
- */
- protected ParentRunner(TestClass testClass) throws InitializationError {
- this.testClass = notNull(testClass);
- validate();
- }
-
- /**
- * @deprecated Please use {@link #ParentRunner(org.junit.runners.model.TestClass)}.
- * @since 4.12
- */
- @Deprecated
protected TestClass createTestClass(Class<?> testClass) {
return new TestClass(testClass);
}
@@ -215,7 +192,6 @@ public abstract class ParentRunner<T> extends Runner implements Filterable,
statement = withBeforeClasses(statement);
statement = withAfterClasses(statement);
statement = withClassRules(statement);
- statement = withInterruptIsolation(statement);
}
return statement;
}
@@ -243,7 +219,7 @@ public abstract class ParentRunner<T> extends Runner implements Filterable,
/**
* Returns a {@link Statement}: run all non-overridden {@code @AfterClass} methods on this class
- * and superclasses after executing {@code statement}; all AfterClass methods are
+ * and superclasses before executing {@code statement}; all AfterClass methods are
* always executed: exceptions thrown by previous steps are combined, if
* necessary, with exceptions from AfterClass methods into a
* {@link org.junit.runners.model.MultipleFailureException}.
@@ -275,10 +251,9 @@ public abstract class ParentRunner<T> extends Runner implements Filterable,
* each method in the tested class.
*/
protected List<TestRule> classRules() {
- ClassRuleCollector collector = new ClassRuleCollector();
- testClass.collectAnnotatedMethodValues(null, ClassRule.class, TestRule.class, collector);
- testClass.collectAnnotatedFieldValues(null, ClassRule.class, TestRule.class, collector);
- return collector.getOrderedRules();
+ List<TestRule> result = testClass.getAnnotatedMethodValues(null, ClassRule.class, TestRule.class);
+ result.addAll(testClass.getAnnotatedFieldValues(null, ClassRule.class, TestRule.class));
+ return result;
}
/**
@@ -296,22 +271,6 @@ public abstract class ParentRunner<T> extends Runner implements Filterable,
}
/**
- * @return a {@link Statement}: clears interrupt status of current thread after execution of statement
- */
- protected final Statement withInterruptIsolation(final Statement statement) {
- return new Statement() {
- @Override
- public void evaluate() throws Throwable {
- try {
- statement.evaluate();
- } finally {
- Thread.interrupted(); // clearing thread interrupted status for isolation
- }
- }
- };
- }
-
- /**
* Evaluates whether a child is ignored. The default implementation always
* returns <code>false</code>.
*
@@ -387,16 +346,8 @@ public abstract class ParentRunner<T> extends Runner implements Filterable,
@Override
public Description getDescription() {
- Class<?> clazz = getTestClass().getJavaClass();
- Description description;
- // if subclass overrides `getName()` then we should use it
- // to maintain backwards compatibility with JUnit 4.12
- if (clazz == null || !clazz.getName().equals(getName())) {
- description = Description.createSuiteDescription(getName(), getRunnerAnnotations());
- } else {
- description = Description.createSuiteDescription(clazz, getRunnerAnnotations());
- }
-
+ Description description = Description.createSuiteDescription(getName(),
+ getRunnerAnnotations());
for (T child : getFilteredChildren()) {
description.addChild(describeChild(child));
}
@@ -407,7 +358,6 @@ public abstract class ParentRunner<T> extends Runner implements Filterable,
public void run(final RunNotifier notifier) {
EachTestNotifier testNotifier = new EachTestNotifier(notifier,
getDescription());
- testNotifier.fireTestSuiteStarted();
try {
Statement statement = classBlock(notifier);
statement.evaluate();
@@ -417,8 +367,6 @@ public abstract class ParentRunner<T> extends Runner implements Filterable,
throw e;
} catch (Throwable e) {
testNotifier.addFailure(e);
- } finally {
- testNotifier.fireTestSuiteFinished();
}
}
@@ -427,8 +375,7 @@ public abstract class ParentRunner<T> extends Runner implements Filterable,
//
public void filter(Filter filter) throws NoTestsRemainException {
- childrenLock.lock();
- try {
+ synchronized (childrenLock) {
List<T> children = new ArrayList<T>(getFilteredChildren());
for (Iterator<T> iter = children.iterator(); iter.hasNext(); ) {
T each = iter.next();
@@ -442,70 +389,21 @@ public abstract class ParentRunner<T> extends Runner implements Filterable,
iter.remove();
}
}
- filteredChildren = Collections.unmodifiableList(children);
+ filteredChildren = Collections.unmodifiableCollection(children);
if (filteredChildren.isEmpty()) {
throw new NoTestsRemainException();
}
- } finally {
- childrenLock.unlock();
}
}
public void sort(Sorter sorter) {
- if (shouldNotReorder()) {
- return;
- }
-
- childrenLock.lock();
- try {
+ synchronized (childrenLock) {
for (T each : getFilteredChildren()) {
sorter.apply(each);
}
List<T> sortedChildren = new ArrayList<T>(getFilteredChildren());
Collections.sort(sortedChildren, comparator(sorter));
- filteredChildren = Collections.unmodifiableList(sortedChildren);
- } finally {
- childrenLock.unlock();
- }
- }
-
- /**
- * Implementation of {@link Orderable#order(Orderer)}.
- *
- * @since 4.13
- */
- public void order(Orderer orderer) throws InvalidOrderingException {
- if (shouldNotReorder()) {
- return;
- }
-
- childrenLock.lock();
- try {
- List<T> children = getFilteredChildren();
- // In theory, we could have duplicate Descriptions. De-dup them before ordering,
- // and add them back at the end.
- Map<Description, List<T>> childMap = new LinkedHashMap<Description, List<T>>(
- children.size());
- for (T child : children) {
- Description description = describeChild(child);
- List<T> childrenWithDescription = childMap.get(description);
- if (childrenWithDescription == null) {
- childrenWithDescription = new ArrayList<T>(1);
- childMap.put(description, childrenWithDescription);
- }
- childrenWithDescription.add(child);
- orderer.apply(child);
- }
-
- List<Description> inOrder = orderer.order(childMap.keySet());
-
- children = new ArrayList<T>(children.size());
- for (Description description : inOrder) {
- children.addAll(childMap.get(description));
- }
- filteredChildren = Collections.unmodifiableList(children);
- } finally {
- childrenLock.unlock();
+ filteredChildren = Collections.unmodifiableCollection(sortedChildren);
}
}
@@ -513,29 +411,20 @@ public abstract class ParentRunner<T> extends Runner implements Filterable,
// Private implementation
//
- private boolean shouldNotReorder() {
- // If the test specifies a specific order, do not reorder.
- return getDescription().getAnnotation(FixMethodOrder.class) != null;
- }
-
private void validate() throws InitializationError {
List<Throwable> errors = new ArrayList<Throwable>();
collectInitializationErrors(errors);
if (!errors.isEmpty()) {
- throw new InvalidTestClassError(testClass.getJavaClass(), errors);
+ throw new InitializationError(errors);
}
}
- private List<T> getFilteredChildren() {
+ private Collection<T> getFilteredChildren() {
if (filteredChildren == null) {
- childrenLock.lock();
- try {
+ synchronized (childrenLock) {
if (filteredChildren == null) {
- filteredChildren = Collections.unmodifiableList(
- new ArrayList<T>(getChildren()));
+ filteredChildren = Collections.unmodifiableCollection(getChildren());
}
- } finally {
- childrenLock.unlock();
}
}
return filteredChildren;
@@ -560,23 +449,4 @@ public abstract class ParentRunner<T> extends Runner implements Filterable,
public void setScheduler(RunnerScheduler scheduler) {
this.scheduler = scheduler;
}
-
- private static class ClassRuleCollector implements MemberValueConsumer<TestRule> {
- final List<RuleContainer.RuleEntry> entries = new ArrayList<RuleContainer.RuleEntry>();
-
- public void accept(FrameworkMember<?> member, TestRule value) {
- ClassRule rule = member.getAnnotation(ClassRule.class);
- entries.add(new RuleContainer.RuleEntry(value, RuleContainer.RuleEntry.TYPE_TEST_RULE,
- rule != null ? rule.order() : null));
- }
-
- public List<TestRule> getOrderedRules() {
- Collections.sort(entries, RuleContainer.ENTRY_COMPARATOR);
- List<TestRule> result = new ArrayList<TestRule>(entries.size());
- for (RuleContainer.RuleEntry entry : entries) {
- result.add((TestRule) entry.rule);
- }
- return result;
- }
- }
}