present in <classpath> even if not among Ant libs. git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@381467 13f79535-47bb-0310-9956-ffa450edef68master
@@ -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: | |||
@@ -77,6 +77,8 @@ Changes that could break older environments: | |||
Fixed bugs: | |||
----------- | |||
* <junit> can now work with junit.jar in its <classpath>. Bugzilla Report 38799. | |||
* Some potential NullPointerExceptions, Bugzilla Reports 37765 and 38056 | |||
* Problem when adding multiple filter files, Bugzilla Report 37341 | |||
@@ -19,12 +19,12 @@ Library Dependencies</a> for more information. | |||
</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 @@ Do not put either in <code>ANT_HOME/lib</code>, and instead | |||
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 @@ supports a nested <code><classpath></code> | |||
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 @@ aborted. Results are collected in files named | |||
<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> |
@@ -456,7 +456,7 @@ you need jakarta-oro 2.0.1 or later, and <a href="#commons-net">commons-net</a>< | |||
</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 @@ advised to do it by the user mailing list. | |||
<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> | |||
@@ -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. | |||
@@ -1490,4 +1490,8 @@ public class AntClassLoader extends ClassLoader implements SubBuildListener { | |||
} | |||
} | |||
public String toString() { | |||
return "AntClassLoader[" + getClasspath() + "]"; | |||
} | |||
} |
@@ -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 @@ public class FormatterElement { | |||
/** | |||
* @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 @@ public class FormatterElement { | |||
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 @@ public class FormatterElement { | |||
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 { | |||
@@ -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 @@ import org.apache.tools.ant.BuildException; | |||
* testrun. | |||
* | |||
*/ | |||
public interface JUnitResultFormatter extends TestListener { | |||
public interface JUnitResultFormatter extends TestListener, JUnitTaskMirror.JUnitResultFormatterMirror { | |||
/** | |||
* The whole testsuite started. | |||
*/ | |||
@@ -24,6 +24,7 @@ import java.io.FileWriter; | |||
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.List; | |||
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 @@ public class JUnitTask extends Task { | |||
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 @@ public class JUnitTask extends Task { | |||
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 class JUnitTask extends Task { | |||
*/ | |||
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 @@ public class JUnitTask extends Task { | |||
* @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 @@ public class JUnitTask extends Task { | |||
} | |||
} finally { | |||
deleteClassLoader(); | |||
if (mirrorLoader instanceof SplitLoader) { | |||
((SplitLoader) mirrorLoader).cleanup(); | |||
} | |||
delegate = null; | |||
} | |||
} | |||
@@ -1061,18 +1147,22 @@ public class JUnitTask extends Task { | |||
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 @@ public class JUnitTask extends Task { | |||
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 @@ public class JUnitTask extends Task { | |||
* 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 @@ public class JUnitTask extends Task { | |||
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 @@ public class JUnitTask extends Task { | |||
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 @@ public class JUnitTask extends Task { | |||
} | |||
} | |||
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 @@ public class JUnitTask extends Task { | |||
* 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 @@ public class JUnitTask extends Task { | |||
// 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 @@ public class JUnitTask extends Task { | |||
} | |||
protected class TestResultHolder { | |||
public int exitCode = JUnitTestRunner.ERRORS; | |||
public int exitCode = JUnitTaskMirror.JUnitTestRunnerMirror.ERRORS; | |||
public boolean timedOut = false; | |||
public boolean crashed = false; | |||
} | |||
@@ -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); | |||
} | |||
} |
@@ -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(); | |||
} | |||
} |
@@ -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 @@ import org.apache.tools.ant.util.TeeOutputStream; | |||
* @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 @@ public class JUnitTestRunner implements TestListener { | |||
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 @@ public class JUnitTestRunner implements TestListener { | |||
* | |||
* @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 @@ public class JUnitTestRunner implements TestListener { | |||
formatters.addElement(f); | |||
} | |||
public void addFormatter(JUnitTaskMirror.JUnitResultFormatterMirror f) { | |||
formatters.addElement((JUnitResultFormatter) f); | |||
} | |||
/** | |||
* Entry point for standalone (forked) mode. | |||
* | |||
@@ -645,7 +625,7 @@ public class JUnitTestRunner implements TestListener { | |||
test.getOutfile() + fe.getExtension()); | |||
fe.setOutfile(destFile); | |||
} | |||
runner.addFormatter(fe.createFormatter()); | |||
runner.addFormatter((JUnitResultFormatter) fe.createFormatter()); | |||
} | |||
} | |||
@@ -29,7 +29,7 @@ import org.apache.tools.ant.BuildException; | |||
* | |||
*/ | |||
public class SummaryJUnitResultFormatter implements JUnitResultFormatter { | |||
public class SummaryJUnitResultFormatter implements JUnitResultFormatter, JUnitTaskMirror.SummaryJUnitResultFormatterMirror { | |||
/** | |||
* Formatter for timings. | |||
@@ -1386,6 +1386,10 @@ mv /tmp/foo $ANT_HOME/bin/antRun | |||
<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 @@ mv /tmp/foo $ANT_HOME/bin/antRun | |||
</faq> | |||
</faqsection> | |||
</document> | |||
</document> |