# Bazaar merge directive format 2 (Bazaar 0.90)
# revision_id: teyckmans@gmail.com-20081101193149-10qk8ojyr39w1yt1
# target_branch: http://bazaar.launchpad.net/%7Erussel/gradle/testng/
# testament_sha1: c226cb6f488c5212d36d5826d081f0ec87520569
# timestamp: 2008-11-01 20:32:06 +0100
# base_revision_id: svn-v3-trunk1:004c2c75-fc45-0410-b1a2-\
#   da8352e2331b:gradle-core%2Ftrunk:1052
# 
# Begin patch
=== modified file '.bzrignore'
--- .bzrignore	2008-10-11 07:49:35 +0000
+++ .bzrignore	2008-11-01 19:08:30 +0000
@@ -5,3 +5,10 @@
 src/docs/userguide/*.out
 src/docs/userguide/*.log
 src/docs/userguide/*.toc
+out
+test-output
+tmpTest
+gradle-testng.ipr
+gradle-testng.iws
+*.ml
+testng.iml

=== modified file 'src/main/groovy/org/gradle/api/plugins/GroovyPlugin.java'
--- src/main/groovy/org/gradle/api/plugins/GroovyPlugin.java	2008-10-21 08:59:48 +0000
+++ src/main/groovy/org/gradle/api/plugins/GroovyPlugin.java	2008-11-01 19:08:30 +0000
@@ -47,7 +47,7 @@
 
         configureTestCompile(project);
 
-        ((Test) project.task(TEST)).getOptions().getForkOptions().setForkMode(ForkMode.ONCE);
+        ((Test) project.task(TEST)).groovyConfigure();
 
         configureJavadoc(project);
 

=== modified file 'src/main/groovy/org/gradle/api/plugins/JavaPlugin.java'
--- src/main/groovy/org/gradle/api/plugins/JavaPlugin.java	2008-10-29 21:50:56 +0000
+++ src/main/groovy/org/gradle/api/plugins/JavaPlugin.java	2008-11-01 19:08:30 +0000
@@ -37,7 +37,6 @@
 import org.gradle.api.tasks.ide.eclipse.EclipseWtpModule;
 import org.gradle.api.tasks.javadoc.Javadoc;
 import org.gradle.api.tasks.testing.Test;
-import org.gradle.api.tasks.testing.ForkMode;
 import org.gradle.api.tasks.util.FileSet;
 import org.gradle.util.GUtil;
 import org.gradle.util.WrapUtil;
@@ -242,10 +241,7 @@
     private void configureTest(Project project) {
         final Test test = (Test) project.createTask(GUtil.map("type", Test.class, "dependsOn", TEST_COMPILE), TEST);
         test.conventionMapping(DefaultConventionsToPropertiesMapping.TEST);
-        test.getOptions().setFork(true);
-        test.getOptions().getForkOptions().setForkMode(ForkMode.PER_TEST);
-        test.getOptions().getForkOptions().setDir(project.getProjectDir());
-        test.include("**/*Tests.class", "**/*Test.class", "**/Abstract*.class");
+        test.javaConfigure();
         test.doFirst(new TaskAction() {
             public void execute(Task task) {
                 Test test = (Test) task;

=== added file 'src/main/groovy/org/gradle/api/tasks/testing/AbstractAntTestTask.groovy'
--- src/main/groovy/org/gradle/api/tasks/testing/AbstractAntTestTask.groovy	1970-01-01 00:00:00 +0000
+++ src/main/groovy/org/gradle/api/tasks/testing/AbstractAntTestTask.groovy	2008-10-30 22:56:48 +0000
@@ -0,0 +1,17 @@
+package org.gradle.api.tasks.testing
+
+/**
+ * @author Tom Eyckmans
+ */
+abstract class AbstractAntTestTask {
+    abstract void execute(File compiledTestsClassesDir, List classPath, File testResultsDir, File testReportDir, List includes, List excludes, TestOptions testngOptions, AntBuilder ant)
+
+    protected void createAntClassPath(AntBuilder ant, List classpath) {
+        ant.path(id: CLASSPATH_ID) {
+            classpath.each {
+                logger.debug("Add {} to Ant classpath!", it)
+                pathelement(location: it)
+            }
+        }
+    }
+}
\ No newline at end of file

=== modified file 'src/main/groovy/org/gradle/api/tasks/testing/AntJunit.groovy'
--- src/main/groovy/org/gradle/api/tasks/testing/AntJunit.groovy	2008-10-29 21:50:56 +0000
+++ src/main/groovy/org/gradle/api/tasks/testing/AntJunit.groovy	2008-11-01 19:08:30 +0000
@@ -19,7 +19,7 @@
 import org.gradle.util.BootstrapUtil
 import org.slf4j.Logger
 import org.slf4j.LoggerFactory
-
+import org.gradle.api.tasks.testing.AbstractAntTestTask
 
 /**
  * @author Hans Dockter
@@ -27,14 +27,14 @@
 //todo: assertions for fork and permissions for non fork
 //todo: offer all the power of ant selectors
 //todo: Find a more stable way to find the ant junit jars
-class AntJunit {
+class AntJunit extends AbstractAntTestTask {
     private static Logger logger = LoggerFactory.getLogger(AntJunit)
 
     private static final String CLASSPATH_ID = 'runtests.classpath'
 
-    public static final String FAILURES_OR_ERRORS_PROPERTY = 'org.gradle.api.tasks.testing.failuresOrErrors'
+    public static final String FAILURES_OR_ERRORS_PROPERTY = "org.gradle.api.tasks.testing.failuresOrErrors"
 
-    void execute(File compiledTestsClassesDir, List classPath, File testResultsDir, File testReportDir, List includes, List excludes, JunitOptions junitOptions, AntBuilder ant) {
+    void execute(File compiledTestsClassesDir, List classPath, File testResultsDir, File testReportDir, List includes, List excludes, TestOptions junitOptions, AntBuilder ant) {
         ant.mkdir(dir: testResultsDir.absolutePath)
         createAntClassPath(ant, classPath + BootstrapUtil.antJunitJarFiles)
         Map otherArgs = [
@@ -73,7 +73,7 @@
         }
     }
 
-    private void createAntClassPath(AntBuilder ant, List classpath) {
+      /*private*/ protected void createAntClassPath(AntBuilder ant, List classpath) {
         ant.path(id: CLASSPATH_ID) {
             classpath.each {
                 logger.debug("Add {} to Ant classpath!", it)

=== added file 'src/main/groovy/org/gradle/api/tasks/testing/AntTestNG.groovy'
--- src/main/groovy/org/gradle/api/tasks/testing/AntTestNG.groovy	1970-01-01 00:00:00 +0000
+++ src/main/groovy/org/gradle/api/tasks/testing/AntTestNG.groovy	2008-11-01 19:08:30 +0000
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2008 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.gradle.api.tasks.testing
+
+import org.gradle.util.BootstrapUtil
+import org.slf4j.Logger
+import org.slf4j.LoggerFactory
+import org.gradle.api.tasks.compile.AbstractOptions
+import org.gradle.api.tasks.testing.AbstractAntTestTask
+
+/**
+ * @author Tom Eyckmans
+ */
+class AntTestNG extends AbstractAntTestTask {
+    private static Logger logger = LoggerFactory.getLogger(AntTestNG);
+
+    static final String CLASSPATH_ID = 'runtests.classpath'
+
+    static final String FAILURES_OR_ERRORS_PROPERTY = 'org.gradle.api.tasks.testing.failuresOrErrors'
+
+    void execute(File compiledTestsClassesDir, List classPath, File testResultsDir, File testReportDir, List includes, List excludes, TestOptions testngOptions, AntBuilder ant) {
+        logger.info("executing testng tests...");
+
+        ant.mkdir(dir: testResultsDir.absolutePath)
+        createAntClassPath(ant, classPath /*+ BootstrapUtil.antTestNGJarFiles*/);
+
+        testngOptions.outputdir = testReportDir.absolutePath;
+        testngOptions.workingDir = testResultsDir.absolutePath;
+
+        Map otherArgs = [
+                failureProperty : FAILURES_OR_ERRORS_PROPERTY,
+                // skippedProperty : ??
+        ]
+
+        ant.taskdef([resource : "testngtasks", classpath : "/home/teyckmans/lib/org/gradle/checkout/testng/testng-tester/lib/testng-5.8.jar"])
+
+        ant.testng(otherArgs + testngOptions.optionMap()) {
+//            testngOptions.jvmArgs.each {
+//                jvmarg(value: it)
+//            }
+//            testngOptions.systemProperties.each {String key, String value ->
+//                sysproperty(key: key, value: value)
+//            }
+//            testngOptions.environment.each {String key, String value ->
+//                env(key: key, value: value)
+//            }
+            classpath {
+                classPath.each {
+                    pathelement(location : it)
+                }
+            }
+            classfileset (dir: compiledTestsClassesDir.absolutePath ) {
+                includes.each {
+                    include(name: it)
+                }
+                excludes.each {
+                    exclude(name: it)
+                }
+            }
+        }
+
+        logger.info("testng tests executed.");
+
+        /*
+        not happy with the output: class and package information is lost
+
+        logger.info("generating test report...")
+
+        ant.junitreport(todir: testReportDir.absolutePath) {
+            fileset(file: new File(testResultsDir, 'Ant suite/Ant test.xml'))
+            report(todir: testReportDir.absolutePath, format: 'noframes') // currently the testng docs mention an incompatability with the frames format
+        }
+        
+        logger.info("test report generated.")
+        */
+    }
+
+
+}

=== renamed file 'src/main/groovy/org/gradle/api/tasks/testing/JunitForkOptions.groovy' => 'src/main/groovy/org/gradle/api/tasks/testing/ForkOptions.groovy'
--- src/main/groovy/org/gradle/api/tasks/testing/JunitForkOptions.groovy	2008-03-10 06:51:58 +0000
+++ src/main/groovy/org/gradle/api/tasks/testing/ForkOptions.groovy	2008-10-30 22:56:48 +0000
@@ -21,7 +21,7 @@
 /**
  * @author Hans Dockter
  */
-class JunitForkOptions extends AbstractOptions {
+class ForkOptions extends AbstractOptions {
     ForkMode forkMode = ForkMode.PER_TEST
     String timeout
     String maxMemory

=== modified file 'src/main/groovy/org/gradle/api/tasks/testing/JunitOptions.groovy'
--- src/main/groovy/org/gradle/api/tasks/testing/JunitOptions.groovy	2008-03-10 06:51:58 +0000
+++ src/main/groovy/org/gradle/api/tasks/testing/JunitOptions.groovy	2008-10-30 22:56:48 +0000
@@ -21,8 +21,7 @@
 /**
  * @author Hans Dockter
  */
-class JunitOptions extends AbstractOptions {
-    boolean fork = true
+class JunitOptions extends TestOptions {
     boolean filterTrace = true
     boolean showOutput = false
     boolean outputToFormatters = true
@@ -32,7 +31,7 @@
     String printSummary = 'true'
 
     FormatterOptions formatterOptions = new FormatterOptions()
-    JunitForkOptions forkOptions = new JunitForkOptions()
+
 
     Map systemProperties = [:]
     Map environment = [:]

=== added file 'src/main/groovy/org/gradle/api/tasks/testing/JunitTestPolicy.groovy'
--- src/main/groovy/org/gradle/api/tasks/testing/JunitTestPolicy.groovy	1970-01-01 00:00:00 +0000
+++ src/main/groovy/org/gradle/api/tasks/testing/JunitTestPolicy.groovy	2008-11-01 19:08:30 +0000
@@ -0,0 +1,36 @@
+package org.gradle.api.tasks.testing
+
+import org.gradle.api.Project
+
+/**
+ * @author Tom Eyckmans
+ */
+class JunitTestPolicy extends TestPolicy {
+
+    void init(Project project, Test test)
+    {
+        test.options = new JunitOptions();
+        test.antTestTask = new AntJunit();
+    }
+
+    public void javaConfigure(Project project, Test test)
+    {
+        final JunitOptions options = (JunitOptions)test.getOptions();
+
+        options.setFork(true);
+        options.getForkOptions().setForkMode(ForkMode.PER_TEST);
+        options.getForkOptions().setDir(project.getProjectDir());
+
+        options.getForkOptions().setForkMode(ForkMode.ONCE);
+
+        super.javaConfigure(project, test);
+    }
+
+    void groovyConfigure(Project project, Test test)
+    {
+        final JunitOptions options = (JunitOptions)test.getOptions();
+
+        options.getForkOptions().setForkMode(ForkMode.ONCE);
+    }
+
+}
\ No newline at end of file

=== modified file 'src/main/groovy/org/gradle/api/tasks/testing/Test.java'
--- src/main/groovy/org/gradle/api/tasks/testing/Test.java	2008-10-29 21:50:56 +0000
+++ src/main/groovy/org/gradle/api/tasks/testing/Test.java	2008-11-01 19:08:30 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright 2007 the original author or authors.
+ * Copyright 2007-8 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -20,40 +20,72 @@
 import org.gradle.api.internal.ConventionTask;
 import org.gradle.api.tasks.compile.ClasspathConverter;
 import org.gradle.api.tasks.util.ExistingDirsFilter;
+import org.gradle.api.tasks.testing.AbstractAntTestTask;
 import org.gradle.util.GUtil;
 import org.gradle.util.WrapUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+//import org.gradle.api.tasks.compile.AbstractOptions;
+
 import java.io.File;
 import java.util.Arrays;
 import java.util.List;
 
 /**
- * A task for executin Junit 3.8.x and Junit 4 tests.
+ * A task for executing Junit 3.8.x and Junit 4 tests.
  * 
  * @author Hans Dockter
  */
 public class Test extends ConventionTask {
     private static Logger logger = LoggerFactory.getLogger(Test.class);
 
-    private File testClassesDir = null;
+     /**
+     * The directory with the compiled test classes
+     */
+   private File testClassesDir = null;
 
+    /**
+     * The directory where the test results are put. Right now only the xml format of the test results is supported.
+     */
     private File testResultsDir = null;
 
+    /**
+     * The directory to generate the test report into.
+     */
     private File testReportDir = null;
 
-    private JunitOptions options = new JunitOptions();
-
+    /**
+     * Include pattern for the filess in the test classes directory (e.g. '**&#2F;*Test.class')).
+     */
     private List<String> includes;
 
+    /**
+     * Exclude pattern for the filess in the test classes directory (e.g. '**&#2F;Abstract*.class').
+     */
     private List<String> excludes;
 
+    /**
+     * If true the build stops with an excepton in case a test fails or throws an uncatched exception. The build
+     * stops in this case after ALL tests have been executed.
+     */
     private boolean stopAtFailuresOrErrors = true;
 
+    /**
+     * This property is used internally by Gradle. It is usually not used by build scripts.
+     * A list of files added to the compile classpath. The files should point to jars or directories containing
+     * class files. The files added here are not shared in a multi-project build and are not mentioned in
+     * a dependency descriptor if you upload your library to a repository.
+     */
     private List unmanagedClasspath = null;
 
-    private AntJunit antJunit = new AntJunit();
+    private TestPolicy testPolicy = null;
+    /**
+     * This task delegates to Ants Junit task for the execution of the tests. This options contain most of the options
+     * of Ants Junit task.
+     */
+    private TestOptions options = null;
+    private AbstractAntTestTask antTestTask = null;
 
     private DependencyManager dependencyManager = null;
 
@@ -71,16 +103,26 @@
     }
 
     protected void executeTests(Task task) {
-        if (getTestClassesDir() == null) throw new InvalidUserDataException(
+        testClassesDir = getTestClassesDir();
+        testResultsDir = getTestResultsDir();
+        testReportDir = getTestReportDir();
+
+        if (testClassesDir == null) throw new InvalidUserDataException(
                 "The testClassesDir property is not set, testing can't be triggered!");
-        if (getTestResultsDir() == null) throw new InvalidUserDataException(
+        if (testResultsDir == null) throw new InvalidUserDataException(
                 "The testResultsDir property is not set, testing can't be triggered!");
 
-        existingDirsFilter.checkExistenceAndThrowStopActionIfNot(getTestClassesDir());
-
-        antJunit.execute(getTestClassesDir(), getClasspath(), getTestResultsDir(), getTestReportDir(), includes,
-                excludes, options, getProject().getAnt());
-        if (stopAtFailuresOrErrors && GUtil.isTrue(getProject().getAnt().getProject().getProperty(AntJunit.FAILURES_OR_ERRORS_PROPERTY))) {
+        existingDirsFilter.checkExistenceAndThrowStopActionIfNot(testClassesDir);
+
+        testResultsDir.mkdir();
+        testReportDir.mkdir();
+
+        antTestTask.execute(testClassesDir, getClasspath(), testResultsDir, testReportDir, includes, excludes, options, getProject().getAnt());
+
+        final String encounteredFailuresOrErrorsString = getProject().getAnt().getProject().getProperty(AntJunit.FAILURES_OR_ERRORS_PROPERTY);
+        final boolean encounteredFailuresOrErrors = GUtil.isTrue(encounteredFailuresOrErrorsString);
+
+        if (stopAtFailuresOrErrors && encounteredFailuresOrErrors) {
             throw new GradleException("There were failing tests. See the report at " + getTestReportDir() + ".");
         }
     }
@@ -177,7 +219,7 @@
      * Returns an JUnit option instance to read or modify.
      * @return
      */
-    public JunitOptions getOptions() {
+    public TestOptions getOptions() {
         return options;
     }
 
@@ -186,7 +228,7 @@
      * 
      * @param options The new instance
      */
-    public void setOptions(JunitOptions options) {
+    public void setOptions(TestOptions options) {
         this.options = options;
     }
 
@@ -263,17 +305,17 @@
     /**
      * Returns the AntJunit instance the test execution is delegated to.
      */
-    public AntJunit getAntJunit() {
-        return antJunit;
+    public AbstractAntTestTask getAntTestTask() {
+        return antTestTask;
     }
 
     /**
      * Sets the AntJunit instance the test execution is delegated to.
      * 
-     * @param antJunit The new instance
+     * @param antTestTask The new instance
      */
-    public void setAntJunit(AntJunit antJunit) {
-        this.antJunit = antJunit;
+    public void setAntTestTask(AbstractAntTestTask antTestTask) {
+        this.antTestTask = antTestTask;
     }
 
     /**
@@ -291,4 +333,78 @@
     public void setDependencyManager(DependencyManager dependencyManager) {
         this.dependencyManager = dependencyManager;
     }
+
+    /**
+     * Base method to initialize the test policy to use.
+     *
+     * Note: this function provides an entry point of other TestPolcies that are not yet bundled in the distribution.
+     *
+     * @param testPolicy The test policy
+     */
+    public void initTestPolicy(TestPolicy testPolicy) {
+        if ( testPolicy == null ) throw new IllegalArgumentException("testPolicy == null!");
+
+        this.testPolicy = testPolicy;
+        testPolicy.init(getProject(), this);
+    }
+
+    /**
+     * Initialize this test with the JunitTestPolicy.
+     *
+     * @see JunitTestPolicy
+     */
+    public void useJunit() {
+        initTestPolicy(new JunitTestPolicy());
+    }
+
+    /**
+     * Initialize this test with the TestNGTestPolicy
+     *
+     * @see TestNGTestPolicy
+     */
+    public void useTestNG () {
+        initTestPolicy(new TestNGTestPolicy());
+    }
+
+    /**
+     * Configures this test for Java test execution.
+     *
+     * If no policy is initialized yet the default test policy will be used (currently hard coded to the JunitTestPolciy).
+     */
+    public void javaConfigure()
+    {
+        initDefaultTestPolicyIfNeeded();
+
+        testPolicy.javaConfigure(getProject(), this);
+    }
+
+    /**
+     * Configures this test for Groovy test execution.
+     *
+     * If no policy is initialized yet the default test policy will be used (currently hard coded to the JunitTestPolciy).
+     */
+    public void groovyConfigure()
+    {
+        initDefaultTestPolicyIfNeeded();
+
+        testPolicy.groovyConfigure(getProject(), this);
+    }
+
+    /**
+     * Initializes this test with the default TestPolicy if no TestPolicy is set yet.
+     *
+     * Currently the default TestPolciy is hard coded to use the JunitTestPolciy.
+     */
+    private void initDefaultTestPolicyIfNeeded()
+    {
+        if ( testPolicy == null ) {
+            // @TODO make configurable
+            useJunit();
+        }
+    }
+
+    public TestPolicy getTestPolicy()
+    {
+        return testPolicy;
+    }
 }

=== added file 'src/main/groovy/org/gradle/api/tasks/testing/TestNGOptions.groovy'
--- src/main/groovy/org/gradle/api/tasks/testing/TestNGOptions.groovy	1970-01-01 00:00:00 +0000
+++ src/main/groovy/org/gradle/api/tasks/testing/TestNGOptions.groovy	2008-11-01 19:08:30 +0000
@@ -0,0 +1,48 @@
+package org.gradle.api.tasks.testing
+
+import org.gradle.api.tasks.compile.AbstractOptions
+
+/**
+ * @author Tom Eyckmans
+ */
+class TestNGOptions extends TestOptions {
+    String annotations = 'JDK'
+    boolean dumpCommand = false
+    boolean enableAssert = true
+    boolean haltonfailure = false
+    boolean haltonskipped = false
+
+//    List<String> groups = new ArrayList<String>()
+//    List<String> excludedgroups = new ArrayList<String>()
+    String jvm = "java"
+
+    String outputdir
+    String sourcedir
+//    String suiteRunnerClass
+//    boolean parallel = false
+//    int threadCount = 1
+//    String testJar
+//    long timeOut = Long.MAX_VALUE
+//    boolean useDefaultListeners = true
+    String workingDir
+//    String suitename = 'Ant suite'
+//    String testname = 'Ant test'
+
+//    List jvmArgs = []
+//    Map systemProperties = [:]
+//    Map environment = [:]
+
+//    List excludedFieldsFromOptionMap() {
+//        ['systemProperties', 'jvmArgs', 'environment']
+//    }
+
+    Map optionMap() {
+        super.optionMap()
+    }
+
+    JunitOptions fork(Map forkArgs) {
+        fork = true
+        forkOptions.define(forkArgs)
+        this
+    }
+}
\ No newline at end of file

=== added file 'src/main/groovy/org/gradle/api/tasks/testing/TestNGTestPolicy.groovy'
--- src/main/groovy/org/gradle/api/tasks/testing/TestNGTestPolicy.groovy	1970-01-01 00:00:00 +0000
+++ src/main/groovy/org/gradle/api/tasks/testing/TestNGTestPolicy.groovy	2008-11-01 19:08:30 +0000
@@ -0,0 +1,21 @@
+package org.gradle.api.tasks.testing
+
+import org.gradle.api.Project
+
+/**
+ * @author Tom Eyckmans
+ */
+class TestNGTestPolicy extends TestPolicy {
+    void init(Project project, Test test)
+    {
+        System.out.println("TestNGTestPolicy [init]")
+        test.options = new TestNGOptions()
+        test.antTestTask = new AntTestNG();
+    }
+
+    void javaConfigure(Project project, Test test)
+    {
+        // ??
+        super.javaConfigure(project, test);
+    }
+}
\ No newline at end of file

=== added file 'src/main/groovy/org/gradle/api/tasks/testing/TestOptions.groovy'
--- src/main/groovy/org/gradle/api/tasks/testing/TestOptions.groovy	1970-01-01 00:00:00 +0000
+++ src/main/groovy/org/gradle/api/tasks/testing/TestOptions.groovy	2008-10-30 22:56:48 +0000
@@ -0,0 +1,11 @@
+package org.gradle.api.tasks.testing
+
+import org.gradle.api.tasks.compile.AbstractOptions
+
+/**
+ * @author Tom Eyckmans
+ */
+abstract class TestOptions extends AbstractOptions {
+    boolean fork = true;
+    ForkOptions forkOptions = new ForkOptions()
+}
\ No newline at end of file

=== added file 'src/main/groovy/org/gradle/api/tasks/testing/TestPolicy.groovy'
--- src/main/groovy/org/gradle/api/tasks/testing/TestPolicy.groovy	1970-01-01 00:00:00 +0000
+++ src/main/groovy/org/gradle/api/tasks/testing/TestPolicy.groovy	2008-11-01 19:08:30 +0000
@@ -0,0 +1,20 @@
+package org.gradle.api.tasks.testing
+
+import org.gradle.api.Project
+
+/**
+ * @author Tom Eyckmans
+ */
+abstract class TestPolicy {
+    abstract void init(Project project, Test test);
+
+    void javaConfigure(Project project, Test test)
+    {
+        test.include("**/*Tests.class", "**/*Test.class", "**/Abstract*.class");
+    }
+
+    void groovyConfigure(Project project, Test test)
+    {
+        
+    }
+}
\ No newline at end of file

=== modified file 'src/test/groovy/org/gradle/api/internal/project/DefaultProjectTest.groovy'
--- src/test/groovy/org/gradle/api/internal/project/DefaultProjectTest.groovy	2008-09-27 07:09:15 +0000
+++ src/test/groovy/org/gradle/api/internal/project/DefaultProjectTest.groovy	2008-11-01 19:08:30 +0000
@@ -450,7 +450,7 @@
         Task mockTask = context.mock(Task)
         project.tasks[TEST_TASK_NAME] = mockTask
         context.checking {
-            one(mockTask).configure(testConfigureClosure); will(returnValue(mockTask))
+            one(mockTask).javaConfigure(testConfigureClosure); will(returnValue(mockTask))
         }
 
         assertThat(project.task(TEST_TASK_NAME, testConfigureClosure), sameInstance(mockTask))

=== modified file 'src/test/groovy/org/gradle/api/tasks/testing/JunitForkOptionsTest.groovy'
--- src/test/groovy/org/gradle/api/tasks/testing/JunitForkOptionsTest.groovy	2008-07-07 11:43:37 +0000
+++ src/test/groovy/org/gradle/api/tasks/testing/JunitForkOptionsTest.groovy	2008-10-30 22:56:48 +0000
@@ -24,10 +24,10 @@
  * @author Hans Dockter
  */
 class JunitForkOptionsTest {
-    JunitForkOptions junitForkOptions
+    ForkOptions junitForkOptions
 
     @Before public void setUp()  {
-        junitForkOptions = new JunitForkOptions()
+        junitForkOptions = new ForkOptions()
     }
 
     @Test public void testJunitForkOptions() {

=== modified file 'src/test/groovy/org/gradle/api/tasks/testing/JunitOptionsTest.groovy'
--- src/test/groovy/org/gradle/api/tasks/testing/JunitOptionsTest.groovy	2008-07-07 11:43:37 +0000
+++ src/test/groovy/org/gradle/api/tasks/testing/JunitOptionsTest.groovy	2008-10-30 22:56:48 +0000
@@ -32,7 +32,7 @@
     @Before public void setUp()  {
         junitOptions = new JunitOptions()
         junitOptions.formatterOptions  = [optionMap: {TEST_FORMATTER_OPTION_MAP}] as FormatterOptions
-        junitOptions.forkOptions = [optionMap: {TEST_FORK_OPTION_MAP}] as JunitForkOptions
+        junitOptions.forkOptions = [optionMap: {TEST_FORK_OPTION_MAP}] as ForkOptions
     }
 
     @Test public void testCompileOptions() {
@@ -104,7 +104,7 @@
         junitOptions.forkOptions = [define: {Map args ->
             forkUseCalled = true
             assertEquals(TEST_FORK_OPTION_MAP, args)
-        }] as JunitForkOptions
+        }] as ForkOptions
         assert junitOptions.fork(TEST_FORK_OPTION_MAP).is(junitOptions)
         assertTrue(junitOptions.fork)
         assertTrue(forkUseCalled)

=== modified file 'src/test/groovy/org/gradle/api/tasks/testing/TestTest.java'
--- src/test/groovy/org/gradle/api/tasks/testing/TestTest.java	2008-10-29 21:50:56 +0000
+++ src/test/groovy/org/gradle/api/tasks/testing/TestTest.java	2008-11-01 19:31:49 +0000
@@ -16,7 +16,6 @@
 
 package org.gradle.api.tasks.testing;
 
-import groovy.mock.interceptor.MockFor;
 import groovy.util.AntBuilder;
 import org.gradle.api.DependencyManager;
 import org.gradle.api.GradleException;
@@ -34,7 +33,6 @@
 import org.hamcrest.Description;
 import static org.junit.Assert.*;
 import org.junit.Before;
-import org.junit.Assert;
 import org.jmock.lib.legacy.ClassImposteriser;
 import org.jmock.integration.junit4.JUnit4Mockery;
 import org.jmock.Expectations;
@@ -42,7 +40,6 @@
 import org.jmock.api.Invocation;
 
 import java.io.File;
-import java.io.PrintWriter;
 import java.util.List;
 
 
@@ -70,6 +67,7 @@
 
     private JUnit4Mockery context = new JUnit4Mockery();
 
+    TestPolicy testPolicyMock;
     AntJunit antJunitMock;
 
     DependencyManager dependencyManagerMock;
@@ -83,10 +81,10 @@
         classpathConverterMock = context.mock(ClasspathConverter.class);
         existentDirsFilterMock = context.mock(ExistingDirsFilter.class);
         dependencyManagerMock = context.mock(DependencyManager.class);
+        testPolicyMock = context.mock(TestPolicy.class);
         super.setUp();
         test = new Test(getProject(), AbstractTaskTest.TEST_TASK_NAME);
         ((AbstractProject) test.getProject()).setProjectDir(TEST_ROOT_DIR);
-        test.setAntJunit(antJunitMock);
     }
 
     public AbstractTask getTask() {
@@ -94,8 +92,9 @@
     }
 
     @org.junit.Test public void testInit() {
-        assertNotNull(test.getAntJunit());
-        assertNotNull(test.getOptions());
+        assertNull(test.getTestPolicy());
+        assertNull(test.getAntTestTask());
+        assertNull(test.getOptions());
         assertNotNull(test.existingDirsFilter);
         assertNotNull(test.classpathConverter);
         assertNull(test.getTestClassesDir());
@@ -105,13 +104,22 @@
         assertNull(test.getIncludes());
         assertNull(test.getExcludes());
         assertNull(test.getUnmanagedClasspath());
+
         assert test.isStopAtFailuresOrErrors();
+
+        test.javaConfigure();
+
+        assertNotNull(test.getTestPolicy());
+        assertNotNull(test.getAntTestTask());
+        assertNotNull(test.getOptions());
+        assertNotNull(test.getIncludes());
     }
 
     @org.junit.Test
     public void testExecute() {
         setUpMocks(test);
         setExistingDirsFilter();
+        test.setAntTestTask(antJunitMock);
         context.checking(new Expectations() {{
             one(antJunitMock).execute(TEST_TEST_CLASSES_DIR, TEST_CONVERTED_CLASSPATH, TEST_TEST_RESULTS_DIR, TEST_TEST_REPORT_DIR,
                     test.getIncludes(), test.getExcludes(), test.getOptions(), getProject().getAnt());
@@ -121,25 +129,27 @@
     }
 
     @org.junit.Test(expected = GradleException.class) 
-    public void testExecuteWithTestFailuresAndStopAtFailures() {
+    public void testJavaExecuteWithTestFailuresAndStopAtFailures() {
         setUpMocks(test);
         setExistingDirsFilter();
+        test.setAntTestTask(antJunitMock);
         context.checking(new Expectations() {{
             one(antJunitMock).execute(TEST_TEST_CLASSES_DIR, TEST_CONVERTED_CLASSPATH, TEST_TEST_RESULTS_DIR, TEST_TEST_REPORT_DIR,
                     test.getIncludes(), test.getExcludes(), test.getOptions(), getProject().getAnt());
-            will(new AntPropertyAction(AntJunit.FAILURES_OR_ERRORS_PROPERTY, "somevalue"));
+            will(new AntPropertyAction("org.gradle.api.tasks.testing.failuresOrErrors", "somevalue"));
         }});
         test.execute();
     }
 
-    @org.junit.Test public void testExecuteWithTestFailuresAndContinueWithFailures() {
+    @org.junit.Test public void testJavaExecuteWithTestFailuresAndContinueWithFailures() {
         setUpMocks(test);
         setExistingDirsFilter();
         test.setStopAtFailuresOrErrors(false);
+        test.setAntTestTask(antJunitMock);
         context.checking(new Expectations() {{
             one(antJunitMock).execute(TEST_TEST_CLASSES_DIR, TEST_CONVERTED_CLASSPATH, TEST_TEST_RESULTS_DIR, TEST_TEST_REPORT_DIR,
                     test.getIncludes(), test.getExcludes(), test.getOptions(), getProject().getAnt());
-            will(new AntPropertyAction(AntJunit.FAILURES_OR_ERRORS_PROPERTY, "somevalue"));
+            will(new AntPropertyAction("org.gradle.api.tasks.testing.failuresOrErrors", "somevalue"));
         }});
         test.execute();
     }
@@ -198,6 +208,13 @@
                     GUtil.addLists(WrapUtil.toList(TEST_TEST_CLASSES_DIR), TEST_UNMANAGED_CLASSPATH, TEST_DEPENDENCY_MANAGER_CLASSPATH));
             will(returnValue(TEST_CONVERTED_CLASSPATH));
         }});
+
+//        context.checking(new Expectations() {{
+//            one(testPolicyMock).init(getProject(), test);
+//        }});
+//        test.initTestPolicy(testPolicyMock);
+        test.setAntTestTask(antJunitMock);
+        test.setOptions(new JunitOptions());
     }
 
     @org.junit.Test public void testIncludes() {
@@ -235,6 +252,7 @@
         String propertyValue;
 
         public AntPropertyAction(String propertyKey, String propertyValue) {
+            if ( propertyKey == null ) throw new IllegalArgumentException(" propertyKey == null! ");
             this.propertyKey = propertyKey;
             this.propertyValue = propertyValue;
         }

=== modified file 'src/test/groovy/org/gradle/integtests/ProjectLoadingIntegrationTest.java'
--- src/test/groovy/org/gradle/integtests/ProjectLoadingIntegrationTest.java	2008-10-10 19:36:41 +0000
+++ src/test/groovy/org/gradle/integtests/ProjectLoadingIntegrationTest.java	2008-10-30 22:56:48 +0000
@@ -15,10 +15,8 @@
  */
 package org.gradle.integtests;
 
-import static org.apache.commons.io.FileUtils.*;
 import static org.junit.Assert.*;
 import org.junit.Test;
-import org.junit.Ignore;
 
 import java.io.File;
 import java.io.IOException;
@@ -26,7 +24,7 @@
 public class ProjectLoadingIntegrationTest extends AbstractIntegrationTest {
     @Test
     public void handlesSimilarlyNamedBuildFilesInSameDirectory() {
-        File buildFile1 = getTestBuildFile("similarly-named build.gradle");
+        File buildFile1 = getTestBuildFile("similarly-named-build.gradle");
         File buildFile2 = getTestBuildFile("similarly_named_build_gradle");
         assertEquals(buildFile1.getParentFile(), buildFile2.getParentFile());
 

# Begin bundle
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
