1cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffinpackage junit.framework;
2cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin
3cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffinimport java.io.PrintWriter;
4cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffinimport java.io.StringWriter;
5cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffinimport java.lang.reflect.Constructor;
6cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffinimport java.lang.reflect.InvocationTargetException;
7cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffinimport java.lang.reflect.Method;
8cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffinimport java.lang.reflect.Modifier;
9cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffinimport java.util.ArrayList;
10cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffinimport java.util.Enumeration;
11cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffinimport java.util.List;
12cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffinimport java.util.Vector;
13cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin
14cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin/**
15cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin * <p>A <code>TestSuite</code> is a <code>Composite</code> of Tests.
16cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin * It runs a collection of test cases. Here is an example using
17cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin * the dynamic test definition.
18cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin * <pre>
19cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin * TestSuite suite= new TestSuite();
20cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin * suite.addTest(new MathTest("testAdd"));
21cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin * suite.addTest(new MathTest("testDivideByZero"));
22cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin * </pre>
23cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin * </p>
24cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin *
25cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin * <p>Alternatively, a TestSuite can extract the tests to be run automatically.
26cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin * To do so you pass the class of your TestCase class to the
27cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin * TestSuite constructor.
28cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin * <pre>
29cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin * TestSuite suite= new TestSuite(MathTest.class);
30cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin * </pre>
31cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin * </p>
32cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin *
33cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin * <p>This constructor creates a suite with all the methods
34cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin * starting with "test" that take no arguments.</p>
35cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin *
36cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin * <p>A final option is to do the same for a large array of test classes.
37cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin * <pre>
38cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin * Class[] testClasses = { MathTest.class, AnotherTest.class }
39cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin * TestSuite suite= new TestSuite(testClasses);
40cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin * </pre>
41cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin * </p>
42cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin *
43cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin * @see Test
44cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin */
45cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffinpublic class TestSuite implements Test {
46cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin
47cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	/**
48cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	 * ...as the moon sets over the early morning Merlin, Oregon
49cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	 * mountains, our intrepid adventurers type...
50cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	 */
51cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	static public Test createTest(Class<?> theClass, String name) {
52cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin		Constructor<?> constructor;
53cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin		try {
54cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin			constructor= getTestConstructor(theClass);
55cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin		} catch (NoSuchMethodException e) {
56cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin			return warning("Class "+theClass.getName()+" has no public constructor TestCase(String name) or TestCase()");
57cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin		}
58cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin		Object test;
59cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin		try {
60cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin			if (constructor.getParameterTypes().length == 0) {
61cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin				test= constructor.newInstance(new Object[0]);
62cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin				if (test instanceof TestCase)
63cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin					((TestCase) test).setName(name);
64cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin			} else {
65cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin				test= constructor.newInstance(new Object[]{name});
66cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin			}
67cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin		} catch (InstantiationException e) {
68cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin			return(warning("Cannot instantiate test case: "+name+" ("+exceptionToString(e)+")"));
69cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin		} catch (InvocationTargetException e) {
70cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin			return(warning("Exception in constructor: "+name+" ("+exceptionToString(e.getTargetException())+")"));
71cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin		} catch (IllegalAccessException e) {
72cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin			return(warning("Cannot access test case: "+name+" ("+exceptionToString(e)+")"));
73cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin		}
74cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin		return (Test) test;
75cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	}
76cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin
77cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	/**
78cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	 * Gets a constructor which takes a single String as
79cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	 * its argument or a no arg constructor.
80cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	 */
81cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	public static Constructor<?> getTestConstructor(Class<?> theClass) throws NoSuchMethodException {
82cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin		try {
83cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin			return theClass.getConstructor(String.class);
84cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin		} catch (NoSuchMethodException e) {
85cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin			// fall through
86cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin		}
87cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin		return theClass.getConstructor(new Class[0]);
88cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	}
89cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin
90cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	/**
91cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	 * Returns a test which will fail and log a warning message.
92cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	 */
93cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	public static Test warning(final String message) {
94cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin		return new TestCase("warning") {
95cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin			@Override
96cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin			protected void runTest() {
97cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin				fail(message);
98cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin			}
99cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin		};
100cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	}
101cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin
102cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	/**
103cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	 * Converts the stack trace into a string
104cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	 */
105cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	private static String exceptionToString(Throwable t) {
106cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin		StringWriter stringWriter= new StringWriter();
107cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin		PrintWriter writer= new PrintWriter(stringWriter);
108cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin		t.printStackTrace(writer);
109cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin		return stringWriter.toString();
110cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	}
111cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin
112cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	private String fName;
113cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin
114cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	private Vector<Test> fTests= new Vector<Test>(10); // Cannot convert this to List because it is used directly by some test runners
115cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin
116cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin    /**
117cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	 * Constructs an empty TestSuite.
118cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	 */
119cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	public TestSuite() {
120cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	}
121cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin
122cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	/**
123cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	 * Constructs a TestSuite from the given class. Adds all the methods
124cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	 * starting with "test" as test cases to the suite.
125cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	 * Parts of this method were written at 2337 meters in the Hueffihuette,
126cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	 * Kanton Uri
127cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	 */
128cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	public TestSuite(final Class<?> theClass) {
129cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin		addTestsFromTestCase(theClass);
130cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	}
131cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin
132cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	private void addTestsFromTestCase(final Class<?> theClass) {
133cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin		fName= theClass.getName();
134cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin		try {
135cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin			getTestConstructor(theClass); // Avoid generating multiple error messages
136cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin		} catch (NoSuchMethodException e) {
137cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin			addTest(warning("Class "+theClass.getName()+" has no public constructor TestCase(String name) or TestCase()"));
138cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin			return;
139cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin		}
140cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin
141cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin		if (!Modifier.isPublic(theClass.getModifiers())) {
142cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin			addTest(warning("Class "+theClass.getName()+" is not public"));
143cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin			return;
144cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin		}
145cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin
146cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin		Class<?> superClass= theClass;
147cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin		List<String> names= new ArrayList<String>();
148cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin		while (Test.class.isAssignableFrom(superClass)) {
149cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin			for (Method each : superClass.getDeclaredMethods())
150cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin				addTestMethod(each, names, theClass);
151cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin			superClass= superClass.getSuperclass();
152cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin		}
153cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin		if (fTests.size() == 0)
154cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin			addTest(warning("No tests found in "+theClass.getName()));
155cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	}
156cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin
157cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	/**
158cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	 * Constructs a TestSuite from the given class with the given name.
159cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	 * @see TestSuite#TestSuite(Class)
160cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	 */
161cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	public TestSuite(Class<? extends TestCase>  theClass, String name) {
162cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin		this(theClass);
163cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin		setName(name);
164cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	}
165cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin
166cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin   	/**
167cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	 * Constructs an empty TestSuite.
168cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	 */
169cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	public TestSuite(String name) {
170cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin		setName(name);
171cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	}
172cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin
173cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	/**
174cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	 * Constructs a TestSuite from the given array of classes.
175cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	 * @param classes {@link TestCase}s
176cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	 */
177cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	public TestSuite (Class<?>... classes) {
178cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin		for (Class<?> each : classes)
179cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin			addTest(testCaseForClass(each));
180cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	}
181cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin
182cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	private Test testCaseForClass(Class<?> each) {
183cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin		if (TestCase.class.isAssignableFrom(each))
184cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin			return new TestSuite(each.asSubclass(TestCase.class));
185cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin		else
186cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin			return warning(each.getCanonicalName() + " does not extend TestCase");
187cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	}
188cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin
189cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	/**
190cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	 * Constructs a TestSuite from the given array of classes with the given name.
191cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	 * @see TestSuite#TestSuite(Class[])
192cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	 */
193cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	public TestSuite(Class<? extends TestCase>[] classes, String name) {
194cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin		this(classes);
195cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin		setName(name);
196cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	}
197cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin
198cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	/**
199cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	 * Adds a test to the suite.
200cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	 */
201cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	public void addTest(Test test) {
202cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin		fTests.add(test);
203cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	}
204cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin
205cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	/**
206cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	 * Adds the tests from the given class to the suite
207cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	 */
208cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	public void addTestSuite(Class<? extends TestCase> testClass) {
209cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin		addTest(new TestSuite(testClass));
210cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	}
211cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin
212cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	/**
213cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	 * Counts the number of test cases that will be run by this test.
214cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	 */
215cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	public int countTestCases() {
216cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin		int count= 0;
217cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin		for (Test each : fTests)
218cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin			count+=  each.countTestCases();
219cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin		return count;
220cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	}
221cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin
222cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	/**
223cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	 * Returns the name of the suite. Not all
224cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	 * test suites have a name and this method
225cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	 * can return null.
226cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	 */
227cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	public String getName() {
228cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin		return fName;
229cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	}
230cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin
231cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	/**
232cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	 * Runs the tests and collects their result in a TestResult.
233cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	 */
234cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	public void run(TestResult result) {
235cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin		for (Test each : fTests) {
236cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	  		if (result.shouldStop() )
237cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	  			break;
238cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin			runTest(each, result);
239cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin		}
240cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	}
241cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin
242cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	public void runTest(Test test, TestResult result) {
243cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin		test.run(result);
244cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	}
245cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin
246cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	/**
247cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	 * Sets the name of the suite.
248cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	 * @param name the name to set
249cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	 */
250cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	public void setName(String name) {
251cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin		fName= name;
252cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	}
253cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin
254cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	/**
255cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	 * Returns the test at the given index
256cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	 */
257cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	public Test testAt(int index) {
258cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin		return fTests.get(index);
259cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	}
260cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin
261cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	/**
262cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	 * Returns the number of tests in this suite
263cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	 */
264cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	public int testCount() {
265cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin		return fTests.size();
266cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	}
267cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin
268cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	/**
269cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	 * Returns the tests as an enumeration
270cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	 */
271cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	public Enumeration<Test> tests() {
272cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin		return fTests.elements();
273cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	}
274cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin
275cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	/**
276cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	 */
277cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	@Override
278cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	public String toString() {
279cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin		if (getName() != null)
280cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin			return getName();
281cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin		return super.toString();
282cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	 }
283cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin
284cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	private void addTestMethod(Method m, List<String> names, Class<?> theClass) {
285cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin		String name= m.getName();
286cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin		if (names.contains(name))
287cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin			return;
288cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin		if (! isPublicTestMethod(m)) {
289cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin			if (isTestMethod(m))
290cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin				addTest(warning("Test method isn't public: "+ m.getName() + "(" + theClass.getCanonicalName() + ")"));
291cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin			return;
292cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin		}
293cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin		names.add(name);
294cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin		addTest(createTest(theClass, name));
295cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	}
296cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin
297cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	private boolean isPublicTestMethod(Method m) {
298cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin		return isTestMethod(m) && Modifier.isPublic(m.getModifiers());
299cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	 }
300cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin
301cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	private boolean isTestMethod(Method m) {
302cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin		return
303cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin			m.getParameterTypes().length == 0 &&
304cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin			m.getName().startsWith("test") &&
305cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin			m.getReturnType().equals(Void.TYPE);
306cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin	 }
307cd7c34d8bf4302e640c742d7bb94107cc1505affPaul Duffin}