Home | History | Annotate | Download | only in manipulation
      1 package org.junit.runner.manipulation;
      2 
      3 import org.junit.runner.Description;
      4 import org.junit.runner.Request;
      5 
      6 /**
      7  * The canonical case of filtering is when you want to run a single test method in a class. Rather
      8  * than introduce runner API just for that one case, JUnit provides a general filtering mechanism.
      9  * If you want to filter the tests to be run, extend <code>Filter</code> and apply an instance of
     10  * your filter to the {@link org.junit.runner.Request} before running it (see
     11  * {@link org.junit.runner.JUnitCore#run(Request)}. Alternatively, apply a <code>Filter</code> to
     12  * a {@link org.junit.runner.Runner} before running tests (for example, in conjunction with
     13  * {@link org.junit.runner.RunWith}.
     14  */
     15 public abstract class Filter {
     16 	/**
     17 	 * A null <code>Filter</code> that passes all tests through.
     18 	 */
     19 	public static Filter ALL= new Filter() {
     20 		@Override
     21 		public boolean shouldRun(Description description) {
     22 			return true;
     23 		}
     24 
     25 		@Override
     26 		public String describe() {
     27 			return "all tests";
     28 		}
     29 
     30 		@Override
     31 		public void apply(Object child) throws NoTestsRemainException {
     32 			// do nothing
     33 		}
     34 
     35 		@Override
     36 		public Filter intersect(Filter second) {
     37 			return second;
     38 		}
     39 	};
     40 
     41 	/**
     42 	 * Returns a {@code Filter} that only runs the single method described by
     43 	 * {@code desiredDescription}
     44 	 */
     45 	public static Filter matchMethodDescription(final Description desiredDescription) {
     46 		return new Filter() {
     47 			@Override
     48 			public boolean shouldRun(Description description) {
     49 				if (description.isTest())
     50 					return desiredDescription.equals(description);
     51 
     52 				// explicitly check if any children want to run
     53 				for (Description each : description.getChildren())
     54 					if (shouldRun(each))
     55 						return true;
     56 				return false;
     57 			}
     58 
     59 			@Override
     60 			public String describe() {
     61 				return String.format("Method %s", desiredDescription.getDisplayName());
     62 			}
     63 		};
     64 	}
     65 
     66 
     67 	/**
     68 	 * @param description the description of the test to be run
     69 	 * @return <code>true</code> if the test should be run
     70 	 */
     71 	public abstract boolean shouldRun(Description description);
     72 
     73 	/**
     74 	 * Returns a textual description of this Filter
     75 	 * @return a textual description of this Filter
     76 	 */
     77 	public abstract String describe();
     78 
     79 	/**
     80 	 * Invoke with a {@link org.junit.runner.Runner} to cause all tests it intends to run
     81 	 * to first be checked with the filter. Only those that pass the filter will be run.
     82 	 * @param child the runner to be filtered by the receiver
     83 	 * @throws NoTestsRemainException if the receiver removes all tests
     84 	 */
     85 	public void apply(Object child) throws NoTestsRemainException {
     86 		if (!(child instanceof Filterable))
     87 			return;
     88 		Filterable filterable= (Filterable) child;
     89 		filterable.filter(this);
     90 	}
     91 
     92 	/**
     93 	 * Returns a new Filter that accepts the intersection of the tests accepted
     94 	 * by this Filter and {@code second}
     95 	 */
     96 	public Filter intersect(final Filter second) {
     97 		if (second == this || second == ALL) {
     98 			return this;
     99 		}
    100 		final Filter first= this;
    101 		return new Filter() {
    102 			@Override
    103 			public boolean shouldRun(Description description) {
    104 				return first.shouldRun(description)
    105 						&& second.shouldRun(description);
    106 			}
    107 
    108 			@Override
    109 			public String describe() {
    110 				return first.describe() + " and " + second.describe();
    111 			}
    112 		};
    113 	}
    114 }
    115