001: package org.junit.internal.runners;
002:
003: import java.lang.annotation.Annotation;
004: import java.lang.reflect.InvocationTargetException;
005: import java.lang.reflect.Method;
006: import java.util.Collections;
007: import java.util.Comparator;
008: import java.util.Iterator;
009: import java.util.List;
010:
011: import org.junit.runner.Description;
012: import org.junit.runner.Runner;
013: import org.junit.runner.manipulation.Filter;
014: import org.junit.runner.manipulation.Filterable;
015: import org.junit.runner.manipulation.NoTestsRemainException;
016: import org.junit.runner.manipulation.Sortable;
017: import org.junit.runner.manipulation.Sorter;
018: import org.junit.runner.notification.RunNotifier;
019:
020: public class JUnit4ClassRunner extends Runner implements Filterable,
021: Sortable {
022: private final List<Method> fTestMethods;
023: private TestClass fTestClass;
024:
025: public JUnit4ClassRunner(Class<?> klass) throws InitializationError {
026: fTestClass = new TestClass(klass);
027: fTestMethods = getTestMethods();
028: validate();
029: }
030:
031: protected List<Method> getTestMethods() {
032: return fTestClass.getTestMethods();
033: }
034:
035: protected void validate() throws InitializationError {
036: MethodValidator methodValidator = new MethodValidator(
037: fTestClass);
038: methodValidator.validateMethodsForDefaultRunner();
039: methodValidator.assertValid();
040: }
041:
042: @Override
043: public void run(final RunNotifier notifier) {
044: new ClassRoadie(notifier, fTestClass, getDescription(),
045: new Runnable() {
046: public void run() {
047: runMethods(notifier);
048: }
049: }).runProtected();
050: }
051:
052: protected void runMethods(final RunNotifier notifier) {
053: for (Method method : fTestMethods)
054: invokeTestMethod(method, notifier);
055: }
056:
057: @Override
058: public Description getDescription() {
059: Description spec = Description.createSuiteDescription(
060: getName(), classAnnotations());
061: List<Method> testMethods = fTestMethods;
062: for (Method method : testMethods)
063: spec.addChild(methodDescription(method));
064: return spec;
065: }
066:
067: protected Annotation[] classAnnotations() {
068: return fTestClass.getJavaClass().getAnnotations();
069: }
070:
071: protected String getName() {
072: return getTestClass().getName();
073: }
074:
075: protected Object createTest() throws Exception {
076: return getTestClass().getConstructor().newInstance();
077: }
078:
079: protected void invokeTestMethod(Method method, RunNotifier notifier) {
080: Description description = methodDescription(method);
081: Object test;
082: try {
083: test = createTest();
084: } catch (InvocationTargetException e) {
085: notifier.testAborted(description, e.getCause());
086: return;
087: } catch (Exception e) {
088: notifier.testAborted(description, e);
089: return;
090: }
091: TestMethod testMethod = wrapMethod(method);
092: new MethodRoadie(test, testMethod, notifier, description).run();
093: }
094:
095: protected TestMethod wrapMethod(Method method) {
096: return new TestMethod(method, fTestClass);
097: }
098:
099: protected String testName(Method method) {
100: return method.getName();
101: }
102:
103: protected Description methodDescription(Method method) {
104: return Description.createTestDescription(getTestClass()
105: .getJavaClass(), testName(method),
106: testAnnotations(method));
107: }
108:
109: protected Annotation[] testAnnotations(Method method) {
110: return method.getAnnotations();
111: }
112:
113: public void filter(Filter filter) throws NoTestsRemainException {
114: for (Iterator<Method> iter = fTestMethods.iterator(); iter
115: .hasNext();) {
116: Method method = iter.next();
117: if (!filter.shouldRun(methodDescription(method)))
118: iter.remove();
119: }
120: if (fTestMethods.isEmpty())
121: throw new NoTestsRemainException();
122: }
123:
124: public void sort(final Sorter sorter) {
125: Collections.sort(fTestMethods, new Comparator<Method>() {
126: public int compare(Method o1, Method o2) {
127: return sorter.compare(methodDescription(o1),
128: methodDescription(o2));
129: }
130: });
131: }
132:
133: protected TestClass getTestClass() {
134: return fTestClass;
135: }
136: }
|