1package org.junit.runner.manipulation; 2 3import org.junit.runner.Description; 4import 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 * @since 4.0 16 */ 17public abstract class Filter { 18 /** 19 * A null <code>Filter</code> that passes all tests through. 20 */ 21 public static final Filter ALL = new Filter() { 22 @Override 23 public boolean shouldRun(Description description) { 24 return true; 25 } 26 27 @Override 28 public String describe() { 29 return "all tests"; 30 } 31 32 @Override 33 public void apply(Object child) throws NoTestsRemainException { 34 // do nothing 35 } 36 37 @Override 38 public Filter intersect(Filter second) { 39 return second; 40 } 41 }; 42 43 /** 44 * Returns a {@code Filter} that only runs the single method described by 45 * {@code desiredDescription} 46 */ 47 public static Filter matchMethodDescription(final Description desiredDescription) { 48 return new Filter() { 49 @Override 50 public boolean shouldRun(Description description) { 51 if (description.isTest()) { 52 return desiredDescription.equals(description); 53 } 54 55 // explicitly check if any children want to run 56 for (Description each : description.getChildren()) { 57 if (shouldRun(each)) { 58 return true; 59 } 60 } 61 return false; 62 } 63 64 @Override 65 public String describe() { 66 return String.format("Method %s", desiredDescription.getDisplayName()); 67 } 68 }; 69 } 70 71 72 /** 73 * @param description the description of the test to be run 74 * @return <code>true</code> if the test should be run 75 */ 76 public abstract boolean shouldRun(Description description); 77 78 /** 79 * Returns a textual description of this Filter 80 * 81 * @return a textual description of this Filter 82 */ 83 public abstract String describe(); 84 85 /** 86 * Invoke with a {@link org.junit.runner.Runner} to cause all tests it intends to run 87 * to first be checked with the filter. Only those that pass the filter will be run. 88 * 89 * @param child the runner to be filtered by the receiver 90 * @throws NoTestsRemainException if the receiver removes all tests 91 */ 92 public void apply(Object child) throws NoTestsRemainException { 93 if (!(child instanceof Filterable)) { 94 return; 95 } 96 Filterable filterable = (Filterable) child; 97 filterable.filter(this); 98 } 99 100 /** 101 * Returns a new Filter that accepts the intersection of the tests accepted 102 * by this Filter and {@code second} 103 */ 104 public Filter intersect(final Filter second) { 105 if (second == this || second == ALL) { 106 return this; 107 } 108 final Filter first = this; 109 return new Filter() { 110 @Override 111 public boolean shouldRun(Description description) { 112 return first.shouldRun(description) 113 && second.shouldRun(description); 114 } 115 116 @Override 117 public String describe() { 118 return first.describe() + " and " + second.describe(); 119 } 120 }; 121 } 122} 123