org.junit.runners.model.RunnerBuilder Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of virtdata-lib-realer Show documentation
Show all versions of virtdata-lib-realer Show documentation
With inspiration from other libraries
package org.junit.runners.model;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.junit.internal.runners.ErrorReportingRunner;
import org.junit.runner.Runner;
/**
* A RunnerBuilder is a strategy for constructing runners for classes.
*
* Only writers of custom runners should use RunnerBuilder
s. A custom runner class with a constructor taking
* a RunnerBuilder
parameter will be passed the instance of RunnerBuilder
used to build that runner itself.
* For example,
* imagine a custom runner that builds suites based on a list of classes in a text file:
*
*
* \@RunWith(TextFileSuite.class)
* \@SuiteSpecFile("mysuite.txt")
* class MySuite {}
*
*
* The implementation of TextFileSuite might include:
*
*
* public TextFileSuite(Class testClass, RunnerBuilder builder) {
* // ...
* for (String className : readClassNames())
* addRunner(builder.runnerForClass(Class.forName(className)));
* // ...
* }
*
*
* @see org.junit.runners.Suite
* @since 4.5
*/
public abstract class RunnerBuilder {
private final Set> parents = new HashSet>();
/**
* Override to calculate the correct runner for a test class at runtime.
*
* @param testClass class to be run
* @return a Runner
* @throws Throwable if a runner cannot be constructed
*/
public abstract Runner runnerForClass(Class> testClass) throws Throwable;
/**
* Always returns a runner, even if it is just one that prints an error instead of running tests.
*
* @param testClass class to be run
* @return a Runner
*/
public Runner safeRunnerForClass(Class> testClass) {
try {
return runnerForClass(testClass);
} catch (Throwable e) {
return new ErrorReportingRunner(testClass, e);
}
}
Class> addParent(Class> parent) throws InitializationError {
if (!parents.add(parent)) {
throw new InitializationError(String.format("class '%s' (possibly indirectly) contains itself as a SuiteClass", parent.getName()));
}
return parent;
}
void removeParent(Class> klass) {
parents.remove(klass);
}
/**
* Constructs and returns a list of Runners, one for each child class in
* {@code children}. Care is taken to avoid infinite recursion:
* this builder will throw an exception if it is requested for another
* runner for {@code parent} before this call completes.
*/
public List runners(Class> parent, Class>[] children)
throws InitializationError {
addParent(parent);
try {
return runners(children);
} finally {
removeParent(parent);
}
}
public List runners(Class> parent, List> children)
throws InitializationError {
return runners(parent, children.toArray(new Class>[0]));
}
private List runners(Class>[] children) {
ArrayList runners = new ArrayList();
for (Class> each : children) {
Runner childRunner = safeRunnerForClass(each);
if (childRunner != null) {
runners.add(childRunner);
}
}
return runners;
}
}