001 package groovy.util;
002
003 import groovy.lang.GroovyClassLoader;
004 import groovy.lang.Script;
005 import junit.framework.Test;
006 import junit.framework.TestSuite;
007 import org.codehaus.groovy.control.CompilationFailedException;
008 import org.codehaus.groovy.runtime.ScriptTestAdapter;
009
010 import java.io.File;
011 import java.io.IOException;
012 import java.util.Collection;
013 import java.util.Iterator;
014 import java.util.logging.Logger;
015
016 /**
017 * AllTestSuite can be used in extension of GroovyTestSuite to execute TestCases written in Groovy
018 * from inside a Java IDE.
019 * AllTestSuite collects all files below a given directory that comply to a given pattern.
020 * From these files, a TestSuite is constructed that can be run via an IDE graphical Test runner.
021 * The files are assumed to be Groovy source files and be either a TestCase or a Script that can
022 * be wrapped transparently into a TestCase.
023 * The directory and the pattern can be set via System properties (see this classes' constants for details.)
024 *
025 * When setting the loglevel of this class to FINEST, all file loading will be logged.
026 *
027 * See also groovy.util.AllTestSuiteTest.groovy
028 * @author Dierk Koenig based on a prototype by Andrew Glover
029 * todo: dk: make FileNameFinder injectable
030 */
031 public class AllTestSuite extends TestSuite {
032
033 /** The System Property to set as base directory for collection of Test Cases.
034 * The pattern will be used as an Ant fileset include basedir.
035 * Key is "groovy.test.dir".
036 * Default value is "./test/".
037 */
038 public static final String SYSPROP_TEST_DIR = "groovy.test.dir";
039
040 /** The System Property to set as the filename pattern for collection of Test Cases.
041 * The pattern will be used as Regualar Expression pattern applied with the find
042 * operator agains each candidate file.path.
043 * Key is "groovy.test.pattern".
044 * Default value is "Test.groovy".
045 */
046 public static final String SYSPROP_TEST_PATTERN = "groovy.test.pattern";
047
048 private static Logger LOG = Logger.getLogger(AllTestSuite.class.getName());
049 private static ClassLoader JAVA_LOADER = AllTestSuite.class.getClassLoader();
050 private static GroovyClassLoader GROOVY_LOADER = new GroovyClassLoader(JAVA_LOADER);
051
052 private static final String[] EMPTY_ARGS = new String[]{};
053 private static IFileNameFinder FINDER = null;
054
055 static { // this is only needed since the Groovy Build compiles *.groovy files after *.java files
056 try {
057 Class finderClass = Class.forName("groovy.util.FileNameFinder");
058 FINDER = (IFileNameFinder) finderClass.newInstance();
059 } catch (Exception e) {
060 throw new RuntimeException("Cannot find and instantiate class FileNameFinder", e);
061 }
062 }
063
064 public static Test suite() {
065 String basedir = System.getProperty(SYSPROP_TEST_DIR, "./test/");
066 String pattern = System.getProperty(SYSPROP_TEST_PATTERN, "**/*Test.groovy");
067 return suite(basedir, pattern);
068 }
069
070 public static Test suite(String basedir, String pattern) {
071 AllTestSuite suite = new AllTestSuite();
072 String fileName = "";
073 try {
074 Collection filenames = FINDER.getFileNames(basedir, pattern);
075 for (Iterator iter = filenames.iterator(); iter.hasNext();) {
076 fileName = (String) iter.next();
077 LOG.finest("trying to load "+ fileName);
078 suite.loadTest(fileName);
079 }
080 } catch (CompilationFailedException e1) {
081 e1.printStackTrace();
082 throw new RuntimeException("CompilationFailedException when loading "+fileName, e1);
083 } catch (IOException e2) {
084 throw new RuntimeException("IOException when loading "+fileName, e2);
085 }
086 return suite;
087 }
088
089 protected void loadTest(String fileName) throws CompilationFailedException, IOException {
090 Class type = compile(fileName);
091 if (!Test.class.isAssignableFrom(type) && Script.class.isAssignableFrom(type)) {
092 addTest(new ScriptTestAdapter(type, EMPTY_ARGS));
093 } else {
094 addTestSuite(type);
095 }
096 }
097
098 protected Class compile(String fileName) throws CompilationFailedException, IOException {
099 return GROOVY_LOADER.parseClass(new File(fileName));
100 }
101 }