001 package org.junit.runner.manipulation; 002 003 import org.junit.runner.Description; 004 import org.junit.runner.Request; 005 006 /** 007 * The canonical case of filtering is when you want to run a single test method in a class. Rather 008 * than introduce runner API just for that one case, JUnit provides a general filtering mechanism. 009 * If you want to filter the tests to be run, extend <code>Filter</code> and apply an instance of 010 * your filter to the {@link org.junit.runner.Request} before running it (see 011 * {@link org.junit.runner.JUnitCore#run(Request)}. Alternatively, apply a <code>Filter</code> to 012 * a {@link org.junit.runner.Runner} before running tests (for example, in conjunction with 013 * {@link org.junit.runner.RunWith}. 014 * 015 * @since 4.0 016 */ 017 public abstract class Filter { 018 /** 019 * A null <code>Filter</code> that passes all tests through. 020 */ 021 public static final Filter ALL = new Filter() { 022 @Override 023 public boolean shouldRun(Description description) { 024 return true; 025 } 026 027 @Override 028 public String describe() { 029 return "all tests"; 030 } 031 032 @Override 033 public void apply(Object child) throws NoTestsRemainException { 034 // do nothing 035 } 036 037 @Override 038 public Filter intersect(Filter second) { 039 return second; 040 } 041 }; 042 043 /** 044 * Returns a {@code Filter} that only runs the single method described by 045 * {@code desiredDescription} 046 */ 047 public static Filter matchMethodDescription(final Description desiredDescription) { 048 return new Filter() { 049 @Override 050 public boolean shouldRun(Description description) { 051 if (description.isTest()) { 052 return desiredDescription.equals(description); 053 } 054 055 // explicitly check if any children want to run 056 for (Description each : description.getChildren()) { 057 if (shouldRun(each)) { 058 return true; 059 } 060 } 061 return false; 062 } 063 064 @Override 065 public String describe() { 066 return String.format("Method %s", desiredDescription.getDisplayName()); 067 } 068 }; 069 } 070 071 072 /** 073 * @param description the description of the test to be run 074 * @return <code>true</code> if the test should be run 075 */ 076 public abstract boolean shouldRun(Description description); 077 078 /** 079 * Returns a textual description of this Filter 080 * 081 * @return a textual description of this Filter 082 */ 083 public abstract String describe(); 084 085 /** 086 * Invoke with a {@link org.junit.runner.Runner} to cause all tests it intends to run 087 * to first be checked with the filter. Only those that pass the filter will be run. 088 * 089 * @param child the runner to be filtered by the receiver 090 * @throws NoTestsRemainException if the receiver removes all tests 091 */ 092 public void apply(Object child) throws NoTestsRemainException { 093 if (!(child instanceof Filterable)) { 094 return; 095 } 096 Filterable filterable = (Filterable) child; 097 filterable.filter(this); 098 } 099 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 }