1 package org.junit.runner; 2 3 import java.util.Comparator; 4 5 import org.junit.internal.builders.AllDefaultPossibilitiesBuilder; 6 import org.junit.internal.requests.ClassRequest; 7 import org.junit.internal.requests.FilterRequest; 8 import org.junit.internal.requests.SortingRequest; 9 import org.junit.internal.runners.ErrorReportingRunner; 10 import org.junit.runner.manipulation.Filter; 11 import org.junit.runners.model.InitializationError; 12 13 /** 14 * <p>A <code>Request</code> is an abstract description of tests to be run. Older versions of 15 * JUnit did not need such a concept--tests to be run were described either by classes containing 16 * tests or a tree of {@link org.junit.Test}s. However, we want to support filtering and sorting, 17 * so we need a more abstract specification than the tests themselves and a richer 18 * specification than just the classes.</p> 19 * 20 * <p>The flow when JUnit runs tests is that a <code>Request</code> specifies some tests to be run -> 21 * a {@link org.junit.runner.Runner} is created for each class implied by the <code>Request</code> -> 22 * the {@link org.junit.runner.Runner} returns a detailed {@link org.junit.runner.Description} 23 * which is a tree structure of the tests to be run.</p> 24 */ 25 public abstract class Request { 26 /** 27 * Create a <code>Request</code> that, when processed, will run a single test. 28 * This is done by filtering out all other tests. This method is used to support rerunning 29 * single tests. 30 * @param clazz the class of the test 31 * @param methodName the name of the test 32 * @return a <code>Request</code> that will cause a single test be run 33 */ method(Class<?> clazz, String methodName)34 public static Request method(Class<?> clazz, String methodName) { 35 Description method= Description.createTestDescription(clazz, methodName); 36 return Request.aClass(clazz).filterWith(method); 37 } 38 39 /** 40 * Create a <code>Request</code> that, when processed, will run all the tests 41 * in a class. The odd name is necessary because <code>class</code> is a reserved word. 42 * @param clazz the class containing the tests 43 * @return a <code>Request</code> that will cause all tests in the class to be run 44 */ aClass(Class<?> clazz)45 public static Request aClass(Class<?> clazz) { 46 return new ClassRequest(clazz); 47 } 48 49 /** 50 * Create a <code>Request</code> that, when processed, will run all the tests 51 * in a class. If the class has a suite() method, it will be ignored. 52 * @param clazz the class containing the tests 53 * @return a <code>Request</code> that will cause all tests in the class to be run 54 */ classWithoutSuiteMethod(Class<?> clazz)55 public static Request classWithoutSuiteMethod(Class<?> clazz) { 56 return new ClassRequest(clazz, false); 57 } 58 59 /** 60 * Create a <code>Request</code> that, when processed, will run all the tests 61 * in a set of classes. 62 * @param computer Helps construct Runners from classes 63 * @param classes the classes containing the tests 64 * @return a <code>Request</code> that will cause all tests in the classes to be run 65 */ classes(Computer computer, Class<?>... classes)66 public static Request classes(Computer computer, Class<?>... classes) { 67 try { 68 AllDefaultPossibilitiesBuilder builder= new AllDefaultPossibilitiesBuilder(true); 69 Runner suite= computer.getSuite(builder, classes); 70 return runner(suite); 71 } catch (InitializationError e) { 72 throw new RuntimeException( 73 "Bug in saff's brain: Suite constructor, called as above, should always complete"); 74 } 75 } 76 77 /** 78 * Create a <code>Request</code> that, when processed, will run all the tests 79 * in a set of classes with the default <code>Computer</code>. 80 * @param classes the classes containing the tests 81 * @return a <code>Request</code> that will cause all tests in the classes to be run 82 */ classes(Class<?>.... classes)83 public static Request classes(Class<?>... classes) { 84 return classes(JUnitCore.defaultComputer(), classes); 85 } 86 87 88 /** 89 * Not used within JUnit. Clients should simply instantiate ErrorReportingRunner themselves 90 */ 91 @Deprecated errorReport(Class<?> klass, Throwable cause)92 public static Request errorReport(Class<?> klass, Throwable cause) { 93 return runner(new ErrorReportingRunner(klass, cause)); 94 } 95 96 /** 97 * @param runner the runner to return 98 * @return a <code>Request</code> that will run the given runner when invoked 99 */ runner(final Runner runner)100 public static Request runner(final Runner runner) { 101 return new Request(){ 102 @Override 103 public Runner getRunner() { 104 return runner; 105 } 106 }; 107 } 108 109 /** 110 * Returns a {@link Runner} for this Request 111 * @return corresponding {@link Runner} for this Request 112 */ 113 public abstract Runner getRunner(); 114 115 /** 116 * Returns a Request that only contains those tests that should run when 117 * <code>filter</code> is applied 118 * @param filter The {@link Filter} to apply to this Request 119 * @return the filtered Request 120 */ 121 public Request filterWith(Filter filter) { 122 return new FilterRequest(this, filter); 123 } 124 125 /** 126 * Returns a Request that only runs contains tests whose {@link Description} 127 * equals <code>desiredDescription</code> 128 * @param desiredDescription {@link Description} of those tests that should be run 129 * @return the filtered Request 130 */ 131 public Request filterWith(final Description desiredDescription) { 132 return filterWith(Filter.matchMethodDescription(desiredDescription)); 133 } 134 135 /** 136 * Returns a Request whose Tests can be run in a certain order, defined by 137 * <code>comparator</code> 138 * 139 * For example, here is code to run a test suite in alphabetical order: 140 * 141 * <pre> 142 private static Comparator<Description> forward() { 143 return new Comparator<Description>() { 144 public int compare(Description o1, Description o2) { 145 return o1.getDisplayName().compareTo(o2.getDisplayName()); 146 } 147 }; 148 } 149 150 public static main() { 151 new JUnitCore().run(Request.aClass(AllTests.class).sortWith(forward())); 152 } 153 * </pre> 154 * 155 * @param comparator definition of the order of the tests in this Request 156 * @return a Request with ordered Tests 157 */ 158 public Request sortWith(Comparator<Description> comparator) { 159 return new SortingRequest(this, comparator); 160 } 161 } 162