• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  * 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.
19  *
20  * <p>The flow when JUnit runs tests is that a <code>Request</code> specifies some tests to be run -&gt;
21  * a {@link org.junit.runner.Runner} is created for each class implied by the <code>Request</code> -&gt;
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.
24  *
25  * @since 4.0
26  */
27 public abstract class Request {
28     /**
29      * Create a <code>Request</code> that, when processed, will run a single test.
30      * This is done by filtering out all other tests. This method is used to support rerunning
31      * single tests.
32      *
33      * @param clazz the class of the test
34      * @param methodName the name of the test
35      * @return a <code>Request</code> that will cause a single test be run
36      */
method(Class<?> clazz, String methodName)37     public static Request method(Class<?> clazz, String methodName) {
38         Description method = Description.createTestDescription(clazz, methodName);
39         return Request.aClass(clazz).filterWith(method);
40     }
41 
42     /**
43      * Create a <code>Request</code> that, when processed, will run all the tests
44      * in a class. The odd name is necessary because <code>class</code> is a reserved word.
45      *
46      * @param clazz the class containing the tests
47      * @return a <code>Request</code> that will cause all tests in the class to be run
48      */
aClass(Class<?> clazz)49     public static Request aClass(Class<?> clazz) {
50         return new ClassRequest(clazz);
51     }
52 
53     /**
54      * Create a <code>Request</code> that, when processed, will run all the tests
55      * in a class. If the class has a suite() method, it will be ignored.
56      *
57      * @param clazz the class containing the tests
58      * @return a <code>Request</code> that will cause all tests in the class to be run
59      */
classWithoutSuiteMethod(Class<?> clazz)60     public static Request classWithoutSuiteMethod(Class<?> clazz) {
61         return new ClassRequest(clazz, false);
62     }
63 
64     /**
65      * Create a <code>Request</code> that, when processed, will run all the tests
66      * in a set of classes.
67      *
68      * @param computer Helps construct Runners from classes
69      * @param classes the classes containing the tests
70      * @return a <code>Request</code> that will cause all tests in the classes to be run
71      */
classes(Computer computer, Class<?>... classes)72     public static Request classes(Computer computer, Class<?>... classes) {
73         try {
74             AllDefaultPossibilitiesBuilder builder = new AllDefaultPossibilitiesBuilder(true);
75             Runner suite = computer.getSuite(builder, classes);
76             return runner(suite);
77         } catch (InitializationError e) {
78             throw new RuntimeException(
79                     "Bug in saff's brain: Suite constructor, called as above, should always complete");
80         }
81     }
82 
83     /**
84      * Create a <code>Request</code> that, when processed, will run all the tests
85      * in a set of classes with the default <code>Computer</code>.
86      *
87      * @param classes the classes containing the tests
88      * @return a <code>Request</code> that will cause all tests in the classes to be run
89      */
classes(Class<?>.... classes)90     public static Request classes(Class<?>... classes) {
91         return classes(JUnitCore.defaultComputer(), classes);
92     }
93 
94 
95     /**
96      * Creates a {@link Request} that, when processed, will report an error for the given
97      * test class with the given cause.
98      */
errorReport(Class<?> klass, Throwable cause)99     public static Request errorReport(Class<?> klass, Throwable cause) {
100         return runner(new ErrorReportingRunner(klass, cause));
101     }
102 
103     /**
104      * @param runner the runner to return
105      * @return a <code>Request</code> that will run the given runner when invoked
106      */
runner(final Runner runner)107     public static Request runner(final Runner runner) {
108         return new Request() {
109             @Override
110             public Runner getRunner() {
111                 return runner;
112             }
113         };
114     }
115 
116     /**
117      * Returns a {@link Runner} for this Request
118      *
119      * @return corresponding {@link Runner} for this Request
120      */
121     public abstract Runner getRunner();
122 
123     /**
124      * Returns a Request that only contains those tests that should run when
125      * <code>filter</code> is applied
126      *
127      * @param filter The {@link Filter} to apply to this Request
128      * @return the filtered Request
129      */
130     public Request filterWith(Filter filter) {
131         return new FilterRequest(this, filter);
132     }
133 
134     /**
135      * Returns a Request that only runs contains tests whose {@link Description}
136      * equals <code>desiredDescription</code>
137      *
138      * @param desiredDescription {@link Description} of those tests that should be run
139      * @return the filtered Request
140      */
141     public Request filterWith(final Description desiredDescription) {
142         return filterWith(Filter.matchMethodDescription(desiredDescription));
143     }
144 
145     /**
146      * Returns a Request whose Tests can be run in a certain order, defined by
147      * <code>comparator</code>
148      * <p>
149      * For example, here is code to run a test suite in alphabetical order:
150      * <pre>
151      * private static Comparator&lt;Description&gt; forward() {
152      * return new Comparator&lt;Description&gt;() {
153      * public int compare(Description o1, Description o2) {
154      * return o1.getDisplayName().compareTo(o2.getDisplayName());
155      * }
156      * };
157      * }
158      *
159      * public static main() {
160      * new JUnitCore().run(Request.aClass(AllTests.class).sortWith(forward()));
161      * }
162      * </pre>
163      *
164      * @param comparator definition of the order of the tests in this Request
165      * @return a Request with ordered Tests
166      */
167     public Request sortWith(Comparator<Description> comparator) {
168         return new SortingRequest(this, comparator);
169     }
170 }
171