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 }