001package junit.framework;
002
003import java.util.List;
004
005import org.junit.Ignore;
006import org.junit.runner.Describable;
007import org.junit.runner.Description;
008import org.junit.runner.Request;
009import org.junit.runner.Runner;
010import org.junit.runner.manipulation.Filter;
011import org.junit.runner.manipulation.Filterable;
012import org.junit.runner.manipulation.Orderer;
013import org.junit.runner.manipulation.InvalidOrderingException;
014import org.junit.runner.manipulation.NoTestsRemainException;
015import org.junit.runner.manipulation.Orderable;
016import org.junit.runner.manipulation.Sorter;
017
018/**
019 * The JUnit4TestAdapter enables running JUnit-4-style tests using a JUnit-3-style test runner.
020 *
021 * <p> To use it, add the following to a test class:
022 * <pre>
023      public static Test suite() {
024        return new JUnit4TestAdapter(<em>YourJUnit4TestClass</em>.class);
025      }
026</pre>
027 */
028public class JUnit4TestAdapter implements Test, Filterable, Orderable, Describable {
029    private final Class<?> fNewTestClass;
030
031    private final Runner fRunner;
032
033    private final JUnit4TestAdapterCache fCache;
034
035    public JUnit4TestAdapter(Class<?> newTestClass) {
036        this(newTestClass, JUnit4TestAdapterCache.getDefault());
037    }
038
039    public JUnit4TestAdapter(final Class<?> newTestClass, JUnit4TestAdapterCache cache) {
040        fCache = cache;
041        fNewTestClass = newTestClass;
042        fRunner = Request.classWithoutSuiteMethod(newTestClass).getRunner();
043    }
044
045    public int countTestCases() {
046        return fRunner.testCount();
047    }
048
049    public void run(TestResult result) {
050        fRunner.run(fCache.getNotifier(result, this));
051    }
052
053    // reflective interface for Eclipse
054    public List<Test> getTests() {
055        return fCache.asTestList(getDescription());
056    }
057
058    // reflective interface for Eclipse
059    public Class<?> getTestClass() {
060        return fNewTestClass;
061    }
062
063    public Description getDescription() {
064        Description description = fRunner.getDescription();
065        return removeIgnored(description);
066    }
067
068    private Description removeIgnored(Description description) {
069        if (isIgnored(description)) {
070            return Description.EMPTY;
071        }
072        Description result = description.childlessCopy();
073        for (Description each : description.getChildren()) {
074            Description child = removeIgnored(each);
075            if (!child.isEmpty()) {
076                result.addChild(child);
077            }
078        }
079        return result;
080    }
081
082    private boolean isIgnored(Description description) {
083        return description.getAnnotation(Ignore.class) != null;
084    }
085
086    @Override
087    public String toString() {
088        return fNewTestClass.getName();
089    }
090
091    public void filter(Filter filter) throws NoTestsRemainException {
092        filter.apply(fRunner);
093    }
094
095    public void sort(Sorter sorter) {
096        sorter.apply(fRunner);
097    }
098
099    /**
100     * {@inheritDoc}
101     *
102     * @since 4.13
103     */
104    public void order(Orderer orderer) throws InvalidOrderingException {
105        orderer.apply(fRunner);
106    }
107}