View Javadoc
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   * @since 4.0
16   */
17  public 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 }