158a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabotpackage junit.framework;
258a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot
358a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabotimport java.io.PrintWriter;
458a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabotimport java.io.StringWriter;
558a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabotimport java.lang.reflect.Constructor;
658a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabotimport java.lang.reflect.InvocationTargetException;
758a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabotimport java.lang.reflect.Method;
858a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabotimport java.lang.reflect.Modifier;
9b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabotimport java.util.ArrayList;
1058a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabotimport java.util.Enumeration;
11b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabotimport java.util.List;
1258a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabotimport java.util.Vector;
1358a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot
1458a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot/**
15b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * <p>A <code>TestSuite</code> is a <code>Composite</code> of Tests.
1658a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot * It runs a collection of test cases. Here is an example using
1758a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot * the dynamic test definition.
1858a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot * <pre>
1958a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot * TestSuite suite= new TestSuite();
2058a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot * suite.addTest(new MathTest("testAdd"));
2158a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot * suite.addTest(new MathTest("testDivideByZero"));
2258a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot * </pre>
23b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * </p>
24b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot *
25b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * <p>Alternatively, a TestSuite can extract the tests to be run automatically.
2658a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot * To do so you pass the class of your TestCase class to the
2758a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot * TestSuite constructor.
2858a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot * <pre>
2958a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot * TestSuite suite= new TestSuite(MathTest.class);
3058a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot * </pre>
31b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * </p>
32b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot *
33b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * <p>This constructor creates a suite with all the methods
34b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * starting with "test" that take no arguments.</p>
35b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot *
36b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * <p>A final option is to do the same for a large array of test classes.
3758a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot * <pre>
3858a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot * Class[] testClasses = { MathTest.class, AnotherTest.class }
3958a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot * TestSuite suite= new TestSuite(testClasses);
4058a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot * </pre>
41b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * </p>
4258a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot *
4358a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot * @see Test
4458a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot */
4558a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabotpublic class TestSuite implements Test {
4658a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot
4758a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	/**
4858a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 * ...as the moon sets over the early morning Merlin, Oregon
4958a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 * mountains, our intrepid adventurers type...
5058a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 */
51b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot	static public Test createTest(Class<?> theClass, String name) {
52b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot		Constructor<?> constructor;
5358a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		try {
5458a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot			constructor= getTestConstructor(theClass);
5558a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		} catch (NoSuchMethodException e) {
5658a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot			return warning("Class "+theClass.getName()+" has no public constructor TestCase(String name) or TestCase()");
5758a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		}
5858a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		Object test;
5958a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		try {
6058a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot			if (constructor.getParameterTypes().length == 0) {
6158a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot				test= constructor.newInstance(new Object[0]);
6258a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot				if (test instanceof TestCase)
6358a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot					((TestCase) test).setName(name);
6458a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot			} else {
6558a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot				test= constructor.newInstance(new Object[]{name});
6658a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot			}
6758a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		} catch (InstantiationException e) {
6858a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot			return(warning("Cannot instantiate test case: "+name+" ("+exceptionToString(e)+")"));
6958a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		} catch (InvocationTargetException e) {
7058a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot			return(warning("Exception in constructor: "+name+" ("+exceptionToString(e.getTargetException())+")"));
7158a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		} catch (IllegalAccessException e) {
7258a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot			return(warning("Cannot access test case: "+name+" ("+exceptionToString(e)+")"));
7358a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		}
7458a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		return (Test) test;
7558a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	}
7658a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot
7758a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	/**
7858a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 * Gets a constructor which takes a single String as
7958a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 * its argument or a no arg constructor.
8058a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 */
81b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot	public static Constructor<?> getTestConstructor(Class<?> theClass) throws NoSuchMethodException {
8258a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		try {
83b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot			return theClass.getConstructor(String.class);
8458a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		} catch (NoSuchMethodException e) {
8558a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot			// fall through
8658a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		}
8758a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		return theClass.getConstructor(new Class[0]);
8858a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	}
8958a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot
9058a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	/**
9158a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 * Returns a test which will fail and log a warning message.
9258a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 */
9358a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	public static Test warning(final String message) {
9458a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		return new TestCase("warning") {
95b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot			@Override
9658a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot			protected void runTest() {
9758a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot				fail(message);
9858a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot			}
9958a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		};
10058a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	}
10158a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot
10258a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	/**
10358a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 * Converts the stack trace into a string
10458a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 */
10558a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	private static String exceptionToString(Throwable t) {
10658a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		StringWriter stringWriter= new StringWriter();
10758a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		PrintWriter writer= new PrintWriter(stringWriter);
10858a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		t.printStackTrace(writer);
10958a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		return stringWriter.toString();
11058a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	}
111b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot
11258a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	private String fName;
11358a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot
114b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot	private Vector<Test> fTests= new Vector<Test>(10); // Cannot convert this to List because it is used directly by some test runners
11558a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot
11658a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot    /**
11758a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 * Constructs an empty TestSuite.
11858a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 */
11958a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	public TestSuite() {
12058a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	}
12158a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot
12258a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	/**
12358a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 * Constructs a TestSuite from the given class. Adds all the methods
12458a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 * starting with "test" as test cases to the suite.
125b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot	 * Parts of this method were written at 2337 meters in the Hueffihuette,
12658a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 * Kanton Uri
12758a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 */
128b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot	public TestSuite(final Class<?> theClass) {
129b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot		addTestsFromTestCase(theClass);
130b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot	}
131b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot
132b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot	private void addTestsFromTestCase(final Class<?> theClass) {
13358a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		fName= theClass.getName();
13458a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		try {
13558a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot			getTestConstructor(theClass); // Avoid generating multiple error messages
13658a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		} catch (NoSuchMethodException e) {
13758a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot			addTest(warning("Class "+theClass.getName()+" has no public constructor TestCase(String name) or TestCase()"));
13858a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot			return;
13958a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		}
14058a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot
14158a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		if (!Modifier.isPublic(theClass.getModifiers())) {
14258a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot			addTest(warning("Class "+theClass.getName()+" is not public"));
14358a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot			return;
14458a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		}
14558a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot
146b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot		Class<?> superClass= theClass;
147b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot		List<String> names= new ArrayList<String>();
14858a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		while (Test.class.isAssignableFrom(superClass)) {
149b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot			for (Method each : superClass.getDeclaredMethods())
150b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot				addTestMethod(each, names, theClass);
15158a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot			superClass= superClass.getSuperclass();
15258a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		}
15358a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		if (fTests.size() == 0)
15458a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot			addTest(warning("No tests found in "+theClass.getName()));
15558a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	}
15658a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot
15758a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	/**
15858a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 * Constructs a TestSuite from the given class with the given name.
15958a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 * @see TestSuite#TestSuite(Class)
16058a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 */
161b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot	public TestSuite(Class<? extends TestCase>  theClass, String name) {
16258a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		this(theClass);
16358a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		setName(name);
16458a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	}
16558a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot
16658a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot   	/**
16758a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 * Constructs an empty TestSuite.
16858a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 */
16958a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	public TestSuite(String name) {
17058a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		setName(name);
17158a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	}
17258a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot
17358a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	/**
17458a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 * Constructs a TestSuite from the given array of classes.
175b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot	 * @param classes {@link TestCase}s
17658a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 */
177b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot	public TestSuite (Class<?>... classes) {
178b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot		for (Class<?> each : classes)
179b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot			addTest(testCaseForClass(each));
180b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot	}
181b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot
182b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot	private Test testCaseForClass(Class<?> each) {
183b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot		if (TestCase.class.isAssignableFrom(each))
184b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot			return new TestSuite(each.asSubclass(TestCase.class));
185b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot		else
186b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot			return warning(each.getCanonicalName() + " does not extend TestCase");
18758a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	}
18858a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot
18958a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	/**
19058a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 * Constructs a TestSuite from the given array of classes with the given name.
19158a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 * @see TestSuite#TestSuite(Class[])
19258a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 */
193b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot	public TestSuite(Class<? extends TestCase>[] classes, String name) {
19458a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		this(classes);
19558a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		setName(name);
19658a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	}
19758a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot
19858a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	/**
19958a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 * Adds a test to the suite.
20058a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 */
20158a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	public void addTest(Test test) {
202b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot		fTests.add(test);
20358a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	}
20458a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot
20558a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	/**
20658a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 * Adds the tests from the given class to the suite
20758a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 */
208b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot	public void addTestSuite(Class<? extends TestCase> testClass) {
20958a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		addTest(new TestSuite(testClass));
21058a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	}
21158a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot
21258a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	/**
21358a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 * Counts the number of test cases that will be run by this test.
21458a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 */
21558a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	public int countTestCases() {
21658a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		int count= 0;
217b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot		for (Test each : fTests)
218b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot			count+=  each.countTestCases();
21958a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		return count;
22058a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	}
22158a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot
22258a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	/**
22358a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 * Returns the name of the suite. Not all
22458a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 * test suites have a name and this method
22558a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 * can return null.
22658a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 */
22758a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	public String getName() {
22858a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		return fName;
22958a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	}
23058a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot
23158a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	/**
23258a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 * Runs the tests and collects their result in a TestResult.
23358a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 */
23458a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	public void run(TestResult result) {
235b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot		for (Test each : fTests) {
23658a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	  		if (result.shouldStop() )
23758a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	  			break;
238b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot			runTest(each, result);
23958a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		}
24058a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	}
24158a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot
24258a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	public void runTest(Test test, TestResult result) {
24358a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		test.run(result);
24458a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	}
24558a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot
24658a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	/**
24758a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 * Sets the name of the suite.
248b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot	 * @param name the name to set
24958a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 */
25058a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	public void setName(String name) {
25158a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		fName= name;
25258a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	}
25358a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot
25458a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	/**
25558a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 * Returns the test at the given index
25658a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 */
25758a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	public Test testAt(int index) {
258b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot		return fTests.get(index);
25958a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	}
26058a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot
26158a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	/**
26258a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 * Returns the number of tests in this suite
26358a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 */
26458a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	public int testCount() {
26558a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		return fTests.size();
26658a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	}
26758a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot
26858a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	/**
26958a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 * Returns the tests as an enumeration
27058a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 */
271b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot	public Enumeration<Test> tests() {
27258a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		return fTests.elements();
27358a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	}
27458a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot
27558a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	/**
27658a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 */
277b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot	@Override
27858a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	public String toString() {
27958a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		if (getName() != null)
28058a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot			return getName();
28158a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		return super.toString();
28258a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 }
28358a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot
284b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot	private void addTestMethod(Method m, List<String> names, Class<?> theClass) {
28558a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		String name= m.getName();
28658a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		if (names.contains(name))
28758a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot			return;
28858a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		if (! isPublicTestMethod(m)) {
28958a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot			if (isTestMethod(m))
290b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot				addTest(warning("Test method isn't public: "+ m.getName() + "(" + theClass.getCanonicalName() + ")"));
29158a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot			return;
29258a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		}
293b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot		names.add(name);
29458a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		addTest(createTest(theClass, name));
29558a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	}
29658a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot
29758a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	private boolean isPublicTestMethod(Method m) {
29858a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		return isTestMethod(m) && Modifier.isPublic(m.getModifiers());
29958a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 }
30058a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot
30158a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	private boolean isTestMethod(Method m) {
302b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot		return
303b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot			m.getParameterTypes().length == 0 &&
304b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot			m.getName().startsWith("test") &&
305b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot			m.getReturnType().equals(Void.TYPE);
30658a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	 }
30758a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot}