package org.junit.runner.manipulation; import org.junit.runner.Description; import org.junit.runner.Request; /** * The canonical case of filtering is when you want to run a single test method in a class. Rather * than introduce runner API just for that one case, JUnit provides a general filtering mechanism. * If you want to filter the tests to be run, extend <code>Filter</code> and apply an instance of * your filter to the {@link org.junit.runner.Request} before running it (see * {@link org.junit.runner.JUnitCore#run(Request)}. Alternatively, apply a <code>Filter</code> to * a {@link org.junit.runner.Runner} before running tests (for example, in conjunction with * {@link org.junit.runner.RunWith}. * * @since 4.0 */ public abstract class Filter { /** * A null <code>Filter</code> that passes all tests through. */ public static final Filter ALL = new Filter() { @Override public boolean shouldRun(Description description) { return true; } @Override public String describe() { return "all tests"; } @Override public void apply(Object child) throws NoTestsRemainException { // do nothing } @Override public Filter intersect(Filter second) { return second; } }; /** * Returns a {@code Filter} that only runs the single method described by * {@code desiredDescription} */ public static Filter matchMethodDescription(final Description desiredDescription) { return new Filter() { @Override public boolean shouldRun(Description description) { if (description.isTest()) { return desiredDescription.equals(description); } // explicitly validate if any children want to run for (Description each : description.getChildren()) { if (shouldRun(each)) { return true; } } return false; } @Override public String describe() { return String.format("Method %s", desiredDescription.getDisplayName()); } }; } /** * @param description the description of the test to be run * @return <code>true</code> if the test should be run */ public abstract boolean shouldRun(Description description); /** * Returns a textual description of this Filter * * @return a textual description of this Filter */ public abstract String describe(); /** * Invoke with a {@link org.junit.runner.Runner} to cause all tests it intends to run * to first be checked with the filter. Only those that pass the filter will be run. * * @param child the runner to be filtered by the receiver * @throws NoTestsRemainException if the receiver removes all tests */ public void apply(Object child) throws NoTestsRemainException { if (!(child instanceof Filterable)) { return; } Filterable filterable = (Filterable) child; filterable.filter(this); } /** * Returns a new Filter that accepts the intersection of the tests accepted * by this Filter and {@code second} */ public Filter intersect(final Filter second) { if (second == this || second == ALL) { return this; } final Filter first = this; return new Filter() { @Override public boolean shouldRun(Description description) { return first.shouldRun(description) && second.shouldRun(description); } @Override public String describe() { return first.describe() + " and " + second.describe(); } }; } }