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