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