1package junit.runner;
2
3import java.lang.reflect.*;
4import junit.framework.*;
5
6/**
7 * An implementation of a TestCollector that loads
8 * all classes on the class path and tests whether
9 * it is assignable from Test or provides a static suite method.
10 * @see TestCollector
11 * {@hide} - Not needed for 1.0 SDK
12 */
13public class LoadingTestCollector extends ClassPathTestCollector {
14
15    TestCaseClassLoader fLoader;
16
17    public LoadingTestCollector() {
18        fLoader= new TestCaseClassLoader();
19    }
20
21    protected boolean isTestClass(String classFileName) {
22        try {
23            if (classFileName.endsWith(".class")) {
24                Class testClass= classFromFile(classFileName);
25                return (testClass != null) && isTestClass(testClass);
26            }
27        }
28        catch (ClassNotFoundException expected) {
29        }
30        catch (NoClassDefFoundError notFatal) {
31        }
32        return false;
33    }
34
35    Class classFromFile(String classFileName) throws ClassNotFoundException {
36        String className= classNameFromFile(classFileName);
37        if (!fLoader.isExcluded(className))
38            return fLoader.loadClass(className, false);
39        return null;
40    }
41
42    boolean isTestClass(Class testClass) {
43        if (hasSuiteMethod(testClass))
44            return true;
45        if (Test.class.isAssignableFrom(testClass) &&
46                Modifier.isPublic(testClass.getModifiers()) &&
47                hasPublicConstructor(testClass))
48            return true;
49        return false;
50    }
51
52    boolean hasSuiteMethod(Class testClass) {
53        try {
54            testClass.getMethod(BaseTestRunner.SUITE_METHODNAME, new Class[0]);
55        } catch(Exception e) {
56            return false;
57        }
58        return true;
59    }
60
61    boolean hasPublicConstructor(Class testClass) {
62        try {
63            TestSuite.getTestConstructor(testClass);
64        } catch(NoSuchMethodException e) {
65            return false;
66        }
67        return true;
68    }
69}
70