Author: jglick
Date: Mon Feb 27 14:24:26 2006
New Revision: 381467
URL: http://svn.apache.org/viewcvs?rev=381467&view=rev
Log:
#38799: <junit> task should work so long as junit.jar
present in <classpath> even if not among Ant libs.
Added:
ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTaskMirror.java
(with props)
ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTaskMirrorImpl.java
(with props)
Modified:
ant/core/trunk/WHATSNEW
ant/core/trunk/docs/manual/OptionalTasks/junit.html
ant/core/trunk/docs/manual/install.html
ant/core/trunk/src/main/org/apache/tools/ant/AntClassLoader.java
ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/FormatterElement.java
ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitResultFormatter.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/JUnitTestRunner.java
ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/SummaryJUnitResultFormatter.java
ant/core/trunk/xdocs/faq.xml
Modified: ant/core/trunk/WHATSNEW
URL: http://svn.apache.org/viewcvs/ant/core/trunk/WHATSNEW?rev=381467&r1=381466&r2=381467&view=diff
==============================================================================
--- ant/core/trunk/WHATSNEW (original)
+++ ant/core/trunk/WHATSNEW Mon Feb 27 14:24:26 2006
@@ -1,4 +1,4 @@
-Changes from current Ant 1.6.5 version to current RCS version
+Changes from current Ant 1.6.5 version to current SVN version
=============================================================
Changes that could break older environments:
@@ -76,6 +76,8 @@
Fixed bugs:
-----------
+
+* <junit> can now work with junit.jar in its <classpath>. Bugzilla Report 38799.
* Some potential NullPointerExceptions, Bugzilla Reports 37765 and 38056
Modified: ant/core/trunk/docs/manual/OptionalTasks/junit.html
URL: http://svn.apache.org/viewcvs/ant/core/trunk/docs/manual/OptionalTasks/junit.html?rev=381467&r1=381466&r2=381467&view=diff
==============================================================================
--- ant/core/trunk/docs/manual/OptionalTasks/junit.html (original)
+++ ant/core/trunk/docs/manual/OptionalTasks/junit.html Mon Feb 27 14:24:26 2006
@@ -19,12 +19,12 @@
</p>
<p>
<strong>Note</strong>:
-You must have <code>junit.jar</code> and the class files for the
-<code><junit></code> task in the same classpath.
+You must have <code>junit.jar</code> available.
You can do one of:
+</p>
<ol>
<li>
-Put both <code>junit.jar</code> and the optional tasks jar file in
+Put both <code>junit.jar</code> and <code>ant-junit.jar</code> in
<code>ANT_HOME/lib</code>.
</li>
<li>
@@ -32,15 +32,23 @@
include their locations in your <code>CLASSPATH</code> environment variable.
</li>
<li>
-Do neither of the above, and instead, specify their locations using
-a <code><classpath></code> element in the build file.
-
+Add both JARs to your classpath using <code>-lib</code>.
+</li>
+<li>
+Specify the locations of both JARs using
+a <code><classpath></code> element in a <code><taskdef></code>
in the build file.
+</li>
+<li>
+Leave <code>ant-junit.jar</code> in its default location in <code>ANT_HOME/lib</code>
+but include <code>junit.jar</code> in the <code><classpath></code>
passed
+to <code><junit></code>. <em>(since Ant 1.7)</em>
+</li>
+</ol>
+<p>
See <a href="../../faq.html#delegating-classloader" target="_top">the
FAQ</a> for details.
-</ol>
</p>
-
<p>Tests are defined by nested <code>test</code> or
<code>batchtest</code> tags (see <a href="#nested">nested
elements</a>).</p>
@@ -217,6 +225,9 @@
element that represents a <a href="../using.html#path">PATH like
structure</a>.</p>
+<p>As of Ant 1.7, this classpath may be used to refer to <code>junit.jar</code>
+as well as your tests and the tested code.
+
<h4>jvmarg</h4>
<p>If <code>fork</code> is enabled, additional parameters may be passed
to
@@ -580,7 +591,7 @@
<code>${reports.tests}</code>.</p>
<hr>
-<p align="center">Copyright © 2000-2005 The Apache Software Foundation. All
rights
+<p align="center">Copyright © 2000-2006 The Apache Software Foundation. All
rights
Reserved.</p>
</body>
</html>
Modified: ant/core/trunk/docs/manual/install.html
URL: http://svn.apache.org/viewcvs/ant/core/trunk/docs/manual/install.html?rev=381467&r1=381466&r2=381467&view=diff
==============================================================================
--- ant/core/trunk/docs/manual/install.html (original)
+++ ant/core/trunk/docs/manual/install.html Mon Feb 27 14:24:26 2006
@@ -456,7 +456,7 @@
</tr>
<tr>
<td>junit.jar</td>
- <td>junit tasks</td>
+ <td><code><junit></code> task. May be in classpath passed
to task rather than Ant's classpath.</td>
<td><a href="http://www.junit.org/" target="_top">http://www.junit.org/</a></td>
</tr>
<tr>
@@ -698,7 +698,7 @@
<hr>
-<p align="center">Copyright © 2000-2005 The Apache Software Foundation. All
rights
+<p align="center">Copyright © 2000-2006 The Apache Software Foundation. All
rights
Reserved.</p>
</body>
Modified: ant/core/trunk/src/main/org/apache/tools/ant/AntClassLoader.java
URL: http://svn.apache.org/viewcvs/ant/core/trunk/src/main/org/apache/tools/ant/AntClassLoader.java?rev=381467&r1=381466&r2=381467&view=diff
==============================================================================
--- ant/core/trunk/src/main/org/apache/tools/ant/AntClassLoader.java (original)
+++ ant/core/trunk/src/main/org/apache/tools/ant/AntClassLoader.java Mon Feb 27 14:24:26 2006
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2005 The Apache Software Foundation
+ * Copyright 2000-2006 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -1488,6 +1488,10 @@
String packageName = (String) e.nextElement();
addSystemPackageRoot(packageName);
}
+ }
+
+ public String toString() {
+ return "AntClassLoader[" + getClasspath() + "]";
}
}
Modified: ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/FormatterElement.java
URL: http://svn.apache.org/viewcvs/ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/FormatterElement.java?rev=381467&r1=381466&r2=381467&view=diff
==============================================================================
--- ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/FormatterElement.java
(original)
+++ ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/FormatterElement.java
Mon Feb 27 14:24:26 2006
@@ -1,5 +1,5 @@
/*
- * Copyright 2001-2004 The Apache Software Foundation
+ * Copyright 2001-2004,2006 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -188,14 +188,14 @@
/**
* @since Ant 1.2
*/
- JUnitResultFormatter createFormatter() throws BuildException {
+ JUnitTaskMirror.JUnitResultFormatterMirror createFormatter() throws BuildException {
return createFormatter(null);
}
/**
* @since Ant 1.6
*/
- JUnitResultFormatter createFormatter(ClassLoader loader)
+ JUnitTaskMirror.JUnitResultFormatterMirror createFormatter(ClassLoader loader)
throws BuildException {
if (classname == null) {
@@ -210,7 +210,9 @@
f = Class.forName(classname, true, loader);
}
} catch (ClassNotFoundException e) {
- throw new BuildException(e);
+ throw new BuildException("Using loader " + loader + " on class " + classname
+ ": " + e, e);
+ } catch (NoClassDefFoundError e) {
+ throw new BuildException("Using loader " + loader + " on class " + classname
+ ": " + e, e);
}
Object o = null;
@@ -222,12 +224,11 @@
throw new BuildException(e);
}
- if (!(o instanceof JUnitResultFormatter)) {
+ if (!(o instanceof JUnitTaskMirror.JUnitResultFormatterMirror)) {
throw new BuildException(classname
+ " is not a JUnitResultFormatter");
}
-
- JUnitResultFormatter r = (JUnitResultFormatter) o;
+ JUnitTaskMirror.JUnitResultFormatterMirror r = (JUnitTaskMirror.JUnitResultFormatterMirror)
o;
if (useFile && outFile != null) {
try {
Modified: ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitResultFormatter.java
URL: http://svn.apache.org/viewcvs/ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitResultFormatter.java?rev=381467&r1=381466&r2=381467&view=diff
==============================================================================
--- ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitResultFormatter.java
(original)
+++ ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitResultFormatter.java
Mon Feb 27 14:24:26 2006
@@ -1,5 +1,5 @@
/*
- * Copyright 2001-2002,2004 The Apache Software Foundation
+ * Copyright 2001-2002,2004,2006 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -26,7 +26,7 @@
* testrun.
*
*/
-public interface JUnitResultFormatter extends TestListener {
+public interface JUnitResultFormatter extends TestListener, JUnitTaskMirror.JUnitResultFormatterMirror
{
/**
* The whole testsuite started.
*/
Modified: ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTask.java
URL: http://svn.apache.org/viewcvs/ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTask.java?rev=381467&r1=381466&r2=381467&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 Mon
Feb 27 14:24:26 2006
@@ -24,6 +24,7 @@
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
+import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
@@ -34,9 +35,6 @@
import java.util.Map;
import java.util.Properties;
import java.util.Vector;
-import junit.framework.AssertionFailedError;
-import junit.framework.Test;
-import junit.framework.TestResult;
import org.apache.tools.ant.AntClassLoader;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
@@ -134,7 +132,7 @@
private boolean summary = false;
private boolean reloading = true;
private String summaryValue = "";
- private JUnitTestRunner runner = null;
+ private JUnitTaskMirror.JUnitTestRunnerMirror runner = null;
private boolean newEnvironment = false;
private Environment env = new Environment();
@@ -148,6 +146,9 @@
private Permissions perm = null;
private ForkMode forkMode = new ForkMode("perTest");
+ private boolean splitJunit = false;
+ private JUnitTaskMirror delegate;
+
private static final int STRING_BUFFER_SIZE = 128;
/**
* @since Ant 1.7
@@ -632,12 +633,81 @@
*/
public void init() {
antRuntimeClasses = new Path(getProject());
- addClasspathEntry("/junit/framework/TestCase.class");
+ splitJunit = !addClasspathEntry("/junit/framework/TestCase.class");
addClasspathEntry("/org/apache/tools/ant/launch/AntMain.class");
addClasspathEntry("/org/apache/tools/ant/Task.class");
addClasspathEntry("/org/apache/tools/ant/taskdefs/optional/junit/JUnitTestRunner.class");
}
+ private static JUnitTaskMirror createMirror(JUnitTask task, ClassLoader loader) {
+ try {
+ loader.loadClass("junit.framework.Test"); // sanity check
+ } catch (ClassNotFoundException e) {
+ throw new BuildException(
+ "The <classpath> for <junit> must include junit.jar if not
in Ant's own classpath",
+ e, task.getLocation());
+ }
+ try {
+ Class c = loader.loadClass(JUnitTaskMirror.class.getName() + "Impl");
+ if (c.getClassLoader() != loader) {
+ throw new BuildException("Overdelegating loader", task.getLocation());
+ }
+ Constructor cons = c.getConstructor(new Class[] {JUnitTask.class});
+ return (JUnitTaskMirror) cons.newInstance(new Object[] {task});
+ } catch (Exception e) {
+ throw new BuildException(e, task.getLocation());
+ }
+ }
+
+ private final class SplitLoader extends AntClassLoader {
+
+ public SplitLoader(ClassLoader parent, Path path) {
+ super(parent, getProject(), path, true);
+ }
+
+ // forceLoadClass is not convenient here since it would not
+ // properly deal with inner classes of these classes.
+ protected synchronized Class loadClass(String classname, boolean resolve)
+ throws ClassNotFoundException {
+ Class theClass = findLoadedClass(classname);
+ if (theClass != null) {
+ return theClass;
+ }
+ if (isSplit(classname)) {
+ theClass = findClass(classname);
+ if (resolve) {
+ resolveClass(theClass);
+ }
+ return theClass;
+ } else {
+ return super.loadClass(classname, resolve);
+ }
+ }
+
+ private final String[] SPLIT_CLASSES = {
+ "BriefJUnitResultFormatter",
+ "JUnitResultFormatter",
+ "JUnitTaskMirrorImpl",
+ "JUnitTestRunner",
+ "JUnitVersionHelper",
+ "OutErrSummaryJUnitResultFormatter",
+ "PlainJUnitResultFormatter",
+ "SummaryJUnitResultFormatter",
+ "XMLJUnitResultFormatter",
+ };
+
+ private boolean isSplit(String classname) {
+ String simplename = classname.substring(classname.lastIndexOf('.') + 1);
+ for (int i = 0; i < SPLIT_CLASSES.length; i++) {
+ if (simplename.equals(SPLIT_CLASSES[i]) || simplename.startsWith(SPLIT_CLASSES[i]
+ '$')) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ }
+
/**
* Runs the testcase.
*
@@ -645,6 +715,18 @@
* @since Ant 1.2
*/
public void execute() throws BuildException {
+ ClassLoader myLoader = JUnitTask.class.getClassLoader();
+ ClassLoader mirrorLoader;
+ if (splitJunit) {
+ Path path = new Path(getProject());
+ path.add(antRuntimeClasses);
+ path.add(getCommandline().getClasspath());
+ mirrorLoader = new SplitLoader(myLoader, path);
+ } else {
+ mirrorLoader = myLoader;
+ }
+ delegate = createMirror(this, mirrorLoader);
+
List testLists = new ArrayList();
boolean forkPerTest = forkMode.getValue().equals(ForkMode.PER_TEST);
@@ -672,6 +754,10 @@
}
} finally {
deleteClassLoader();
+ if (mirrorLoader instanceof SplitLoader) {
+ ((SplitLoader) mirrorLoader).cleanup();
+ }
+ delegate = null;
}
}
@@ -1061,18 +1147,22 @@
try {
log("Using System properties " + System.getProperties(),
Project.MSG_VERBOSE);
- createClassLoader();
+ if (splitJunit) {
+ classLoader = (AntClassLoader) delegate.getClass().getClassLoader();
+ } else {
+ createClassLoader();
+ }
if (classLoader != null) {
classLoader.setThreadContextLoader();
}
- runner = new JUnitTestRunner(test, test.getHaltonerror(),
+ runner = delegate.newJUnitTestRunner(test, test.getHaltonerror(),
test.getFiltertrace(),
test.getHaltonfailure(), false,
true, classLoader);
if (summary) {
- SummaryJUnitResultFormatter f =
- new SummaryJUnitResultFormatter();
+ JUnitTaskMirror.SummaryJUnitResultFormatterMirror f =
+ delegate.newSummaryJUnitResultFormatter();
f.setWithOutAndErr("withoutanderr"
.equalsIgnoreCase(summaryValue));
f.setOutput(getDefaultOutput());
@@ -1186,7 +1276,7 @@
if (fe.getUseFile()) {
String base = test.getOutfile();
if (base == null) {
- base = JUnitTestRunner.IGNORED_FILE_NAME;
+ base = JUnitTaskMirror.JUnitTestRunnerMirror.IGNORED_FILE_NAME;
}
String filename = base + fe.getExtension();
File destFile = new File(test.getTodir(), filename);
@@ -1204,9 +1294,10 @@
* getResource doesn't contain the name of the archive.</p>
*
* @param resource resource that one wants to lookup
+ * @return true if something was in fact added
* @since Ant 1.4
*/
- protected void addClasspathEntry(String resource) {
+ protected boolean addClasspathEntry(String resource) {
/*
* pre Ant 1.6 this method used to call getClass().getResource
* while Ant 1.6 will call ClassLoader.getResource().
@@ -1228,8 +1319,10 @@
if (f != null) {
log("Found " + f.getAbsolutePath(), Project.MSG_DEBUG);
antRuntimeClasses.createPath().setLocation(f);
+ return true;
} else {
log("Couldn\'t find " + resource, Project.MSG_DEBUG);
+ return false;
}
}
@@ -1269,7 +1362,7 @@
for (int i = 0; i < feArray.length; i++) {
FormatterElement fe = feArray[i];
File outFile = getOutput(fe, test);
- JUnitResultFormatter formatter = fe.createFormatter(classLoader);
+ JUnitTaskMirror.JUnitResultFormatterMirror formatter = fe.createFormatter(classLoader);
if (outFile != null && formatter != null) {
try {
OutputStream out = new FileOutputStream(outFile);
@@ -1280,7 +1373,7 @@
}
}
if (summary) {
- SummaryJUnitResultFormatter f = new SummaryJUnitResultFormatter();
+ JUnitTaskMirror.SummaryJUnitResultFormatterMirror f = delegate.newSummaryJUnitResultFormatter();
f.setWithOutAndErr("withoutanderr".equalsIgnoreCase(summaryValue));
addVmExit(test, f, getDefaultOutput(), message);
}
@@ -1291,23 +1384,9 @@
* Only used from the logVmExit method.
* @since Ant 1.7
*/
- private void addVmExit(JUnitTest test, JUnitResultFormatter formatter,
+ private void addVmExit(JUnitTest test, JUnitTaskMirror.JUnitResultFormatterMirror formatter,
OutputStream out, final String message) {
- formatter.setOutput(out);
- formatter.startTestSuite(test);
-
- //the trick to integrating test output to the formatter, is to
- //create a special test class that asserts an error
- //and tell the formatter that it raised.
- Test t = new Test() {
- public int countTestCases() { return 1; }
- public void run(TestResult r) {
- throw new AssertionFailedError(message);
- }
- };
- formatter.startTest(t);
- formatter.addError(t, new AssertionFailedError(message));
- formatter.endTestSuite(test);
+ delegate.addVmExit(test, formatter, out, message);
}
/**
@@ -1535,9 +1614,9 @@
// everything otherwise just log a statement
boolean fatal = result.timedOut || result.crashed;
boolean errorOccurredHere =
- result.exitCode == JUnitTestRunner.ERRORS || fatal;
+ result.exitCode == JUnitTaskMirror.JUnitTestRunnerMirror.ERRORS || fatal;
boolean failureOccurredHere =
- result.exitCode != JUnitTestRunner.SUCCESS || fatal;
+ result.exitCode != JUnitTaskMirror.JUnitTestRunnerMirror.SUCCESS || fatal;
if (errorOccurredHere || failureOccurredHere) {
if ((errorOccurredHere && test.getHaltonerror())
|| (failureOccurredHere && test.getHaltonfailure())) {
@@ -1559,7 +1638,7 @@
}
protected class TestResultHolder {
- public int exitCode = JUnitTestRunner.ERRORS;
+ public int exitCode = JUnitTaskMirror.JUnitTestRunnerMirror.ERRORS;
public boolean timedOut = false;
public boolean crashed = false;
}
Added: ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTaskMirror.java
URL: http://svn.apache.org/viewcvs/ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTaskMirror.java?rev=381467&view=auto
==============================================================================
--- ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTaskMirror.java
(added)
+++ ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTaskMirror.java
Mon Feb 27 14:24:26 2006
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2006 The Apache Software Foundation
+ *
+ * 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.apache.tools.ant.taskdefs.optional.junit;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import org.apache.tools.ant.AntClassLoader;
+import org.apache.tools.ant.types.Permissions;
+
+/**
+ * Handles the portions of {@link JUnitTask} which need to directly access
+ * actual JUnit classes, so that junit.jar need not be on Ant's startup classpath.
+ * Neither JUnitTask.java nor JUnitTaskMirror.java nor their transitive static
+ * deps may import any junit.** classes!
+ * Specifically, need to not refer to
+ * - JUnitResultFormatter or its subclasses
+ * - JUnitVersionHelper
+ * - JUnitTestRunner
+ * Cf. {@link JUnitTask.SplitLoader#isSplit}
+ * Public only to permit access from classes in this package; do not use directly.
+ *
+ * @author refactoring tricks by Jesse Glick, real code by others
+ * @since 1.7
+ * @see "bug #38799"
+ */
+public interface JUnitTaskMirror {
+
+ void addVmExit(JUnitTest test, JUnitResultFormatterMirror formatter,
+ OutputStream out, final String message);
+
+ JUnitTestRunnerMirror newJUnitTestRunner(JUnitTest test, boolean haltOnError,
+ boolean filterTrace, boolean haltOnFailure, boolean showOutput,
+ boolean logTestListenerEvents, AntClassLoader classLoader);
+
+ SummaryJUnitResultFormatterMirror newSummaryJUnitResultFormatter();
+
+ public interface JUnitResultFormatterMirror {
+
+ void setOutput(OutputStream outputStream);
+
+ }
+
+ public interface SummaryJUnitResultFormatterMirror extends JUnitResultFormatterMirror
{
+
+ void setWithOutAndErr(boolean value);
+
+ }
+
+ public interface JUnitTestRunnerMirror {
+
+ /**
+ * Used in formatter arguments as a placeholder for the basename
+ * of the output file (which gets replaced by a test specific
+ * output file name later).
+ *
+ * @since Ant 1.6.3
+ */
+ String IGNORED_FILE_NAME = "IGNORETHIS";
+
+ /**
+ * No problems with this test.
+ */
+ int SUCCESS = 0;
+
+ /**
+ * Some tests failed.
+ */
+ int FAILURES = 1;
+
+ /**
+ * An error occurred.
+ */
+ int ERRORS = 2;
+
+ void setPermissions(Permissions perm);
+
+ void run();
+
+ void addFormatter(JUnitResultFormatterMirror formatter);
+
+ int getRetCode();
+
+ void handleErrorFlush(String output);
+
+ void handleErrorOutput(String output);
+
+ void handleOutput(String output);
+
+ int handleInput(byte[] buffer, int offset, int length) throws IOException;
+
+ void handleFlush(String output);
+
+ }
+
+}
Propchange: ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTaskMirror.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTaskMirrorImpl.java
URL: http://svn.apache.org/viewcvs/ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTaskMirrorImpl.java?rev=381467&view=auto
==============================================================================
--- ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTaskMirrorImpl.java
(added)
+++ ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTaskMirrorImpl.java
Mon Feb 27 14:24:26 2006
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2006 The Apache Software Foundation
+ *
+ * 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.apache.tools.ant.taskdefs.optional.junit;
+
+import java.io.OutputStream;
+import junit.framework.AssertionFailedError;
+import junit.framework.Test;
+import junit.framework.TestResult;
+import org.apache.tools.ant.AntClassLoader;
+
+/**
+ * Implementation of the part of the junit task which can directly refer to junit.* classes.
+ * Public only to permit use of reflection; do not use directly.
+ * @see JUnitTaskMirror
+ * @see "bug #38799"
+ * @since 1.7
+ */
+public final class JUnitTaskMirrorImpl implements JUnitTaskMirror {
+
+ private final JUnitTask task;
+
+ public JUnitTaskMirrorImpl(JUnitTask task) {
+ this.task = task;
+ }
+
+ public void addVmExit(JUnitTest test, JUnitResultFormatterMirror _formatter,
+ OutputStream out, final String message) {
+ JUnitResultFormatter formatter = (JUnitResultFormatter) _formatter;
+ formatter.setOutput(out);
+ formatter.startTestSuite(test);
+
+ //the trick to integrating test output to the formatter, is to
+ //create a special test class that asserts an error
+ //and tell the formatter that it raised.
+ Test t = new Test() {
+ public int countTestCases() { return 1; }
+ public void run(TestResult r) {
+ throw new AssertionFailedError(message);
+ }
+ };
+ formatter.startTest(t);
+ formatter.addError(t, new AssertionFailedError(message));
+ formatter.endTestSuite(test);
+ }
+
+ public JUnitTaskMirror.JUnitTestRunnerMirror newJUnitTestRunner(JUnitTest test,
+ boolean haltOnError, boolean filterTrace, boolean haltOnFailure,
+ boolean showOutput, boolean logTestListenerEvents, AntClassLoader classLoader)
{
+ return new JUnitTestRunner(test, haltOnError, filterTrace, haltOnFailure,
+ showOutput, logTestListenerEvents, classLoader);
+ }
+
+ public JUnitTaskMirror.SummaryJUnitResultFormatterMirror newSummaryJUnitResultFormatter()
{
+ return new SummaryJUnitResultFormatter();
+ }
+
+}
Propchange: ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTaskMirrorImpl.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTestRunner.java
URL: http://svn.apache.org/viewcvs/ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTestRunner.java?rev=381467&r1=381466&r2=381467&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
Mon Feb 27 14:24:26 2006
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2005 The Apache Software Foundation
+ * Copyright 2000-2006 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -62,31 +62,7 @@
* @since Ant 1.2
*/
-public class JUnitTestRunner implements TestListener {
-
- /**
- * No problems with this test.
- */
- public static final int SUCCESS = 0;
-
- /**
- * Some tests failed.
- */
- public static final int FAILURES = 1;
-
- /**
- * An error occurred.
- */
- public static final int ERRORS = 2;
-
- /**
- * Used in formatter arguments as a placeholder for the basename
- * of the output file (which gets replaced by a test specific
- * output file name later).
- *
- * @since Ant 1.6.3
- */
- public static final String IGNORED_FILE_NAME = "IGNORETHIS";
+public class JUnitTestRunner implements TestListener, JUnitTaskMirror.JUnitTestRunnerMirror
{
/**
* Holds the registered formatters.
@@ -441,7 +417,7 @@
perm = permissions;
}
- protected void handleOutput(String output) {
+ public void handleOutput(String output) {
if (!logTestListenerEvents && output.startsWith(JUnitTask.TESTLISTENER_PREFIX))
; // ignore
else if (systemOut != null) {
@@ -454,24 +430,24 @@
*
* @since Ant 1.6
*/
- protected int handleInput(byte[] buffer, int offset, int length)
+ public int handleInput(byte[] buffer, int offset, int length)
throws IOException {
return -1;
}
- protected void handleErrorOutput(String output) {
+ public void handleErrorOutput(String output) {
if (systemError != null) {
systemError.print(output);
}
}
- protected void handleFlush(String output) {
+ public void handleFlush(String output) {
if (systemOut != null) {
systemOut.print(output);
}
}
- protected void handleErrorFlush(String output) {
+ public void handleErrorFlush(String output) {
if (systemError != null) {
systemError.print(output);
}
@@ -505,6 +481,10 @@
formatters.addElement(f);
}
+ public void addFormatter(JUnitTaskMirror.JUnitResultFormatterMirror f) {
+ formatters.addElement((JUnitResultFormatter) f);
+ }
+
/**
* Entry point for standalone (forked) mode.
*
@@ -645,7 +625,7 @@
test.getOutfile() + fe.getExtension());
fe.setOutfile(destFile);
}
- runner.addFormatter(fe.createFormatter());
+ runner.addFormatter((JUnitResultFormatter) fe.createFormatter());
}
}
Modified: ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/SummaryJUnitResultFormatter.java
URL: http://svn.apache.org/viewcvs/ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/SummaryJUnitResultFormatter.java?rev=381467&r1=381466&r2=381467&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
Mon Feb 27 14:24:26 2006
@@ -29,7 +29,7 @@
*
*/
-public class SummaryJUnitResultFormatter implements JUnitResultFormatter {
+public class SummaryJUnitResultFormatter implements JUnitResultFormatter, JUnitTaskMirror.SummaryJUnitResultFormatterMirror
{
/**
* Formatter for timings.
Modified: ant/core/trunk/xdocs/faq.xml
URL: http://svn.apache.org/viewcvs/ant/core/trunk/xdocs/faq.xml?rev=381467&r1=381466&r2=381467&view=diff
==============================================================================
--- ant/core/trunk/xdocs/faq.xml (original)
+++ ant/core/trunk/xdocs/faq.xml Mon Feb 27 14:24:26 2006
@@ -1386,6 +1386,10 @@
<code>org.apache.tools.ant.taskdefs.XSLTLiaison</code>
class.</p>
+ <p><em>As of Ant 1.7</em> <code><junit></code>
no longer
+ requires you to have <code>junit.jar</code> in Ant's startup
+ classpath even if <code>ant-junit.jar</code> is present there.</p>
+
<p>Ant's class loader implementation uses Java's
delegation model, see <a
href="http://java.sun.com/products/jdk/1.2/docs/api/java/lang/ClassLoader.html">http://java.sun.com/products/jdk/1.2/docs/api/java/lang/ClassLoader.html</a>
@@ -1776,4 +1780,4 @@
</faq>
</faqsection>
-</document>
\ No newline at end of file
+</document>
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@ant.apache.org
For additional commands, e-mail: dev-help@ant.apache.org
|