001: package org.junit.runner;
002:
003: import java.util.Comparator;
004:
005: import org.junit.internal.requests.ClassRequest;
006: import org.junit.internal.requests.ClassesRequest;
007: import org.junit.internal.requests.ErrorReportingRequest;
008: import org.junit.internal.requests.FilterRequest;
009: import org.junit.internal.requests.SortingRequest;
010: import org.junit.runner.manipulation.Filter;
011:
012: /**
013: * <p>A <code>Request</code> is an abstract description of tests to be run. Older versions of
014: * JUnit did not need such a concept--tests to be run were described either by classes containing
015: * tests or a tree of {@link org.junit.Test}s. However, we want to support filtering and sorting,
016: * so we need a more abstract specification than the tests themselves and a richer
017: * specification than just the classes.</p>
018: *
019: * <p>The flow when JUnit runs tests is that a <code>Request</code> specifies some tests to be run ->
020: * a {@link org.junit.runner.Runner} is created for each class implied by the <code>Request</code> ->
021: * the {@link org.junit.runner.Runner} returns a detailed {@link org.junit.runner.Description}
022: * which is a tree structure of the tests to be run.</p>
023: */
024: public abstract class Request {
025: /**
026: * Create a <code>Request</code> that, when processed, will run a single test.
027: * This is done by filtering out all other tests. This method is used to support rerunning
028: * single tests.
029: * @param clazz the class of the test
030: * @param methodName the name of the test
031: * @return a <code>Request</code> that will cause a single test be run
032: */
033: public static Request method(Class<?> clazz, String methodName) {
034: Description method = Description.createTestDescription(clazz,
035: methodName);
036: return Request.aClass(clazz).filterWith(method);
037: }
038:
039: /**
040: * Create a <code>Request</code> that, when processed, will run all the tests
041: * in a class. The odd name is necessary because <code>class</code> is a reserved word.
042: * @param clazz the class containing the tests
043: * @return a <code>Request</code> that will cause all tests in the class to be run
044: */
045: public static Request aClass(Class<?> clazz) {
046: return new ClassRequest(clazz);
047: }
048:
049: /**
050: * Create a <code>Request</code> that, when processed, will run all the tests
051: * in a set of classes.
052: * @param collectionName a name to identify this suite of tests
053: * @param classes the classes containing the tests
054: * @return a <code>Request</code> that will cause all tests in the classes to be run
055: */
056: public static Request classes(String collectionName,
057: Class<?>... classes) {
058: return new ClassesRequest(collectionName, classes);
059: }
060:
061: public static Request errorReport(Class<?> klass, Throwable cause) {
062: return new ErrorReportingRequest(klass, cause);
063: }
064:
065: /**
066: * Returns a {@link Runner} for this Request
067: * @return corresponding {@link Runner} for this Request
068: */
069: public abstract Runner getRunner();
070:
071: /**
072: * Returns a Request that only contains those tests that should run when
073: * <code>filter</code> is applied
074: * @param filter The {@link Filter} to apply to this Request
075: * @return the filtered Request
076: */
077: public Request filterWith(Filter filter) {
078: return new FilterRequest(this , filter);
079: }
080:
081: /**
082: * Returns a Request that only runs contains tests whose {@link Description}
083: * equals <code>desiredDescription</code>
084: * @param desiredDescription {@link Description} of those tests that should be run
085: * @return the filtered Request
086: */
087: public Request filterWith(final Description desiredDescription) {
088: return filterWith(new Filter() {
089: @Override
090: public boolean shouldRun(Description description) {
091: if (description.isTest())
092: return desiredDescription.equals(description);
093: for (Description each : description.getChildren())
094: if (shouldRun(each))
095: return true;
096: return false;
097: }
098:
099: @Override
100: public String describe() {
101: return String.format("Method %s", desiredDescription
102: .getDisplayName());
103: }
104: });
105: }
106:
107: /**
108: * Returns a Request whose Tests can be run in a certain order, defined by
109: * <code>comparator</code>
110: *
111: * For example, here is code to run a test suite in alphabetical order:
112: *
113: * <pre>
114: private static Comparator<Description> forward() {
115: return new Comparator<Description>() {
116: public int compare(Description o1, Description o2) {
117: return o1.getDisplayName().compareTo(o2.getDisplayName());
118: }
119: };
120: }
121:
122: public static main() {
123: new JUnitCore().run(Request.aClass(AllTests.class).sortWith(forward()));
124: }
125: * </pre>
126: *
127: * @param comparator definition of the order of the tests in this Request
128: * @return a Request with ordered Tests
129: */
130: public Request sortWith(Comparator<Description> comparator) {
131: return new SortingRequest(this , comparator);
132: }
133:
134: public static Request classWithoutSuiteMethod(Class<?> newTestClass) {
135: return new ClassRequest(newTestClass, false);
136: }
137: }
|