1b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabotpackage org.junit.runners; 2b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot 3b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabotimport static org.junit.internal.runners.rules.RuleFieldValidator.CLASS_RULE_VALIDATOR; 4b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot 5b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabotimport java.lang.annotation.Annotation; 6b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabotimport java.lang.reflect.Method; 7b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabotimport java.util.ArrayList; 8b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabotimport java.util.Collections; 9b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabotimport java.util.Comparator; 10b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabotimport java.util.Iterator; 11b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabotimport java.util.List; 12b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot 13b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabotimport org.junit.AfterClass; 14b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabotimport org.junit.BeforeClass; 15b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabotimport org.junit.ClassRule; 16b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabotimport org.junit.Rule; 17b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabotimport org.junit.internal.AssumptionViolatedException; 18b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabotimport org.junit.internal.runners.model.EachTestNotifier; 19b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabotimport org.junit.internal.runners.statements.RunAfters; 20b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabotimport org.junit.internal.runners.statements.RunBefores; 21b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabotimport org.junit.rules.RunRules; 22b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabotimport org.junit.rules.TestRule; 23b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabotimport org.junit.runner.Description; 24b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabotimport org.junit.runner.Runner; 25b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabotimport org.junit.runner.manipulation.Filter; 26b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabotimport org.junit.runner.manipulation.Filterable; 27b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabotimport org.junit.runner.manipulation.NoTestsRemainException; 28b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabotimport org.junit.runner.manipulation.Sortable; 29b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabotimport org.junit.runner.manipulation.Sorter; 30b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabotimport org.junit.runner.notification.RunNotifier; 31b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabotimport org.junit.runner.notification.StoppedByUserException; 32b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabotimport org.junit.runners.model.FrameworkMethod; 33b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabotimport org.junit.runners.model.InitializationError; 34b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabotimport org.junit.runners.model.MultipleFailureException; 35b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabotimport org.junit.runners.model.RunnerScheduler; 36b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabotimport org.junit.runners.model.Statement; 37b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabotimport org.junit.runners.model.TestClass; 38b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot 39b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot/** 40b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * Provides most of the functionality specific to a Runner that implements a 41b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * "parent node" in the test tree, with children defined by objects of some data 42b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * type {@code T}. (For {@link BlockJUnit4ClassRunner}, {@code T} is 43b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * {@link Method} . For {@link Suite}, {@code T} is {@link Class}.) Subclasses 44b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * must implement finding the children of the node, describing each child, and 45b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * running each child. ParentRunner will filter and sort children, handle 46b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * {@code @BeforeClass} and {@code @AfterClass} methods, 47b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * handle annotated {@link ClassRule}s, create a composite 48b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * {@link Description}, and run children sequentially. 49b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot */ 50b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabotpublic abstract class ParentRunner<T> extends Runner implements Filterable, 51b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot Sortable { 52b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot private final TestClass fTestClass; 53b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot 54b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot private Sorter fSorter= Sorter.NULL; 55b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot 56b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot private List<T> fFilteredChildren= null; 57b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot 58b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot private RunnerScheduler fScheduler= new RunnerScheduler() { 59b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot public void schedule(Runnable childStatement) { 60b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot childStatement.run(); 61b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot } 62b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot 63b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot public void finished() { 64b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot // do nothing 65b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot } 66b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot }; 67b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot 68b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot /** 69b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * Constructs a new {@code ParentRunner} that will run {@code @TestClass} 70b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * @throws InitializationError 71b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot */ 72b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot protected ParentRunner(Class<?> testClass) throws InitializationError { 73b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot fTestClass= new TestClass(testClass); 74b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot validate(); 75b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot } 76b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot 77b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot // 78b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot // Must be overridden 79b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot // 80b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot 81b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot /** 82b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * Returns a list of objects that define the children of this Runner. 83b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot */ 84b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot protected abstract List<T> getChildren(); 85b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot 86b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot /** 87b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * Returns a {@link Description} for {@code child}, which can be assumed to 88b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * be an element of the list returned by {@link ParentRunner#getChildren()} 89b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot */ 90b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot protected abstract Description describeChild(T child); 91b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot 92b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot /** 93b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * Runs the test corresponding to {@code child}, which can be assumed to be 94b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * an element of the list returned by {@link ParentRunner#getChildren()}. 95b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * Subclasses are responsible for making sure that relevant test events are 96b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * reported through {@code notifier} 97b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot */ 98b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot protected abstract void runChild(T child, RunNotifier notifier); 99b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot 100b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot // 101b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot // May be overridden 102b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot // 103b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot 104b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot /** 105b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * Adds to {@code errors} a throwable for each problem noted with the test class (available from {@link #getTestClass()}). 106b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * Default implementation adds an error for each method annotated with 107b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * {@code @BeforeClass} or {@code @AfterClass} that is not 108b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * {@code public static void} with no arguments. 109b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot */ 110b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot protected void collectInitializationErrors(List<Throwable> errors) { 111b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot validatePublicVoidNoArgMethods(BeforeClass.class, true, errors); 112b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot validatePublicVoidNoArgMethods(AfterClass.class, true, errors); 113b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot validateClassRules(errors); 114b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot } 115b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot 116b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot /** 117b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * Adds to {@code errors} if any method in this class is annotated with 118b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * {@code annotation}, but: 119b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * <ul> 120b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * <li>is not public, or 121b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * <li>takes parameters, or 122b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * <li>returns something other than void, or 123b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * <li>is static (given {@code isStatic is false}), or 124b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * <li>is not static (given {@code isStatic is true}). 125b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot */ 126b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot protected void validatePublicVoidNoArgMethods(Class<? extends Annotation> annotation, 127b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot boolean isStatic, List<Throwable> errors) { 128b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot List<FrameworkMethod> methods= getTestClass().getAnnotatedMethods(annotation); 129b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot 130b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot for (FrameworkMethod eachTestMethod : methods) 131b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot eachTestMethod.validatePublicVoidNoArg(isStatic, errors); 132b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot } 133b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot 134b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot private void validateClassRules(List<Throwable> errors) { 135b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot CLASS_RULE_VALIDATOR.validate(getTestClass(), errors); 136b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot } 137b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot 138b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot /** 139b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * Constructs a {@code Statement} to run all of the tests in the test class. Override to add pre-/post-processing. 140b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * Here is an outline of the implementation: 141b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * <ul> 142b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * <li>Call {@link #runChild(Object, RunNotifier)} on each object returned by {@link #getChildren()} (subject to any imposed filter and sort).</li> 143b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * <li>ALWAYS run all non-overridden {@code @BeforeClass} methods on this class 144b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * and superclasses before the previous step; if any throws an 145b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * Exception, stop execution and pass the exception on. 146b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * <li>ALWAYS run all non-overridden {@code @AfterClass} methods on this class 147b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * and superclasses before any of the previous steps; all AfterClass methods are 148b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * always executed: exceptions thrown by previous steps are combined, if 149b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * necessary, with exceptions from AfterClass methods into a 150b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * {@link MultipleFailureException}. 151b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * </ul> 152b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * @param notifier 153b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * @return {@code Statement} 154b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot */ 155b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot protected Statement classBlock(final RunNotifier notifier) { 156b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot Statement statement= childrenInvoker(notifier); 157b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot statement= withBeforeClasses(statement); 158b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot statement= withAfterClasses(statement); 159b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot statement= withClassRules(statement); 160b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot return statement; 161b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot } 162b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot 163b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot /** 164b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * Returns a {@link Statement}: run all non-overridden {@code @BeforeClass} methods on this class 165b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * and superclasses before executing {@code statement}; if any throws an 166b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * Exception, stop execution and pass the exception on. 167b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot */ 168b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot protected Statement withBeforeClasses(Statement statement) { 169b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot List<FrameworkMethod> befores= fTestClass 170b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot .getAnnotatedMethods(BeforeClass.class); 171b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot return befores.isEmpty() ? statement : 172b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot new RunBefores(statement, befores, null); 173b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot } 174b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot 175b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot /** 176b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * Returns a {@link Statement}: run all non-overridden {@code @AfterClass} methods on this class 177b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * and superclasses before executing {@code statement}; all AfterClass methods are 178b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * always executed: exceptions thrown by previous steps are combined, if 179b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * necessary, with exceptions from AfterClass methods into a 180b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * {@link MultipleFailureException}. 181b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot */ 182b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot protected Statement withAfterClasses(Statement statement) { 183b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot List<FrameworkMethod> afters= fTestClass 184b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot .getAnnotatedMethods(AfterClass.class); 185b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot return afters.isEmpty() ? statement : 186b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot new RunAfters(statement, afters, null); 187b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot } 188b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot 189b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot /** 190b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * Returns a {@link Statement}: apply all 191b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * static fields assignable to {@link TestRule} 192b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * annotated with {@link ClassRule}. 193b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * 194b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * @param statement 195b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * the base statement 196b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * @return a RunRules statement if any class-level {@link Rule}s are 197b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * found, or the base statement 198b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot */ 199b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot private Statement withClassRules(Statement statement) { 200b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot List<TestRule> classRules= classRules(); 201b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot return classRules.isEmpty() ? statement : 202b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot new RunRules(statement, classRules, getDescription()); 203b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot } 204b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot 205b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot /** 206b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * @return the {@code ClassRule}s that can transform the block that runs 207b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * each method in the tested class. 208b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot */ 209b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot protected List<TestRule> classRules() { 210b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot return fTestClass.getAnnotatedFieldValues(null, ClassRule.class, TestRule.class); 211b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot } 212b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot 213b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot /** 214b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * Returns a {@link Statement}: Call {@link #runChild(Object, RunNotifier)} 215b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * on each object returned by {@link #getChildren()} (subject to any imposed 216b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * filter and sort) 217b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot */ 218b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot protected Statement childrenInvoker(final RunNotifier notifier) { 219b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot return new Statement() { 220b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot @Override 221b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot public void evaluate() { 222b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot runChildren(notifier); 223b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot } 224b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot }; 225b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot } 226b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot 227b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot private void runChildren(final RunNotifier notifier) { 228b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot for (final T each : getFilteredChildren()) 229b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot fScheduler.schedule(new Runnable() { 230b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot public void run() { 231b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot ParentRunner.this.runChild(each, notifier); 232b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot } 233b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot }); 234b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot fScheduler.finished(); 235b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot } 236b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot 237b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot /** 238b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * Returns a name used to describe this Runner 239b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot */ 240b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot protected String getName() { 241b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot return fTestClass.getName(); 242b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot } 243b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot 244b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot // 245b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot // Available for subclasses 246b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot // 247b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot 248b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot /** 249b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * Returns a {@link TestClass} object wrapping the class to be executed. 250b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot */ 251b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot public final TestClass getTestClass() { 252b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot return fTestClass; 253b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot } 254b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot 255b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot /** 256b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * Runs a {@link Statement} that represents a leaf (aka atomic) test. 257b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot */ 258b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot protected final void runLeaf(Statement statement, Description description, 259b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot RunNotifier notifier) { 260b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot EachTestNotifier eachNotifier= new EachTestNotifier(notifier, description); 261b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot eachNotifier.fireTestStarted(); 262b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot try { 263b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot statement.evaluate(); 264b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot } catch (AssumptionViolatedException e) { 265b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot eachNotifier.addFailedAssumption(e); 266b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot } catch (Throwable e) { 267b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot eachNotifier.addFailure(e); 268b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot } finally { 269b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot eachNotifier.fireTestFinished(); 270b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot } 271b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot } 272b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot 273b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot /** 274b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * @return the annotations that should be attached to this runner's 275b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * description. 276b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot */ 277b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot protected Annotation[] getRunnerAnnotations() { 278b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot return fTestClass.getAnnotations(); 279b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot } 280b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot 281b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot // 282b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot // Implementation of Runner 283b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot // 284b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot 285b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot @Override 286b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot public Description getDescription() { 287b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot Description description= Description.createSuiteDescription(getName(), 288b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot getRunnerAnnotations()); 289b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot for (T child : getFilteredChildren()) 290b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot description.addChild(describeChild(child)); 291b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot return description; 292b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot } 293b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot 294b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot @Override 295b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot public void run(final RunNotifier notifier) { 296b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot EachTestNotifier testNotifier= new EachTestNotifier(notifier, 297b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot getDescription()); 298b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot try { 299b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot Statement statement= classBlock(notifier); 300b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot statement.evaluate(); 301b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot } catch (AssumptionViolatedException e) { 302b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot testNotifier.fireTestIgnored(); 303b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot } catch (StoppedByUserException e) { 304b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot throw e; 305b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot } catch (Throwable e) { 306b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot testNotifier.addFailure(e); 307b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot } 308b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot } 309b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot 310b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot // 311b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot // Implementation of Filterable and Sortable 312b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot // 313b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot 314b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot public void filter(Filter filter) throws NoTestsRemainException { 315b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot for (Iterator<T> iter = getFilteredChildren().iterator(); iter.hasNext(); ) { 316b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot T each = iter.next(); 317b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot if (shouldRun(filter, each)) 318b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot try { 319b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot filter.apply(each); 320b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot } catch (NoTestsRemainException e) { 321b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot iter.remove(); 322b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot } 323b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot else 324b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot iter.remove(); 325b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot } 326b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot if (getFilteredChildren().isEmpty()) { 327b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot throw new NoTestsRemainException(); 328b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot } 329b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot } 330b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot 331b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot public void sort(Sorter sorter) { 332b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot fSorter= sorter; 333b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot for (T each : getFilteredChildren()) 334b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot sortChild(each); 335b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot Collections.sort(getFilteredChildren(), comparator()); 336b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot } 337b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot 338b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot // 339b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot // Private implementation 340b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot // 341b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot 342b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot private void validate() throws InitializationError { 343b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot List<Throwable> errors= new ArrayList<Throwable>(); 344b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot collectInitializationErrors(errors); 345b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot if (!errors.isEmpty()) 346b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot throw new InitializationError(errors); 347b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot } 348b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot 349b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot private List<T> getFilteredChildren() { 350b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot if (fFilteredChildren == null) 351b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot fFilteredChildren = new ArrayList<T>(getChildren()); 352b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot return fFilteredChildren; 353b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot } 354b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot 355b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot private void sortChild(T child) { 356b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot fSorter.apply(child); 357b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot } 358b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot 359b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot private boolean shouldRun(Filter filter, T each) { 360b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot return filter.shouldRun(describeChild(each)); 361b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot } 362b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot 363b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot private Comparator<? super T> comparator() { 364b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot return new Comparator<T>() { 365b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot public int compare(T o1, T o2) { 366b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot return fSorter.compare(describeChild(o1), describeChild(o2)); 367b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot } 368b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot }; 369b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot } 370b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot 371b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot /** 372b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * Sets a scheduler that determines the order and parallelization 373b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * of children. Highly experimental feature that may change. 374b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot */ 375b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot public void setScheduler(RunnerScheduler scheduler) { 376b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot this.fScheduler = scheduler; 377b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot } 378b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot} 379