1 package groovy.util;
2
3 import groovy.lang.GroovyClassLoader;
4 import groovy.lang.Script;
5 import junit.framework.Test;
6 import junit.framework.TestSuite;
7 import org.codehaus.groovy.control.CompilationFailedException;
8 import org.codehaus.groovy.runtime.ScriptTestAdapter;
9
10 import java.io.File;
11 import java.io.IOException;
12 import java.util.Collection;
13 import java.util.Iterator;
14 import java.util.logging.Logger;
15
16 /***
17 * AllTestSuite can be used in extension of GroovyTestSuite to execute TestCases written in Groovy
18 * from inside a Java IDE.
19 * AllTestSuite collects all files below a given directory that comply to a given pattern.
20 * From these files, a TestSuite is constructed that can be run via an IDE graphical Test runner.
21 * The files are assumed to be Groovy source files and be either a TestCase or a Script that can
22 * be wrapped transparently into a TestCase.
23 * The directory and the pattern can be set via System properties (see this classes' constants for details.)
24 *
25 * When setting the loglevel of this class to FINEST, all file loading will be logged.
26 *
27 * See also groovy.util.AllTestSuiteTest.groovy
28 * @author Dierk Koenig based on a prototype by Andrew Glover
29 * todo: dk: make FileNameFinder injectable
30 */
31 public class AllTestSuite extends TestSuite {
32
33 /*** The System Property to set as base directory for collection of Test Cases.
34 * The pattern will be used as an Ant fileset include basedir.
35 * Key is "groovy.test.dir".
36 * Default value is "./test/".
37 */
38 public static final String SYSPROP_TEST_DIR = "groovy.test.dir";
39
40 /*** The System Property to set as the filename pattern for collection of Test Cases.
41 * The pattern will be used as Regualar Expression pattern applied with the find
42 * operator agains each candidate file.path.
43 * Key is "groovy.test.pattern".
44 * Default value is "Test.groovy".
45 */
46 public static final String SYSPROP_TEST_PATTERN = "groovy.test.pattern";
47
48 private static Logger LOG = Logger.getLogger(AllTestSuite.class.getName());
49 private static ClassLoader JAVA_LOADER = AllTestSuite.class.getClassLoader();
50 private static GroovyClassLoader GROOVY_LOADER = new GroovyClassLoader(JAVA_LOADER);
51
52 private static final String[] EMPTY_ARGS = new String[]{};
53 private static IFileNameFinder FINDER = null;
54
55 static {
56 try {
57 Class finderClass = Class.forName("groovy.util.FileNameFinder");
58 FINDER = (IFileNameFinder) finderClass.newInstance();
59 } catch (Exception e) {
60 throw new RuntimeException("Cannot find and instantiate class FileNameFinder", e);
61 }
62 }
63
64 public static Test suite() {
65 String basedir = System.getProperty(SYSPROP_TEST_DIR, "./test/");
66 String pattern = System.getProperty(SYSPROP_TEST_PATTERN, "**/*Test.groovy");
67 return suite(basedir, pattern);
68 }
69
70 public static Test suite(String basedir, String pattern) {
71 AllTestSuite suite = new AllTestSuite();
72 String fileName = "";
73 try {
74 Collection filenames = FINDER.getFileNames(basedir, pattern);
75 for (Iterator iter = filenames.iterator(); iter.hasNext();) {
76 fileName = (String) iter.next();
77 LOG.finest("trying to load "+ fileName);
78 suite.loadTest(fileName);
79 }
80 } catch (CompilationFailedException e1) {
81 e1.printStackTrace();
82 throw new RuntimeException("CompilationFailedException when loading "+fileName, e1);
83 } catch (IOException e2) {
84 throw new RuntimeException("IOException when loading "+fileName, e2);
85 }
86 return suite;
87 }
88
89 protected void loadTest(String fileName) throws CompilationFailedException, IOException {
90 Class type = compile(fileName);
91 if (!Test.class.isAssignableFrom(type) && Script.class.isAssignableFrom(type)) {
92 addTest(new ScriptTestAdapter(type, EMPTY_ARGS));
93 } else {
94 addTestSuite(type);
95 }
96 }
97
98 protected Class compile(String fileName) throws CompilationFailedException, IOException {
99 return GROOVY_LOADER.parseClass(new File(fileName));
100 }
101 }