ant-notifications mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From anto...@apache.org
Subject svn commit: r1452674 - in /ant/core/trunk: ./ lib/ lib/optional/ src/etc/testcases/taskdefs/optional/ src/main/org/apache/tools/ant/taskdefs/optional/junit/ src/tests/antunit/taskdefs/optional/junit/ src/tests/junit/org/apache/tools/ant/taskdefs/option...
Date Tue, 05 Mar 2013 05:42:52 GMT
Author: antoine
Date: Tue Mar  5 05:42:51 2013
New Revision: 1452674

URL: http://svn.apache.org/r1452674
Log:
JUnit4 tests marked @Ignore do not appear in XML output. PR 43969

Added:
    ant/core/trunk/lib/optional/junit-4.11.jar   (with props)
    ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/CustomJUnit4TestAdapterCache.java   (with props)
    ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/IgnoredTestListener.java   (with props)
    ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/IgnoredTestResult.java   (with props)
    ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/TestIgnored.java   (with props)
    ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/TestListenerWrapper.java   (with props)
    ant/core/trunk/src/tests/junit/org/example/junit/Junit4Skippable.java   (with props)
Removed:
    ant/core/trunk/lib/optional/junit-4.8.1.jar
Modified:
    ant/core/trunk/CONTRIBUTORS
    ant/core/trunk/WHATSNEW
    ant/core/trunk/contributors.xml
    ant/core/trunk/lib/libraries.properties
    ant/core/trunk/release.sh
    ant/core/trunk/src/etc/testcases/taskdefs/optional/junit.xml
    ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/BriefJUnitResultFormatter.java
    ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnit4TestMethodAdapter.java
    ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTask.java
    ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTest.java
    ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTestRunner.java
    ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/PlainJUnitResultFormatter.java
    ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/SummaryJUnitResultFormatter.java
    ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/XMLConstants.java
    ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/XMLJUnitResultFormatter.java
    ant/core/trunk/src/tests/antunit/taskdefs/optional/junit/junit-test.xml
    ant/core/trunk/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/JUnitTaskTest.java

Modified: ant/core/trunk/CONTRIBUTORS
URL: http://svn.apache.org/viewvc/ant/core/trunk/CONTRIBUTORS?rev=1452674&r1=1452673&r2=1452674&view=diff
==============================================================================
--- ant/core/trunk/CONTRIBUTORS (original)
+++ ant/core/trunk/CONTRIBUTORS Tue Mar  5 05:42:51 2013
@@ -234,6 +234,7 @@ Matthew Inger
 Matthew Kuperus Heun
 Matthew Watson
 Michael Bayne
+Michael Clarke
 Michael Davey
 Michael J. Sikorsky
 Michael McCallum

Modified: ant/core/trunk/WHATSNEW
URL: http://svn.apache.org/viewvc/ant/core/trunk/WHATSNEW?rev=1452674&r1=1452673&r2=1452674&view=diff
==============================================================================
--- ant/core/trunk/WHATSNEW (original)
+++ ant/core/trunk/WHATSNEW Tue Mar  5 05:42:51 2013
@@ -87,6 +87,9 @@ Fixed bugs:
    set to ANSI_X3.4-1968.
    Bugzilla Report 54606
 
+ * JUnit4 tests marked @Ignore do not appear in XML output
+   Bugzilla Report 43969
+
 Other changes:
 --------------
 

Modified: ant/core/trunk/contributors.xml
URL: http://svn.apache.org/viewvc/ant/core/trunk/contributors.xml?rev=1452674&r1=1452673&r2=1452674&view=diff
==============================================================================
--- ant/core/trunk/contributors.xml (original)
+++ ant/core/trunk/contributors.xml Tue Mar  5 05:42:51 2013
@@ -959,6 +959,10 @@
   </name>
   <name>
     <first>Michael</first>
+    <last>Clarke</last>
+  </name>
+  <name>
+    <first>Michael</first>
     <last>Davey</last>
   </name>
   <name>

Modified: ant/core/trunk/lib/libraries.properties
URL: http://svn.apache.org/viewvc/ant/core/trunk/lib/libraries.properties?rev=1452674&r1=1452673&r2=1452674&view=diff
==============================================================================
--- ant/core/trunk/lib/libraries.properties (original)
+++ ant/core/trunk/lib/libraries.properties Tue Mar  5 05:42:51 2013
@@ -45,7 +45,7 @@ jasper-compiler.version=4.1.36
 jasper-runtime.version=${jasper-compiler.version}
 jdepend.version=2.9.1
 jruby.version=0.9.8
-junit.version=4.8.1
+junit.version=4.11
 jsch.version=0.1.42
 jython.version=2.1
 #log4j 1.2.15 requires JMS and a few other Sun jars that are not in the m2 repo

Added: ant/core/trunk/lib/optional/junit-4.11.jar
URL: http://svn.apache.org/viewvc/ant/core/trunk/lib/optional/junit-4.11.jar?rev=1452674&view=auto
==============================================================================
Binary file - no diff available.

Propchange: ant/core/trunk/lib/optional/junit-4.11.jar
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Modified: ant/core/trunk/release.sh
URL: http://svn.apache.org/viewvc/ant/core/trunk/release.sh?rev=1452674&r1=1452673&r2=1452674&view=diff
==============================================================================
--- ant/core/trunk/release.sh (original)
+++ ant/core/trunk/release.sh Tue Mar  5 05:42:51 2013
@@ -17,7 +17,7 @@
 # this is a first attempt to document the build of the distribution
 # paths are hard-coded and obviously this is for a Cygwin/Windows combo
 #######################################################################
-rm -rf bootstrap build dist distribution
+rm -rf bootstrap build dist distribution java-repository
 unset ANT_HOME
 # OS specific support.  $var _must_ be set to either true or false.
 cygwin=false;

Modified: ant/core/trunk/src/etc/testcases/taskdefs/optional/junit.xml
URL: http://svn.apache.org/viewvc/ant/core/trunk/src/etc/testcases/taskdefs/optional/junit.xml?rev=1452674&r1=1452673&r2=1452674&view=diff
==============================================================================
--- ant/core/trunk/src/etc/testcases/taskdefs/optional/junit.xml (original)
+++ ant/core/trunk/src/etc/testcases/taskdefs/optional/junit.xml Tue Mar  5 05:42:51 2013
@@ -276,4 +276,49 @@
     </junit>
   </target>
 
+  <!-- Junit4 Ignore and Assume for skipping tests -->
+  <target name="testSkippableTests">
+    <mkdir dir="out"/>
+    <junit fork="true">
+            <classpath refid="test"/>
+            <formatter type="xml"/>
+            <classpath refid="test"/>
+            <batchtest todir="out">
+                <fileset dir="../../../../tests/junit">
+                    <include
+                            name="org/example/junit/Junit4Skippable.java"/>
+                    <!-- tests remove out-dir on tearDown -->
+                </fileset>
+            </batchtest>
+    </junit>
+  </target>
+
+  <target name="testTestMethods" >
+    <echo file="${tmp.dir}/T1.java">public class T1 extends
+      junit.framework.TestCase {
+      public void testOK() {}
+      public void testBad() {throw new RuntimeException("failed");}
+      }</echo>
+    <echo file="${tmp.dir}/T2.java">
+      import org.junit.Test;
+      public class T2 {
+      @Test
+      public void ok() {}
+      @Test
+      public void bad() {
+      throw new RuntimeException("failed");}
+      }</echo>
+    <javac srcdir="${tmp.dir}" destdir="${tmp.dir}" includes="T1.java,T2.java" source="5">
+
+    </javac>
+    <junit fork="false" printsummary="true" haltonerror="true">
+      <classpath>
+        <pathelement location="${tmp.dir}" />
+        <path refid="test" />
+      </classpath>
+      <test name="T1" methods="testOK" />
+      <test name="T2" methods="ok" />
+    </junit>
+  </target>
+
 </project>

Modified: ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/BriefJUnitResultFormatter.java
URL: http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/BriefJUnitResultFormatter.java?rev=1452674&r1=1452673&r2=1452674&view=diff
==============================================================================
--- ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/BriefJUnitResultFormatter.java (original)
+++ ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/BriefJUnitResultFormatter.java Tue Mar  5 05:42:51 2013
@@ -25,11 +25,13 @@ import java.io.StringWriter;
 import java.text.NumberFormat;
 
 import junit.framework.AssertionFailedError;
+import junit.framework.JUnit4TestCaseFacade;
 import junit.framework.Test;
 
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.util.FileUtils;
 import org.apache.tools.ant.util.StringUtils;
+import org.junit.Ignore;
 
 /**
  * Prints plain text output of the test to a specified Writer.
@@ -38,7 +40,7 @@ import org.apache.tools.ant.util.StringU
  * @see FormatterElement
  * @see PlainJUnitResultFormatter
  */
-public class BriefJUnitResultFormatter implements JUnitResultFormatter {
+public class BriefJUnitResultFormatter implements JUnitResultFormatter, IgnoredTestListener {
 
     private static final double ONE_SECOND = 1000.0;
 
@@ -141,6 +143,8 @@ public class BriefJUnitResultFormatter i
         sb.append(suite.failureCount());
         sb.append(", Errors: ");
         sb.append(suite.errorCount());
+        sb.append(", Skipped: ");
+        sb.append(suite.skipCount());
         sb.append(", Time elapsed: ");
         sb.append(numberFormat.format(suite.getRunTime() / ONE_SECOND));
         sb.append(" sec");
@@ -267,4 +271,42 @@ public class BriefJUnitResultFormatter i
             throw new BuildException(ex);
         }
     }
+
+
+    @Override
+    public void testIgnored(Test test) {
+        String message = null;
+        if (test instanceof JUnit4TestCaseFacade) {
+            JUnit4TestCaseFacade facade = (JUnit4TestCaseFacade) test;
+            Ignore annotation = facade.getDescription().getAnnotation(Ignore.class);
+            if (annotation != null && annotation.value() != null && !annotation.value().isEmpty()) {
+                message = annotation.value();
+            }
+        }
+        formatSkip(test, message);
+    }
+
+
+    public void formatSkip(Test test, String message) {
+        if (test != null) {
+            endTest(test);
+        }
+
+        try {
+            resultWriter.write(formatTest(test) + "SKIPPED");
+            if (message != null) {
+                resultWriter.write(": ");
+                resultWriter.write(message);
+            }
+            resultWriter.newLine();
+        } catch (IOException ex) {
+            throw new BuildException(ex);
+        }
+
+    }
+
+    @Override
+    public void testAssumptionFailure(Test test, Throwable cause) {
+        formatSkip(test, cause.getMessage());
+    }
 }

Added: ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/CustomJUnit4TestAdapterCache.java
URL: http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/CustomJUnit4TestAdapterCache.java?rev=1452674&view=auto
==============================================================================
--- ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/CustomJUnit4TestAdapterCache.java (added)
+++ ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/CustomJUnit4TestAdapterCache.java Tue Mar  5 05:42:51 2013
@@ -0,0 +1,89 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You 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.apache.tools.ant.taskdefs.optional.junit;
+
+import junit.framework.JUnit4TestAdapter;
+import junit.framework.JUnit4TestAdapterCache;
+import junit.framework.TestResult;
+import org.junit.runner.Description;
+import org.junit.runner.notification.Failure;
+import org.junit.runner.notification.RunListener;
+import org.junit.runner.notification.RunNotifier;
+
+/**
+ * Provides a custom implementation of the notifier for a Junit4TestAdapter
+ * so that skipped and ignored tests can be reported to the existing
+ * <tt>TestListener</tt>s.
+ *
+ */
+public class CustomJUnit4TestAdapterCache extends JUnit4TestAdapterCache {
+
+    private static final CustomJUnit4TestAdapterCache INSTANCE = new CustomJUnit4TestAdapterCache();
+
+    public static CustomJUnit4TestAdapterCache getInstance() {
+        return INSTANCE;
+    }
+
+    private CustomJUnit4TestAdapterCache() {
+        super();
+    }
+
+    public RunNotifier getNotifier(final TestResult result, final JUnit4TestAdapter adapter) {
+        return getNotifier(result);
+    }
+
+    public RunNotifier getNotifier(final TestResult result) {
+
+        final IgnoredTestResult resultWrapper = (IgnoredTestResult) result;
+
+        RunNotifier notifier = new RunNotifier();
+        notifier.addListener(new RunListener() {
+            @Override
+            public void testFailure(Failure failure) throws Exception {
+                result.addError(asTest(failure.getDescription()), failure.getException());
+            }
+
+            @Override
+            public void testFinished(Description description) throws Exception {
+                result.endTest(asTest(description));
+            }
+
+            @Override
+            public void testStarted(Description description) throws Exception {
+                result.startTest(asTest(description));
+            }
+
+            @Override
+            public void testIgnored(Description description) throws Exception {
+                if (resultWrapper != null) {
+                    resultWrapper.testIgnored(asTest(description));
+                }
+            }
+
+            @Override
+            public void testAssumptionFailure(Failure failure) {
+                if (resultWrapper != null) {
+                    resultWrapper.testAssumptionFailure(asTest(failure.getDescription()), failure.getException());
+                }
+            }
+        });
+
+        return notifier;
+    }
+}

Propchange: ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/CustomJUnit4TestAdapterCache.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/IgnoredTestListener.java
URL: http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/IgnoredTestListener.java?rev=1452674&view=auto
==============================================================================
--- ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/IgnoredTestListener.java (added)
+++ ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/IgnoredTestListener.java Tue Mar  5 05:42:51 2013
@@ -0,0 +1,53 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You 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.apache.tools.ant.taskdefs.optional.junit;
+
+import junit.framework.Test;
+import junit.framework.TestListener;
+import org.junit.runner.notification.Failure;
+
+/**
+ * Provides the functionality for TestListeners to be able to be notified of
+ * the necessary Junit4 events for test being ignored (@Ignore annotation)
+ * or skipped (Assume failures). Tests written in Junit4 will report against
+ * the methods in this interface alongside the methods in the existing TestListener
+ */
+public interface IgnoredTestListener extends TestListener {
+
+    /**
+     * Reports when a test has been marked with the @Ignore annotation. The parameter
+     * should normally be typed to Junit's {@link junit.framework.JUnit4TestCaseFacade}
+     * so implementing classes should be able to get the details of the ignore by casting
+     * the argument and retrieving the descriptor from the test.
+     * @param test
+     */
+    void testIgnored(Test test);
+
+    /**
+     * Receive a report that a test has failed an assumption. Within JUnit4
+     * this is normally treated as a test being skipped, although how any
+     * listener handles this is up to that specific listener.<br />
+     * <b>Note:</b> Tests that throw assumption failures will still report
+     * the endTest method, which may differ from how the addError and addFailure
+     * methods work, it's up for any implementing classes to handle this.
+     * @param test the details of the test and failure that have triggered this report.
+     * @param exception the AssumptionViolatedException thrown from the current assumption failure.
+     */
+    void testAssumptionFailure(Test test, Throwable exception);
+}

Propchange: ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/IgnoredTestListener.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/IgnoredTestResult.java
URL: http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/IgnoredTestResult.java?rev=1452674&view=auto
==============================================================================
--- ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/IgnoredTestResult.java (added)
+++ ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/IgnoredTestResult.java Tue Mar  5 05:42:51 2013
@@ -0,0 +1,99 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You 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.apache.tools.ant.taskdefs.optional.junit;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import junit.framework.Test;
+import junit.framework.TestListener;
+import junit.framework.TestResult;
+
+/**
+ * Records ignored and skipped tests reported as part of the execution of
+ * JUnit 4 tests.
+ *
+ */
+public class IgnoredTestResult extends TestResult {
+
+
+    private List<IgnoredTestListener> listeners = new ArrayList<IgnoredTestListener>();
+    private List<TestIgnored> ignored = new ArrayList<TestIgnored>();
+    private List<TestIgnored> skipped = new ArrayList<TestIgnored>();
+
+    public IgnoredTestResult() {
+        super();
+    }
+
+
+    public synchronized void addListener(TestListener listener) {
+        if (listener instanceof IgnoredTestListener) {
+            listeners.add((IgnoredTestListener)listener);
+        }
+        super.addListener(listener);
+    }
+
+    public synchronized  void removeListener(TestListener listener) {
+        if (listener instanceof IgnoredTestListener) {
+            listeners.remove(listener);
+        }
+        super.removeListener(listener);
+    }
+
+    /**
+     * Record a test as having been ignored, normally by the @Ignore annotation.
+     * @param test the test that was ignored.
+     * @throws Exception is the listener thrown an exception on handling the notification.
+     */
+    public synchronized void testIgnored(Test test) throws Exception {
+        ignored.add(new TestIgnored(test));
+        for (IgnoredTestListener listener : listeners) {
+            listener.testIgnored(test);
+        }
+    }
+
+    /**
+     * Report how many tests were ignored.
+     * @return the number of tests reported as ignored during the current execution.
+     */
+    public long ignoredCount() {
+        return ignored.size();
+    }
+
+    /**
+     * Records a test as having an assumption failure so JUnit will no longer be executing it.
+     * Under normal circumstances this would be counted as a skipped test.
+     * @param test the test to record
+     * @param cause the details of the test and assumption failure.
+     */
+    public void testAssumptionFailure(Test test, Throwable cause) {
+    	skipped.add(new TestIgnored(test));
+        for (IgnoredTestListener listener : listeners) {
+            listener.testAssumptionFailure(test, cause);
+        }
+    }
+
+    /**
+     * Report how many tests has assumption failures.
+     * @return the number of tests that reported assumption failures during the current execution.
+     */
+    public long skippedCount() {
+        return skipped.size();
+    }
+}

Propchange: ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/IgnoredTestResult.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnit4TestMethodAdapter.java
URL: http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnit4TestMethodAdapter.java?rev=1452674&r1=1452673&r2=1452674&view=diff
==============================================================================
--- ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnit4TestMethodAdapter.java (original)
+++ ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnit4TestMethodAdapter.java Tue Mar  5 05:42:51 2013
@@ -20,20 +20,16 @@ package org.apache.tools.ant.taskdefs.op
 
 import java.util.Iterator;
 import java.util.List;
-import junit.framework.JUnit4TestAdapterCache;
 import junit.framework.Test;
 import junit.framework.TestResult;
 import org.junit.runner.Description;
 import org.junit.runner.Request;
 import org.junit.runner.Runner;
 import org.junit.runner.manipulation.Filter;
-import org.junit.runner.notification.Failure;
-import org.junit.runner.notification.RunListener;
-import org.junit.runner.notification.RunNotifier;
 
 /**
  * Adapter between JUnit 3.8.x API and JUnit 4.x API for execution of tests
- * and listening of events (test start, test finish, test failure).
+ * and listening of events (test start, test finish, test failure, test skipped).
  * The constructor is passed a JUnit 4 test class and a list of name of methods
  * in it that should be executed. Method {@link #run run(TestResult)} executes
  * the given JUnit-4-style test methods and notifies the given {@code TestResult}
@@ -46,7 +42,7 @@ public class JUnit4TestMethodAdapter imp
     private final Class testClass;
     private final String[] methodNames;
     private final Runner runner;
-    private final Cache cache;
+    private final CustomJUnit4TestAdapterCache cache;
 
     /**
      * Creates a new adapter for the given class and a method within the class.
@@ -75,7 +71,7 @@ public class JUnit4TestMethodAdapter imp
         }
         this.testClass = testClass;
         this.methodNames = (String[]) methodNames.clone();
-        this.cache = Cache.instance;
+        this.cache = CustomJUnit4TestAdapterCache.getInstance();
 
         // Warning: If 'testClass' is an old-style (pre-JUnit-4) class,
         // then all its test methods will be executed by the returned runner!
@@ -104,7 +100,7 @@ public class JUnit4TestMethodAdapter imp
     public Class getTestClass() {
         return testClass;
     }
-    
+
     public void run(final TestResult result) {
         runner.run(cache.getNotifier(result));
     }
@@ -188,42 +184,5 @@ public class JUnit4TestMethodAdapter imp
 
     }
 
-    /**
-     * Effectively a copy of {@code JUnit4TestAdapterCache}, except that its
-     * method {@code getNotifier()} does not require an argument
-     * of type {@code JUnit4TestAdapter}.
-     */
-    private static final class Cache extends JUnit4TestAdapterCache {
-        
-        private static final long serialVersionUID = 8454901854293461610L;
-
-	private static final Cache instance = new Cache();
-
-	public static JUnit4TestAdapterCache getDefault() {
-            return instance;
-	}
-	
-	public RunNotifier getNotifier(final TestResult result) {
-            RunNotifier notifier = new RunNotifier();
-            notifier.addListener(new RunListener() {
-                    public void testFailure(Failure failure) throws Exception {
-                        result.addError(asTest(failure.getDescription()),
-                                        failure.getException());
-                    }
-
-                    public void testFinished(Description description)
-                                    throws Exception {
-                        result.endTest(asTest(description));
-                    }
-
-                    public void testStarted(Description description)
-                                    throws Exception {
-                        result.startTest(asTest(description));
-                    }
-            });
-            return notifier;
-	}
-
-    }
 
 }

Modified: ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTask.java
URL: http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTask.java?rev=1452674&r1=1452673&r2=1452674&view=diff
==============================================================================
--- ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTask.java (original)
+++ ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTask.java Tue Mar  5 05:42:51 2013
@@ -1645,7 +1645,7 @@ public class JUnitTask extends Task {
                 classLoader.setThreadContextLoader();
             }
 
-            test.setCounts(1, 0, 1);
+            test.setCounts(1, 0, 1, 0);
             test.setProperties(getProject().getProperties());
             for (int i = 0; i < feArray.length; i++) {
                 FormatterElement fe = feArray[i];

Modified: ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTest.java
URL: http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTest.java?rev=1452674&r1=1452673&r2=1452674&view=diff
==============================================================================
--- ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTest.java (original)
+++ ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTest.java Tue Mar  5 05:42:51 2013
@@ -62,6 +62,11 @@ public class JUnitTest extends BaseTest 
     // part of the result. So we'd better derive a new class from TestResult
     // and deal with it. (SB)
     private long runs, failures, errors;
+    /**
+    @since Ant 1.9.0
+    */
+    private long skips;
+
     private long runTime;
 
     // Snapshot of the system properties
@@ -352,16 +357,31 @@ public class JUnitTest extends BaseTest 
     }
 
     /**
-     * Set the number of runs, failures and errors.
+     * Set the number of runs, failures, errors, and skipped tests.
      * @param runs     the number of runs.
      * @param failures the number of failures.
      * @param errors   the number of errors.
+     * Kept for backward compatibility with Ant 1.8.4
      */
     public void setCounts(long runs, long failures, long errors) {
         this.runs = runs;
         this.failures = failures;
         this.errors = errors;
     }
+    /**
+     * Set the number of runs, failures, errors, and skipped tests.
+     * @param runs     the number of runs.
+     * @param failures the number of failures.
+     * @param errors   the number of errors.
+     * @param skips   the number of skipped tests.
+     * @since Ant 1.9.0
+     */
+    public void setCounts(long runs, long failures, long errors, long skips) {
+        this.runs = runs;
+        this.failures = failures;
+        this.errors = errors;
+        this.skips = skips;
+    }
 
     /**
      * Set the runtime.
@@ -396,6 +416,14 @@ public class JUnitTest extends BaseTest 
     }
 
     /**
+     * Get the number of skipped tests.
+     * @return the number of skipped tests.
+     */
+    public long skipCount() {
+        return skips;
+    }
+
+    /**
      * Get the run time.
      * @return the run time in milliseconds.
      */

Modified: ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTestRunner.java
URL: http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTestRunner.java?rev=1452674&r1=1452673&r2=1452674&view=diff
==============================================================================
--- ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTestRunner.java (original)
+++ ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTestRunner.java Tue Mar  5 05:42:51 2013
@@ -36,6 +36,7 @@ import java.util.Properties;
 import java.util.StringTokenizer;
 import java.util.Vector;
 import junit.framework.AssertionFailedError;
+import junit.framework.JUnit4TestAdapterCache;
 import junit.framework.Test;
 import junit.framework.TestFailure;
 import junit.framework.TestListener;
@@ -76,7 +77,7 @@ public class JUnitTestRunner implements 
     /**
      * Collects TestResults.
      */
-    private TestResult res;
+    private IgnoredTestResult res;
 
     /**
      * Do we filter junit.*.* stack frames out of failure and error exceptions.
@@ -289,6 +290,7 @@ public class JUnitTestRunner implements 
                            boolean filtertrace, boolean haltOnFailure,
                            boolean showOutput, boolean logTestListenerEvents,
                            ClassLoader loader) {
+        super();
         JUnitTestRunner.filtertrace = filtertrace; // XXX clumsy, should use instance field somehow
         this.junitTest = test;
         this.haltOnError = haltOnError;
@@ -350,7 +352,7 @@ public class JUnitTestRunner implements 
      * Run the test.
      */
     public void run() {
-        res = new TestResult();
+        res = new IgnoredTestResult();
         res.addListener(wrapListener(this));
         final int size = formatters.size();
         for (int i = 0; i < size; i++) {
@@ -468,8 +470,8 @@ public class JUnitTestRunner implements 
                             formalParams = new Class[] {Class.class, String[].class};
                             actualParams = new Object[] {testClass, methods};
                         } else {
-                            formalParams = new Class[] {Class.class};
-                            actualParams = new Object[] {testClass};
+                            formalParams = new Class[] {Class.class, JUnit4TestAdapterCache.class};
+                            actualParams = new Object[] {testClass, CustomJUnit4TestAdapterCache.getInstance()};
                         }
                         suite =
                             (Test) junit4TestAdapterClass
@@ -512,7 +514,7 @@ public class JUnitTestRunner implements 
                     ((TestListener) formatters.elementAt(i))
                         .addError(null, exception);
                 }
-                junitTest.setCounts(1, 0, 1);
+                junitTest.setCounts(1, 0, 1, 0);
                 junitTest.setRunTime(0);
             } else {
                 try {
@@ -522,10 +524,10 @@ public class JUnitTestRunner implements 
                     if (junit4 ||
                         suite.getClass().getName().equals(JUNIT_4_TEST_ADAPTER)) {
                         int[] cnts = findJUnit4FailureErrorCount(res);
-                        junitTest.setCounts(res.runCount(), cnts[0], cnts[1]);
+                        junitTest.setCounts(res.runCount() + res.ignoredCount(), cnts[0], cnts[1], res.ignoredCount() + res.skippedCount());
                     } else {
-                        junitTest.setCounts(res.runCount(), res.failureCount(),
-                                res.errorCount());
+                        junitTest.setCounts(res.runCount() + res.ignoredCount(), res.failureCount(),
+                                res.errorCount(), res.ignoredCount() + res.skippedCount());
                     }
                     junitTest.setRunTime(System.currentTimeMillis() - start);
                 }
@@ -1101,8 +1103,8 @@ public class JUnitTestRunner implements 
      *
      * @since Ant 1.7
      */
-    private TestListener wrapListener(final TestListener testListener) {
-        return new TestListener() {
+    private TestListenerWrapper wrapListener(final TestListener testListener) {
+        return new TestListenerWrapper(testListener) {
             public void addError(Test test, Throwable t) {
                 if (junit4 && t instanceof AssertionFailedError) {
                     // JUnit 4 does not distinguish between errors and failures

Modified: ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/PlainJUnitResultFormatter.java
URL: http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/PlainJUnitResultFormatter.java?rev=1452674&r1=1452673&r2=1452674&view=diff
==============================================================================
--- ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/PlainJUnitResultFormatter.java (original)
+++ ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/PlainJUnitResultFormatter.java Tue Mar  5 05:42:51 2013
@@ -26,11 +26,14 @@ import java.text.NumberFormat;
 import java.util.Hashtable;
 
 import junit.framework.AssertionFailedError;
+import junit.framework.JUnit4TestCaseFacade;
 import junit.framework.Test;
 
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.util.FileUtils;
 import org.apache.tools.ant.util.StringUtils;
+import org.junit.Ignore;
+import org.junit.runner.notification.Failure;
 
 
 /**
@@ -38,7 +41,7 @@ import org.apache.tools.ant.util.StringU
  *
  */
 
-public class PlainJUnitResultFormatter implements JUnitResultFormatter {
+public class PlainJUnitResultFormatter implements JUnitResultFormatter, IgnoredTestListener {
 
     private static final double ONE_SECOND = 1000.0;
 
@@ -123,6 +126,8 @@ public class PlainJUnitResultFormatter i
         sb.append(suite.failureCount());
         sb.append(", Errors: ");
         sb.append(suite.errorCount());
+        sb.append(", Skipped: ");
+        sb.append(suite.skipCount());
         sb.append(", Time elapsed: ");
         sb.append(nf.format(suite.getRunTime() / ONE_SECOND));
         sb.append(" sec");
@@ -258,4 +263,40 @@ public class PlainJUnitResultFormatter i
         }
     }
 
+    @Override
+    public void testIgnored(Test test) {
+        String message = null;
+        if (test instanceof JUnit4TestCaseFacade) {
+            JUnit4TestCaseFacade facade = (JUnit4TestCaseFacade) test;
+            Ignore annotation = facade.getDescription().getAnnotation(Ignore.class);
+            if (annotation != null && annotation.value() != null && !annotation.value().isEmpty()) {
+                message = annotation.value();
+            }
+        }
+        formatSkip(test, message);
+    }
+
+
+    public void formatSkip(Test test, String message) {
+        if (test != null) {
+            endTest(test);
+        }
+
+        try {
+            wri.write("\tSKIPPED");
+            if (message != null) {
+                wri.write(": ");
+                wri.write(message);
+            }
+            wri.newLine();
+        } catch (IOException ex) {
+            throw new BuildException(ex);
+        }
+
+    }
+
+    @Override
+    public void testAssumptionFailure(Test test, Throwable throwable) {
+        formatSkip(test, throwable.getMessage());
+    }
 } // PlainJUnitResultFormatter

Modified: ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/SummaryJUnitResultFormatter.java
URL: http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/SummaryJUnitResultFormatter.java?rev=1452674&r1=1452673&r2=1452674&view=diff
==============================================================================
--- ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/SummaryJUnitResultFormatter.java (original)
+++ ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/SummaryJUnitResultFormatter.java Tue Mar  5 05:42:51 2013
@@ -144,6 +144,8 @@ public class SummaryJUnitResultFormatter
         sb.append(suite.failureCount());
         sb.append(", Errors: ");
         sb.append(suite.errorCount());
+        sb.append(", Skipped: ");
+        sb.append(suite.skipCount());
         sb.append(", Time elapsed: ");
         sb.append(nf.format(suite.getRunTime() / ONE_SECOND));
         sb.append(" sec");

Added: ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/TestIgnored.java
URL: http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/TestIgnored.java?rev=1452674&view=auto
==============================================================================
--- ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/TestIgnored.java (added)
+++ ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/TestIgnored.java Tue Mar  5 05:42:51 2013
@@ -0,0 +1,35 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You 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.apache.tools.ant.taskdefs.optional.junit;
+
+import junit.framework.Test;
+
+public class TestIgnored {
+
+    private Test test;
+
+    public TestIgnored(Test test) {
+        this.test = test;
+    }
+
+    public Test getTest() {
+        return test;
+    }
+
+}

Propchange: ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/TestIgnored.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/TestListenerWrapper.java
URL: http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/TestListenerWrapper.java?rev=1452674&view=auto
==============================================================================
--- ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/TestListenerWrapper.java (added)
+++ ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/TestListenerWrapper.java Tue Mar  5 05:42:51 2013
@@ -0,0 +1,74 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You 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.apache.tools.ant.taskdefs.optional.junit;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.JUnit4TestAdapterCache;
+import junit.framework.Test;
+import junit.framework.TestListener;
+
+import org.junit.internal.AssumptionViolatedException;
+import org.junit.runner.Description;
+import org.junit.runner.notification.Failure;
+
+public class TestListenerWrapper implements TestListener, IgnoredTestListener {
+
+    private TestListener wrapped;
+
+    public TestListenerWrapper(TestListener listener) {
+        super();
+        wrapped = listener;
+    }
+
+    @Override
+    public void addError(Test test, Throwable throwable) {
+        wrapped.addError(test, throwable);
+    }
+
+    @Override
+    public void addFailure(Test test, AssertionFailedError assertionFailedError) {
+        wrapped.addFailure(test, assertionFailedError);
+    }
+
+    @Override
+    public void endTest(Test test) {
+        wrapped.endTest(test);
+    }
+
+    @Override
+    public void startTest(Test test) {
+        wrapped.startTest(test);
+    }
+
+    @Override
+    public void testIgnored(Test test) {
+        if (wrapped instanceof IgnoredTestListener) {
+            ((IgnoredTestListener)wrapped).testIgnored(test);
+        }
+    }
+
+    @Override
+    public void testAssumptionFailure(Test test, Throwable throwable) {
+        if (wrapped instanceof IgnoredTestListener) {
+            ((IgnoredTestListener)wrapped).testAssumptionFailure(test, throwable);
+        }
+    }
+
+
+}

Propchange: ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/TestListenerWrapper.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/XMLConstants.java
URL: http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/XMLConstants.java?rev=1452674&r1=1452673&r2=1452674&view=diff
==============================================================================
--- ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/XMLConstants.java (original)
+++ ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/XMLConstants.java Tue Mar  5 05:42:51 2013
@@ -106,6 +106,8 @@ public interface XMLConstants {
     /** tests attribute for testsuite elements */
     String ATTR_TESTS = "tests";
 
+    String ATTR_SKIPPED = "skipped";
+
     /** type attribute for failure and error elements */
     String ATTR_TYPE = "type";
 

Modified: ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/XMLJUnitResultFormatter.java
URL: http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/XMLJUnitResultFormatter.java?rev=1452674&r1=1452673&r2=1452674&view=diff
==============================================================================
--- ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/XMLJUnitResultFormatter.java (original)
+++ ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/XMLJUnitResultFormatter.java Tue Mar  5 05:42:51 2013
@@ -23,20 +23,26 @@ import java.io.IOException;
 import java.io.OutputStream;
 import java.io.OutputStreamWriter;
 import java.io.Writer;
+import java.lang.reflect.Method;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.Date;
 import java.util.Enumeration;
 import java.util.Hashtable;
 import java.util.Properties;
-import java.util.Date;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
+
 import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
+
 import junit.framework.AssertionFailedError;
+import junit.framework.JUnit4TestCaseFacade;
 import junit.framework.Test;
+
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.util.DOMElementWriter;
 import org.apache.tools.ant.util.DateUtils;
 import org.apache.tools.ant.util.FileUtils;
+import org.junit.Ignore;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.Text;
@@ -48,7 +54,7 @@ import org.w3c.dom.Text;
  * @see FormatterElement
  */
 
-public class XMLJUnitResultFormatter implements JUnitResultFormatter, XMLConstants {
+public class XMLJUnitResultFormatter implements JUnitResultFormatter, XMLConstants, IgnoredTestListener {
 
     private static final double ONE_SECOND = 1000.0;
 
@@ -73,16 +79,29 @@ public class XMLJUnitResultFormatter imp
     private Element rootElement;
     /**
      * Element for the current test.
+     * 
+     * The keying of this map is a bit of a hack: tests are keyed by caseName(className) since
+     * the Test we get for Test-start isn't the same as the Test we get during test-assumption-fail,
+     * so we can't easily match Test objects without manually iterating over all keys and checking
+     * individual fields.
      */
-    private Hashtable testElements = new Hashtable();
+    private Hashtable<String, Element> testElements = new Hashtable<String, Element>();
     /**
      * tests that failed.
      */
     private Hashtable failedTests = new Hashtable();
     /**
+     * Tests that were skipped.
+     */
+    private Hashtable<String, Test> skippedTests = new Hashtable<String, Test>();
+    /**
+     * Tests that were ignored. See the note above about the key being a bit of a hack.
+     */
+    private Hashtable<String, Test> ignoredTests = new Hashtable<String, Test>();
+    /**
      * Timing helper.
      */
-    private Hashtable testStarts = new Hashtable();
+    private Hashtable<String, Long> testStarts = new Hashtable<String, Long>();
     /**
      * Where to write the log to.
      */
@@ -161,6 +180,7 @@ public class XMLJUnitResultFormatter imp
         rootElement.setAttribute(ATTR_TESTS, "" + suite.runCount());
         rootElement.setAttribute(ATTR_FAILURES, "" + suite.failureCount());
         rootElement.setAttribute(ATTR_ERRORS, "" + suite.errorCount());
+        rootElement.setAttribute(ATTR_SKIPPED, "" + suite.skipCount());
         rootElement.setAttribute(
             ATTR_TIME, "" + (suite.getRunTime() / ONE_SECOND));
         if (out != null) {
@@ -193,9 +213,13 @@ public class XMLJUnitResultFormatter imp
      * @param t the test.
      */
     public void startTest(Test t) {
-        testStarts.put(t, new Long(System.currentTimeMillis()));
+        testStarts.put(createDescription(t), System.currentTimeMillis());
     }
 
+    private static String createDescription(Test test) throws BuildException {
+        return JUnitVersionHelper.getTestCaseName(test) + "(" + JUnitVersionHelper.getTestCaseClassName(test) + ")";
+	}
+
     /**
      * Interface TestListener.
      *
@@ -203,15 +227,16 @@ public class XMLJUnitResultFormatter imp
      * @param test the test.
      */
     public void endTest(Test test) {
+        String testDescription = createDescription(test);
+
         // Fix for bug #5637 - if a junit.extensions.TestSetup is
         // used and throws an exception during setUp then startTest
         // would never have been called
-        if (!testStarts.containsKey(test)) {
+        if (!testStarts.containsKey(testDescription)) {
             startTest(test);
         }
-
-        Element currentTest = null;
-        if (!failedTests.containsKey(test)) {
+        Element currentTest;
+        if (!failedTests.containsKey(test) && !skippedTests.containsKey(testDescription) && !ignoredTests.containsKey(testDescription)) {
             currentTest = doc.createElement(TESTCASE);
             String n = JUnitVersionHelper.getTestCaseName(test);
             currentTest.setAttribute(ATTR_NAME,
@@ -221,15 +246,14 @@ public class XMLJUnitResultFormatter imp
             currentTest.setAttribute(ATTR_CLASSNAME,
                     JUnitVersionHelper.getTestCaseClassName(test));
             rootElement.appendChild(currentTest);
-            testElements.put(test, currentTest);
+            testElements.put(createDescription(test), currentTest);
         } else {
-            currentTest = (Element) testElements.get(test);
+            currentTest = testElements.get(testDescription);
         }
 
-        Long l = (Long) testStarts.get(test);
+        Long l = testStarts.get(createDescription(test));
         currentTest.setAttribute(ATTR_TIME,
-            "" + ((System.currentTimeMillis()
-                   - l.longValue()) / ONE_SECOND));
+            "" + ((System.currentTimeMillis() - l) / ONE_SECOND));
     }
 
     /**
@@ -272,9 +296,9 @@ public class XMLJUnitResultFormatter imp
         }
 
         Element nested = doc.createElement(type);
-        Element currentTest = null;
+        Element currentTest;
         if (test != null) {
-            currentTest = (Element) testElements.get(test);
+            currentTest = testElements.get(createDescription(test));
         } else {
             currentTest = rootElement;
         }
@@ -298,4 +322,63 @@ public class XMLJUnitResultFormatter imp
         nested.appendChild(doc.createCDATASection(output));
     }
 
+    @Override
+    public void testIgnored(Test test) {
+        String message = null;
+        if (test != null && test instanceof JUnit4TestCaseFacade) {
+        	//try and get the message coded as part of the ignore
+        	/*
+        	 * org.junit.runner.Description contains a getAnnotation(Class) method... but this
+        	 * wasn't in older versions of JUnit4 so we have to try and do this by reflection
+        	 */
+        	try {
+        		Class<?> testClass = Class.forName(JUnitVersionHelper.getTestCaseClassName(test));
+        	
+                Method testMethod = testClass.getMethod(JUnitVersionHelper.getTestCaseName(test));
+                Ignore annotation = testMethod.getAnnotation(Ignore.class);
+                if (annotation != null && annotation.value() != null && !annotation.value().isEmpty()) {
+                    message = annotation.value();
+                }
+        	} catch (NoSuchMethodException e) {
+				// silently ignore - we'll report a skip with no message
+			} catch (ClassNotFoundException e) {
+				// silently ignore - we'll report a skip with no message
+			}
+        }
+        formatSkip(test, message);
+        if (test != null) {
+            ignoredTests.put(createDescription(test), test);
+        }
+    }
+
+
+    public void formatSkip(Test test, String message) {
+        if (test != null) {
+            endTest(test);
+        }
+
+        Element nested = doc.createElement("skipped");
+
+        if (message != null) {
+            nested.setAttribute("message", message);
+        }
+
+        Element currentTest;
+        if (test != null) {
+            currentTest = testElements.get(createDescription(test));
+        } else {
+            currentTest = rootElement;
+        }
+
+        currentTest.appendChild(nested);
+
+    }
+
+    @Override
+    public void testAssumptionFailure(Test test, Throwable failure) {
+        String message = failure.getMessage();
+        formatSkip(test, message);
+        skippedTests.put(createDescription(test), test);
+
+    }
 } // XMLJUnitResultFormatter

Modified: ant/core/trunk/src/tests/antunit/taskdefs/optional/junit/junit-test.xml
URL: http://svn.apache.org/viewvc/ant/core/trunk/src/tests/antunit/taskdefs/optional/junit/junit-test.xml?rev=1452674&r1=1452673&r2=1452674&view=diff
==============================================================================
--- ant/core/trunk/src/tests/antunit/taskdefs/optional/junit/junit-test.xml (original)
+++ ant/core/trunk/src/tests/antunit/taskdefs/optional/junit/junit-test.xml Tue Mar  5 05:42:51 2013
@@ -20,6 +20,7 @@
 
   <path id="junit">
     <fileset dir="../../../../../../lib/optional" includes="junit*" />
+    <fileset dir="../../../../../../lib/optional" includes="hamcrest-core*" />
   </path>
 
   <macrodef name="empty-test">

Modified: ant/core/trunk/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/JUnitTaskTest.java
URL: http://svn.apache.org/viewvc/ant/core/trunk/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/JUnitTaskTest.java?rev=1452674&r1=1452673&r2=1452674&view=diff
==============================================================================
--- ant/core/trunk/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/JUnitTaskTest.java (original)
+++ ant/core/trunk/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/JUnitTaskTest.java Tue Mar  5 05:42:51 2013
@@ -25,6 +25,14 @@ import java.io.IOException;
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.BuildFileTest;
 import org.apache.tools.ant.util.JavaEnvUtils;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathFactory;
 
 public class JUnitTaskTest extends BuildFileTest {
 
@@ -262,7 +270,7 @@ public class JUnitTaskTest extends Build
                          line);
             line = reader.readLine();
             assertNotNull(line);
-            assertTrue(line.startsWith("Tests run: 1, Failures: 0, Errors: 0, Time elapsed:"));
+            assertTrue(line.startsWith("Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed:"));
             line = reader.readLine();
             assertEquals("------------- Standard Output ---------------",
                          line);
@@ -296,4 +304,33 @@ public class JUnitTaskTest extends Build
         assertEquals(search, line);
     }
 
+    public void testJunit4Skip() throws Exception {
+        executeTarget("testSkippableTests");
+
+        DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
+        DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
+        Document doc = dBuilder.parse(getProject().getResource("out/TEST-org.example.junit.Junit4Skippable.xml").getInputStream());
+
+        assertEquals("Incorrect number of nodes created", 8, doc.getElementsByTagName("testcase").getLength());
+
+        XPathFactory factory = XPathFactory.newInstance();
+        XPath xpath = factory.newXPath();
+
+        assertEquals("Incorrect number of skipped tests in header", 4, Integer.parseInt(xpath.compile("//testsuite/@skipped").evaluate(doc)));
+        assertEquals("Incorrect number of error tests in header", 1, Integer.parseInt(xpath.compile("//testsuite/@errors").evaluate(doc)));
+        assertEquals("Incorrect number of failure tests in header", 2, Integer.parseInt(xpath.compile("//testsuite/@failures").evaluate(doc)));
+        assertEquals("Incorrect number of tests in header", 8, Integer.parseInt(xpath.compile("//testsuite/@tests").evaluate(doc)));
+
+
+        assertEquals("Incorrect ignore message on explicit ignored test", "Please don't ignore me!", xpath.compile("//testsuite/testcase[@name='explicitIgnoreTest']/skipped/@message").evaluate(doc));
+        assertEquals("No message should be set on Ignored tests with no Ignore annotation text", 0, ((Node)xpath.compile("//testsuite/testcase[@name='explicitlyIgnoreTestNoMessage']/skipped").evaluate(doc, XPathConstants.NODE)).getAttributes().getLength());
+        assertEquals("Incorrect ignore message on implicit ignored test", "This test will be ignored", xpath.compile("//testsuite/testcase[@name='implicitlyIgnoreTest']/skipped/@message").evaluate(doc));
+        assertNotNull("Implicit ignore test should have an ignore element", xpath.compile("//testsuite/testcase[@name='implicitlyIgnoreTestNoMessage']/skipped").evaluate(doc, XPathConstants.NODE));
+
+    }
+
+    public void testTestMethods() throws Exception {
+        executeTarget("testTestMethods");
+    }
+
 }
\ No newline at end of file

Added: ant/core/trunk/src/tests/junit/org/example/junit/Junit4Skippable.java
URL: http://svn.apache.org/viewvc/ant/core/trunk/src/tests/junit/org/example/junit/Junit4Skippable.java?rev=1452674&view=auto
==============================================================================
--- ant/core/trunk/src/tests/junit/org/example/junit/Junit4Skippable.java (added)
+++ ant/core/trunk/src/tests/junit/org/example/junit/Junit4Skippable.java Tue Mar  5 05:42:51 2013
@@ -0,0 +1,56 @@
+package org.example.junit;
+
+import org.junit.Assume;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+public class Junit4Skippable {
+
+    @Test
+    public void passingTest() {
+        assertTrue("This test passed", true);
+    }
+
+    @Ignore("Please don't ignore me!")
+    @Test
+    public void explicitIgnoreTest() {
+        fail("This test should be skipped");
+    }
+
+    @Test
+    public void implicitlyIgnoreTest() {
+        Assume.assumeFalse("This test will be ignored", true);
+        fail("I told you, this test should have been ignored!");
+    }
+
+    @Test
+    @Ignore
+    public void explicitlyIgnoreTestNoMessage() {
+        fail("This test should be skipped");
+    }
+
+    @Test
+    public void implicitlyIgnoreTestNoMessage() {
+        Assume.assumeFalse(true);
+        fail("I told you, this test should have been ignored!");
+    }
+
+    @Test
+    public void failingTest() {
+        fail("I told you this test was going to fail");
+    }
+
+    @Test
+    public void failingTestNoMessage() {
+        fail();
+    }
+
+    @Test
+    public void errorTest() {
+        throw new RuntimeException("Whoops, this test went wrong");
+    }
+
+}

Propchange: ant/core/trunk/src/tests/junit/org/example/junit/Junit4Skippable.java
------------------------------------------------------------------------------
    svn:eol-style = native



Mime
View raw message