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