Home | History | Annotate | Download | only in runner
      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 	 */
     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 	 */
     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 	 */
     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 	 */
     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 	 */
     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
     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 	 */
    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