• 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.OrderingRequest;
9 import org.junit.internal.requests.SortingRequest;
10 import org.junit.internal.runners.ErrorReportingRunner;
11 import org.junit.runner.manipulation.Filter;
12 import org.junit.runner.manipulation.Ordering;
13 import org.junit.runners.model.InitializationError;
14 
15 /**
16  * A <code>Request</code> is an abstract description of tests to be run. Older versions of
17  * JUnit did not need such a concept--tests to be run were described either by classes containing
18  * tests or a tree of {@link  org.junit.Test}s. However, we want to support filtering and sorting,
19  * so we need a more abstract specification than the tests themselves and a richer
20  * specification than just the classes.
21  *
22  * <p>The flow when JUnit runs tests is that a <code>Request</code> specifies some tests to be run -&gt;
23  * a {@link org.junit.runner.Runner} is created for each class implied by the <code>Request</code> -&gt;
24  * the {@link org.junit.runner.Runner} returns a detailed {@link org.junit.runner.Description}
25  * which is a tree structure of the tests to be run.
26  *
27  * @since 4.0
28  */
29 public abstract class Request {
30     /**
31      * Create a <code>Request</code> that, when processed, will run a single test.
32      * This is done by filtering out all other tests. This method is used to support rerunning
33      * single tests.
34      *
35      * @param clazz the class of the test
36      * @param methodName the name of the test
37      * @return a <code>Request</code> that will cause a single test be run
38      */
method(Class<?> clazz, String methodName)39     public static Request method(Class<?> clazz, String methodName) {
40         Description method = Description.createTestDescription(clazz, methodName);
41         return Request.aClass(clazz).filterWith(method);
42     }
43 
44     /**
45      * Create a <code>Request</code> that, when processed, will run all the tests
46      * in a class. The odd name is necessary because <code>class</code> is a reserved word.
47      *
48      * @param clazz the class containing the tests
49      * @return a <code>Request</code> that will cause all tests in the class to be run
50      */
aClass(Class<?> clazz)51     public static Request aClass(Class<?> clazz) {
52         return new ClassRequest(clazz);
53     }
54 
55     /**
56      * Create a <code>Request</code> that, when processed, will run all the tests
57      * in a class. If the class has a suite() method, it will be ignored.
58      *
59      * @param clazz the class containing the tests
60      * @return a <code>Request</code> that will cause all tests in the class to be run
61      */
classWithoutSuiteMethod(Class<?> clazz)62     public static Request classWithoutSuiteMethod(Class<?> clazz) {
63         return new ClassRequest(clazz, false);
64     }
65 
66     /**
67      * Create a <code>Request</code> that, when processed, will run all the tests
68      * in a set of classes.
69      *
70      * @param computer Helps construct Runners from classes
71      * @param classes the classes containing the tests
72      * @return a <code>Request</code> that will cause all tests in the classes to be run
73      */
classes(Computer computer, Class<?>... classes)74     public static Request classes(Computer computer, Class<?>... classes) {
75         try {
76             AllDefaultPossibilitiesBuilder builder = new AllDefaultPossibilitiesBuilder();
77             Runner suite = computer.getSuite(builder, classes);
78             return runner(suite);
79         } catch (InitializationError e) {
80             return runner(new ErrorReportingRunner(e, classes));
81         }
82     }
83 
84     /**
85      * Create a <code>Request</code> that, when processed, will run all the tests
86      * in a set of classes with the default <code>Computer</code>.
87      *
88      * @param classes the classes containing the tests
89      * @return a <code>Request</code> that will cause all tests in the classes to be run
90      */
classes(Class<?>.... classes)91     public static Request classes(Class<?>... classes) {
92         return classes(JUnitCore.defaultComputer(), classes);
93     }
94 
95 
96     /**
97      * Creates a {@link Request} that, when processed, will report an error for the given
98      * test class with the given cause.
99      */
errorReport(Class<?> klass, Throwable cause)100     public static Request errorReport(Class<?> klass, Throwable cause) {
101         return runner(new ErrorReportingRunner(klass, cause));
102     }
103 
104     /**
105      * @param runner the runner to return
106      * @return a <code>Request</code> that will run the given runner when invoked
107      */
runner(final Runner runner)108     public static Request runner(final Runner runner) {
109         return new Request() {
110             @Override
111             public Runner getRunner() {
112                 return runner;
113             }
114         };
115     }
116 
117     /**
118      * Returns a {@link Runner} for this Request
119      *
120      * @return corresponding {@link Runner} for this Request
121      */
122     public abstract Runner getRunner();
123 
124     /**
125      * Returns a Request that only contains those tests that should run when
126      * <code>filter</code> is applied
127      *
128      * @param filter The {@link Filter} to apply to this Request
129      * @return the filtered Request
130      */
131     public Request filterWith(Filter filter) {
132         return new FilterRequest(this, filter);
133     }
134 
135     /**
136      * Returns a Request that only runs tests whose {@link Description}
137      * matches the given description.
138      *
139      * <p>Returns an empty {@code Request} if {@code desiredDescription} is not a single test and filters all but the single
140      * test if {@code desiredDescription} is a single test.</p>
141      *
142      * @param desiredDescription {@code Description} of those tests that should be run
143      * @return the filtered Request
144      */
145     public Request filterWith(Description desiredDescription) {
146         return filterWith(Filter.matchMethodDescription(desiredDescription));
147     }
148 
149     /**
150      * Returns a Request whose Tests can be run in a certain order, defined by
151      * <code>comparator</code>
152      * <p>
153      * For example, here is code to run a test suite in alphabetical order:
154      * <pre>
155      * private static Comparator&lt;Description&gt; forward() {
156      *   return new Comparator&lt;Description&gt;() {
157      *     public int compare(Description o1, Description o2) {
158      *       return o1.getDisplayName().compareTo(o2.getDisplayName());
159      *     }
160      *   };
161      * }
162      *
163      * public static main() {
164      *   new JUnitCore().run(Request.aClass(AllTests.class).sortWith(forward()));
165      * }
166      * </pre>
167      *
168      * @param comparator definition of the order of the tests in this Request
169      * @return a Request with ordered Tests
170      */
171     public Request sortWith(Comparator<Description> comparator) {
172         return new SortingRequest(this, comparator);
173     }
174 
175     /**
176      * Returns a Request whose Tests can be run in a certain order, defined by
177      * <code>ordering</code>
178      * <p>
179      * For example, here is code to run a test suite in reverse order:
180      * <pre>
181      * private static Ordering reverse() {
182      *   return new Ordering() {
183      *     public List&lt;Description&gt; orderItems(Collection&lt;Description&gt; descriptions) {
184      *       List&lt;Description&gt; ordered = new ArrayList&lt;&gt;(descriptions);
185      *       Collections.reverse(ordered);
186      *       return ordered;
187      *     }
188      *   }
189      * }
190      *
191      * public static main() {
192      *   new JUnitCore().run(Request.aClass(AllTests.class).orderWith(reverse()));
193      * }
194      * </pre>
195      *
196      * @return a Request with ordered Tests
197      * @since 4.13
198      */
199     public Request orderWith(Ordering ordering) {
200         return new OrderingRequest(this, ordering);
201     }
202 }
203