    001    package org.junit.runner;
    002
    003    import java.util.Comparator;
    004
    005    import org.junit.internal.builders.AllDefaultPossibilitiesBuilder;
    006    import org.junit.internal.requests.ClassRequest;
    007    import org.junit.internal.requests.FilterRequest;
    008    import org.junit.internal.requests.OrderingRequest;
    009    import org.junit.internal.requests.SortingRequest;
    010    import org.junit.internal.runners.ErrorReportingRunner;
    011    import org.junit.runner.manipulation.Filter;
    012    import org.junit.runner.manipulation.Ordering;
    013    import org.junit.runners.model.InitializationError;
    014
    015    /**
    016     * A <code>Request</code> is an abstract description of tests to be run. Older versions of
    017     * JUnit did not need such a concept--tests to be run were described either by classes containing
    018     * tests or a tree of {@link  org.junit.Test}s. However, we want to support filtering and sorting,
    019     * so we need a more abstract specification than the tests themselves and a richer
    020     * specification than just the classes.
    021     *
    022     * <p>The flow when JUnit runs tests is that a <code>Request</code> specifies some tests to be run -&gt;
    023     * a {@link org.junit.runner.Runner} is created for each class implied by the <code>Request</code> -&gt;
    024     * the {@link org.junit.runner.Runner} returns a detailed {@link org.junit.runner.Description}
    025     * which is a tree structure of the tests to be run.
    026     *
    027     * @since 4.0
    028     */
    029    public abstract class Request {
    030        /**
    031         * Create a <code>Request</code> that, when processed, will run a single test.
    032         * This is done by filtering out all other tests. This method is used to support rerunning
    033         * single tests.
    034         *
    035         * @param clazz the class of the test
    036         * @param methodName the name of the test
    037         * @return a <code>Request</code> that will cause a single test be run
    038         */
    039        public static Request method(Class<?> clazz, String methodName) {
    040            Description method = Description.createTestDescription(clazz, methodName);
    041            return Request.aClass(clazz).filterWith(method);
    042        }
    043
    044        /**
    045         * Create a <code>Request</code> that, when processed, will run all the tests
    046         * in a class. The odd name is necessary because <code>class</code> is a reserved word.
    047         *
    048         * @param clazz the class containing the tests
    049         * @return a <code>Request</code> that will cause all tests in the class to be run
    050         */
    051        public static Request aClass(Class<?> clazz) {
    052            return new ClassRequest(clazz);
    053        }
    054
    055        /**
    056         * Create a <code>Request</code> that, when processed, will run all the tests
    057         * in a class. If the class has a suite() method, it will be ignored.
    058         *
    059         * @param clazz the class containing the tests
    060         * @return a <code>Request</code> that will cause all tests in the class to be run
    061         */
    062        public static Request classWithoutSuiteMethod(Class<?> clazz) {
    063            return new ClassRequest(clazz, false);
    064        }
    065
    066        /**
    067         * Create a <code>Request</code> that, when processed, will run all the tests
    068         * in a set of classes.
    069         *
    070         * @param computer Helps construct Runners from classes
    071         * @param classes the classes containing the tests
    072         * @return a <code>Request</code> that will cause all tests in the classes to be run
    073         */
    074        public static Request classes(Computer computer, Class<?>... classes) {
    075            try {
    076                AllDefaultPossibilitiesBuilder builder = new AllDefaultPossibilitiesBuilder();
    077                Runner suite = computer.getSuite(builder, classes);
    078                return runner(suite);
    079            } catch (InitializationError e) {
    080                return runner(new ErrorReportingRunner(e, classes));
    081            }
    082        }
    083
    084        /**
    085         * Create a <code>Request</code> that, when processed, will run all the tests
    086         * in a set of classes with the default <code>Computer</code>.
    087         *
    088         * @param classes the classes containing the tests
    089         * @return a <code>Request</code> that will cause all tests in the classes to be run
    090         */
    091        public static Request classes(Class<?>... classes) {
    092            return classes(JUnitCore.defaultComputer(), classes);
    093        }
    094
    095
    096        /**
    097         * Creates a {@link Request} that, when processed, will report an error for the given
    098         * test class with the given cause.
    099         */
    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         */
    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    }