• 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  * <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