# Bazaar merge directive format 2 (Bazaar 0.90)
# revision_id: teyckmans@gmail.com-20081101190830-3hcbvtecsilv858p
# target_branch: http://bazaar.launchpad.net/%7Erussel/gradle/testng/
# testament_sha1: de892ee934df99b0015726b9345170c8f5406f55
# timestamp: 2008-11-01 20:10:10 +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:08:30 +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.javaConfigure();
         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.javaConfigure();
         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", "true"));
         }});
         test.execute();
     }
 
-    @org.junit.Test public void testExecuteWithTestFailuresAndContinueWithFailures() {
+    @org.junit.Test public void testJavaExecuteWithTestFailuresAndContinueWithFailures() {
         setUpMocks(test);
         setExistingDirsFilter();
+        test.javaConfigure();
         test.setStopAtFailuresOrErrors(false);
         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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
