From 28e641ed17852d21e7f72dbf26b27ca1db99169b Mon Sep 17 00:00:00 2001 From: Stephane Bailliez Date: Sat, 5 Jan 2002 19:06:44 +0000 Subject: [PATCH] Initial commit This is a refactoring that have too much impact on the Ant JUnit code, therefore I'm experimenting some ideas here. git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@270535 13f79535-47bb-0310-9956-ffa450edef68 --- .../taskdefs/optional/junit/JUnitHelper.java | 127 ++++++++++ .../optional/junit/TestRunListener.java | 120 ++++++++++ .../taskdefs/optional/junit/WatchdogTest.java | 115 +++++++++ .../junit/formatter/BaseFormatter.java | 160 +++++++++++++ .../junit/formatter/BriefFormatter.java | 80 +++++++ .../formatter/DefaultTestRunListener.java | 94 ++++++++ .../junit/formatter/FilterFormatter.java | 111 +++++++++ .../junit/formatter/FilterStackFormatter.java | 132 +++++++++++ .../optional/junit/formatter/Formatter.java | 80 +++++++ .../junit/formatter/SummaryFormatter.java | 87 +++++++ .../junit/formatter/XMLFormatter.java | 223 ++++++++++++++++++ 11 files changed, 1329 insertions(+) create mode 100644 proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitHelper.java create mode 100644 proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/junit/TestRunListener.java create mode 100644 proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/junit/WatchdogTest.java create mode 100644 proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/junit/formatter/BaseFormatter.java create mode 100644 proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/junit/formatter/BriefFormatter.java create mode 100644 proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/junit/formatter/DefaultTestRunListener.java create mode 100644 proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/junit/formatter/FilterFormatter.java create mode 100644 proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/junit/formatter/FilterStackFormatter.java create mode 100644 proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/junit/formatter/Formatter.java create mode 100644 proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/junit/formatter/SummaryFormatter.java create mode 100644 proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/junit/formatter/XMLFormatter.java diff --git a/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitHelper.java b/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitHelper.java new file mode 100644 index 000000000..588bafc53 --- /dev/null +++ b/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitHelper.java @@ -0,0 +1,127 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Ant", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.tools.ant.taskdefs.optional.junit; + +import java.lang.reflect.Method; + +import junit.framework.Test; +import junit.framework.TestSuite; + +/** + * A set of helpers functions to deal with JUnit. + * + * @author Stephane Bailliez + */ +public final class JUnitHelper { + + private static final String SUITE_METHODNAME = "suite"; + + /** + * This method parse the output of the method toString() + * from the TestCase class. The format returned is: + * name(classname) + * @return an array with the elements in the order name, classname. + */ + public static String[] parseTestString(String testname){ + int p1 = testname.indexOf('('); + int p2 = testname.indexOf(')', p1); + return new String[]{ + testname.substring(0, p1), + testname.substring(p1 + 1, p2) }; + } + + /** + * Returns the Test corresponding to to the given class name + * @param classname the classname of the test we want to extract. + * @throws Exception a generic exception + */ + public static Test getTest(ClassLoader loader, String classname) throws Exception { + Class clazz = null; + if (loader == null) { + clazz = Class.forName(classname); + } else { + loader.loadClass(classname); + } + return getTest(clazz); + } + + + /** + * Extract a test from a given class + * @param clazz the class to extract a test from. + * @throws Exception a generic exception + */ + public static Test getTest(Class clazz) { + try { + Object obj = clazz.newInstance(); + if (obj instanceof TestSuite){ + return (TestSuite) obj; + } + } catch (Exception e){ + } + try { + // check if there is a suite method + Method suiteMethod = clazz.getMethod(SUITE_METHODNAME, new Class[0]); + return (Test) suiteMethod.invoke(null, new Class[0]); + } catch (Exception e) { + } + // try to extract a test suite automatically + // this will generate warnings if the class is no suitable Test + try { + return new TestSuite(clazz); + } catch (Exception e){ + } + return null; + } +} diff --git a/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/junit/TestRunListener.java b/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/junit/TestRunListener.java new file mode 100644 index 000000000..297d43dd1 --- /dev/null +++ b/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/junit/TestRunListener.java @@ -0,0 +1,120 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Ant", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.tools.ant.taskdefs.optional.junit; + +import java.util.Properties; + + +/** + * A test sequence listener listening for a batch test run. + * + * + * This code is based on the code from Erich Gamma made for the + * JUnit plugin for Eclipse. {@link http://www.eclipse.org} and is merged + * with code originating from Ant 1.4.x. + * + * + * @author Stephane Bailliez + */ +public interface TestRunListener { + + /** Some tests failed. */ + public final static int STATUS_FAILURE = 1; + + /** An error occured. */ + public final static int STATUS_ERROR = 2; + + /** + * A test has started. + * @param a testname made of the testname and testcase classname. + * in the following format: <testname>(<testcase>) + */ + public void testStarted(String testname); + + /** + * A test ended. + * @param a testname made of the testname and testcase classname. + * in the following format: <testname>(<testcase>) + */ + public void testEnded(String testname); + + /** + * A test has failed. + * @param status failure or error status code. + * @param a testname made of the testname and testcase classname. + * in the following format: <testname>(<testcase>) + * @param trace the error/failure stacktrace. + * @todo change this to a testFailure / testError ? + */ + public void testFailed(int status, String testname, String trace); + + /** test logged this line on stdout */ + public void testStdOutLine(String testname, String line); + + /** test logged this line on sterr */ + public void testStdErrLine(String testname, String line); + + /** these system properties are used on the remote client */ + public void testRunSystemProperties(Properties props); + + /** starting a sequence of testcount tests. */ + public void testRunStarted(int testcount); + + /** ending gracefully the sequence after elapsedtime ms. */ + public void testRunEnded(long elapsedtime); + + /** stopping the sequence after elapsedtime ms. */ + public void testRunStopped(long elapsedtime); + +} diff --git a/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/junit/WatchdogTest.java b/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/junit/WatchdogTest.java new file mode 100644 index 000000000..7a0587acd --- /dev/null +++ b/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/junit/WatchdogTest.java @@ -0,0 +1,115 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 1999 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Jakarta-Regexp", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ +package org.apache.tools.ant.taskdefs.optional.junit; + +import junit.extensions.TestDecorator; +import junit.framework.AssertionFailedError; +import junit.framework.Test; +import junit.framework.TestResult; + +/** + * A Test decorator that allows to cancel a test if it exceeds + * a certain time. It can be used globally or individually over + * each testcase. + * + * @author Stephane Bailliez + */ +public class WatchdogTest extends TestDecorator { + + /** the time out delay in msecs */ + protected long timeOut; + + /** + * Create a new watchdog. + * @param test the test to watch for + * @param msecs the time out delay in msecs. + */ + public WatchdogTest(Test test, long msecs) { + super(test); + timeOut = msecs; + } + + public void run(TestResult result) { + Thread worker = createWorker(result); + worker.start(); + + try { + // wait at most the timeOut time. + worker.join(timeOut); + + // if the thread is still alive, it must be killed. + if (worker.isAlive()) { + worker.interrupt(); + result.addFailure(getTest(), + new AssertionFailedError("Timed out after " + timeOut + "ms")); + } + } catch (InterruptedException e) { + worker.interrupt(); + result.addError(getTest(), e); + result.stop(); + } + } + + /** create a new worker thread */ + protected Thread createWorker(final TestResult result) { + Thread worker = new Thread("JUnit Test Worker") { + public void run() { + getTest().run(result); + } + }; + return worker; + } + +} diff --git a/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/junit/formatter/BaseFormatter.java b/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/junit/formatter/BaseFormatter.java new file mode 100644 index 000000000..74b89b1de --- /dev/null +++ b/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/junit/formatter/BaseFormatter.java @@ -0,0 +1,160 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Ant", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.tools.ant.taskdefs.optional.junit.formatter; + +import java.io.BufferedWriter; +import java.io.IOException; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; +import java.util.Properties; + +/** + * Provide a common set of attributes and methods to factorize + * + * @author Stephane Bailliez + */ +public abstract class BaseFormatter implements Formatter { + + protected OutputStream out; + + protected PrintWriter writer; + + protected int errorCount; + + protected int failureCount; + + protected int runCount; + + protected Properties props; + + public void setOutput(OutputStream value) { + out = value; + try { + writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(out, "UTF8")), true); + } catch (IOException e){ + // should not happen + throw new IllegalStateException(e.getMessage()); + } + } + + protected void finalize() throws Throwable { + super.finalize(); + close(); + } + + public void setSystemOutput(String out) { + } + + public void setSystemError(String err) { + } + + public void testStdOutLine(String testname, String line) { + } + + public void testStdErrLine(String testname, String line) { + } + + public void testRunSystemProperties(Properties props) { + } + + public void testStarted(String testname) { + } + + public void testEnded(String testname) { + } + + public void testFailed(int status, String testname, String trace) { + if (status == STATUS_ERROR) { + errorCount++; + } else if (status == STATUS_FAILURE) { + failureCount++; + } + } + + public void testRunStarted(int testcount) { + runCount = testcount; + } + + public void testRunEnded(long elapsedtime) { + finished(elapsedtime); + } + + public void testRunStopped(long elapsedtime) { + finished(elapsedtime); + } + + protected void finished(long elapsedtime) { + close(); + } + + /** helper method to flush and close all streams */ + protected void close() { + try { + if (writer != null) { + writer.flush(); + writer = null; + } + } finally { + // make sure we're not closing System.out or System.err... + if (out != null && out != System.err && out != System.out) { + try { + out.close(); + out = null; + } catch (IOException e) { + } + } + } + } +} diff --git a/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/junit/formatter/BriefFormatter.java b/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/junit/formatter/BriefFormatter.java new file mode 100644 index 000000000..602a9d841 --- /dev/null +++ b/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/junit/formatter/BriefFormatter.java @@ -0,0 +1,80 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Ant", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.tools.ant.taskdefs.optional.junit.formatter; + + +/** + * Display additional messages from a SummaryFormatter + * for failures and errors. + * + * @author Stephane Bailliez + */ +public class BriefFormatter extends SummaryFormatter { + + public void testFailed(int status, String testname, String trace) { + writer.print("TestCase: "); + writer.print(testname); + if (status == STATUS_ERROR) { + writer.print("\tCaused an ERROR"); + } else if (status == STATUS_FAILURE) { + writer.write("\tFAILED"); + } + writer.println(); + writer.print(trace); + writer.println(); + writer.println(); + super.testFailed(status, testname, trace); + } + +} diff --git a/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/junit/formatter/DefaultTestRunListener.java b/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/junit/formatter/DefaultTestRunListener.java new file mode 100644 index 000000000..5bb2ffca9 --- /dev/null +++ b/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/junit/formatter/DefaultTestRunListener.java @@ -0,0 +1,94 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Ant", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.tools.ant.taskdefs.optional.junit.formatter; + +import java.util.Properties; + +import org.apache.tools.ant.taskdefs.optional.junit.TestRunListener; + +/** + * + * @author Stephane Bailliez + */ +public class DefaultTestRunListener implements TestRunListener { + + public void testStarted(String testname) { + System.out.println("Started " + testname); + } + + public void testEnded(String testname) { + System.out.println("Ended " + testname); + } + + public void testFailed(int status, String testname, String trace) { + System.out.println(testname + " failed with status " + status); + System.out.println(trace); + } + + public void testRunSystemProperties(Properties props) { + System.out.println("properties: " + props); + } + + public void testRunStarted(int testcount) { + System.out.println("testsuite: " + testcount); + } + + public void testRunEnded(long elapsedtime) { + System.out.println("testsuite ended after: " + elapsedtime); + } + + public void testRunStopped(long elapsedtime) { + System.out.println("testsuite stopped after: " + elapsedtime); + } +} diff --git a/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/junit/formatter/FilterFormatter.java b/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/junit/formatter/FilterFormatter.java new file mode 100644 index 000000000..514f055b1 --- /dev/null +++ b/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/junit/formatter/FilterFormatter.java @@ -0,0 +1,111 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Ant", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.tools.ant.taskdefs.optional.junit.formatter; + +import java.io.OutputStream; +import java.util.Properties; + +/** + * A base class that can be used to filter data. + * + * @author Stephane Bailliez + */ +public abstract class FilterFormatter implements Formatter { + + protected Formatter formatter; + + protected FilterFormatter(Formatter value){ + formatter = value; + } + + public void setOutput(OutputStream out) { + formatter.setOutput(out); + } + + public void testStarted(String testname) { + formatter.testStarted(testname); + } + + public void setSystemOutput(String out) { + formatter.setSystemOutput(out); + } + + public void testEnded(String testname) { + formatter.testEnded(testname); + } + + public void setSystemError(String err) { + formatter.setSystemError(err); + } + + public void testFailed(int status, String testname, String trace) { + formatter.testFailed(status, testname, trace); + } + + public void testRunSystemProperties(Properties props) { + formatter.testRunSystemProperties(props); + } + + public void testRunStarted(int testcount) { + formatter.testRunStarted(testcount); + } + + public void testRunEnded(long elapsedtime) { + formatter.testRunEnded(elapsedtime); + } + + public void testRunStopped(long elapsedtime) { + formatter.testRunEnded(elapsedtime); + } +} diff --git a/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/junit/formatter/FilterStackFormatter.java b/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/junit/formatter/FilterStackFormatter.java new file mode 100644 index 000000000..d12fd9ffa --- /dev/null +++ b/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/junit/formatter/FilterStackFormatter.java @@ -0,0 +1,132 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Ant", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.tools.ant.taskdefs.optional.junit.formatter; + +import java.io.StringWriter; +import java.io.PrintWriter; +import java.io.StringReader; +import java.io.BufferedReader; +import java.util.StringTokenizer; + +import org.apache.tools.ant.util.StringUtils; + +/** + * Filtered Formatter that strips out unwanted stack frames from the full + * stack trace, for instance it will filter the lines containing the + * following matches: + *
+ *   junit.framework.TestCase
+ *   junit.framework.TestResult
+ *   junit.framework.TestSuite
+ *   junit.framework.Assert.
+ *   junit.swingui.TestRunner
+ *   junit.awtui.TestRunner
+ *   junit.textui.TestRunner
+ *   java.lang.reflect.Method.invoke(
+ *   org.apache.tools.ant.
+ * 
+ * Removing all the above will help to make stacktrace more readable. + * + * @author Stephane Bailliez + */ +public class FilterStackFormatter extends FilterFormatter { + + /** the set of matches to look for in a stack trace */ + private final static String[] DEFAULT_TRACE_FILTERS = new String[] { + "junit.framework.TestCase", + "junit.framework.TestResult", + "junit.framework.TestSuite", + "junit.framework.Assert.", // don't filter AssertionFailure + "junit.swingui.TestRunner", + "junit.awtui.TestRunner", + "junit.textui.TestRunner", + "java.lang.reflect.Method.invoke(", + "org.apache.tools.ant." + }; + + /** + * Creates a new FilterStackFormatter + * @param formatter the formatter to be filtered. + */ + public FilterStackFormatter(Formatter formatter){ + super(formatter); + } + + public void testFailed(int status, String testname, String trace) { + StringTokenizer st = new StringTokenizer(trace,"\r\n"); + StringBuffer buf = new StringBuffer(trace.length()); + while ( st.hasMoreTokens() ){ + String line = st.nextToken(); + if ( accept(line) ){ + buf.append(line).append(StringUtils.LINE_SEP); + } + } + super.testFailed(status, testname, buf.toString()); + } + + /** + * Check whether or not the line should be accepted. + * @param the line to be check for acceptance. + * @return true if the line is accepted, false if not. + */ + protected boolean accept(String line){ + for (int i = 0; i < DEFAULT_TRACE_FILTERS.length; i++) { + if (line.indexOf(DEFAULT_TRACE_FILTERS[i]) > 0) { + return false; + } + } + return true; + } + +} diff --git a/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/junit/formatter/Formatter.java b/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/junit/formatter/Formatter.java new file mode 100644 index 000000000..b01cd6efa --- /dev/null +++ b/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/junit/formatter/Formatter.java @@ -0,0 +1,80 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Ant", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.tools.ant.taskdefs.optional.junit.formatter; + +import java.io.OutputStream; + +import org.apache.tools.ant.taskdefs.optional.junit.TestRunListener; + +/** + * + * @author Stephane Bailliez + */ +public interface Formatter extends TestRunListener { + /** + * Sets the stream the formatter is supposed to write its results to. + */ + public void setOutput( OutputStream out ); + + /** + * This is what the test has written to System.out + */ + public void setSystemOutput( String out ); + + /** + * This is what the test has written to System.err + */ + public void setSystemError( String err ); + +} diff --git a/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/junit/formatter/SummaryFormatter.java b/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/junit/formatter/SummaryFormatter.java new file mode 100644 index 000000000..8978e6f3f --- /dev/null +++ b/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/junit/formatter/SummaryFormatter.java @@ -0,0 +1,87 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Ant", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.tools.ant.taskdefs.optional.junit.formatter; + +import java.text.MessageFormat; + +/** + * Display a summary message at the end of a testsuite stating + * runs, failures, errors, and elapsed time. + * + * @author Stephane Bailliez + */ +public class SummaryFormatter extends BaseFormatter { + + protected MessageFormat mf = new MessageFormat( + "Tests run: {0, number, integer}" + + ", Failures: {1, number, integer}" + + ", Errors: {2, number, integer}" + + ", Time elapsed: {3, number, integer} sec"); + + protected void finished(long elapsedtime) { + writer.print("Testsuite: "); + writer.println(); + String line = mf.format(new Object[]{ + new Integer(runCount), + new Integer(failureCount), + new Integer(errorCount), + new Long(elapsedtime / 1000) + }); + writer.print(line); + writer.println(); + writer.println(); + close(); + } + +} diff --git a/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/junit/formatter/XMLFormatter.java b/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/junit/formatter/XMLFormatter.java new file mode 100644 index 000000000..2b595b7fe --- /dev/null +++ b/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/junit/formatter/XMLFormatter.java @@ -0,0 +1,223 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Ant", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.tools.ant.taskdefs.optional.junit.formatter; + +import java.util.Hashtable; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Text; + +import org.apache.tools.ant.taskdefs.optional.junit.TestRunListener; + +/** + * + * @author Stephane Bailliez + */ +public class XMLFormatter extends BaseFormatter { + + /** the testsuites element for the aggregate document */ + public final static String TESTSUITES = "testsuites"; + + /** the testsuite element */ + public final static String TESTSUITE = "testsuite"; + + /** the testcase element */ + public final static String TESTCASE = "testcase"; + + /** the error element */ + public final static String ERROR = "error"; + + /** the failure element */ + public final static String FAILURE = "failure"; + + /** the system-err element */ + public final static String SYSTEM_ERR = "system-err"; + + /** the system-out element */ + public final static String SYSTEM_OUT = "system-out"; + + /** package attribute for the aggregate document */ + public final static String ATTR_PACKAGE = "package"; + + /** name attribute for property, testcase and testsuite elements */ + public final static String ATTR_NAME = "name"; + + /** time attribute for testcase and testsuite elements */ + public final static String ATTR_TIME = "time"; + + /** errors attribute for testsuite elements */ + public final static String ATTR_ERRORS = "errors"; + + /** failures attribute for testsuite elements */ + public final static String ATTR_FAILURES = "failures"; + + /** tests attribute for testsuite elements */ + public final static String ATTR_TESTS = "tests"; + + /** type attribute for failure and error elements */ + public final static String ATTR_TYPE = "type"; + + /** message attribute for failure elements */ + public final static String ATTR_MESSAGE = "message"; + + /** the properties element */ + public final static String PROPERTIES = "properties"; + + /** the property element */ + public final static String PROPERTY = "property"; + + /** value attribute for property elements */ + public final static String ATTR_VALUE = "value"; + + /** The XML document. */ + private Document doc; + + /** The wrapper for the whole testsuite. */ + private Element rootElement; + + /** Element for the current test. */ + private Hashtable testElements = new Hashtable(); + + /** Timing helper. */ + private Hashtable testStarts = new Hashtable(); + + public void testStarted(String testname) { + //@fixme, eh, a testname only can obviouslly be a duplicate... + testStarts.put(testname, new Long(System.currentTimeMillis())); + Element currentTest = doc.createElement(TESTCASE); + currentTest.setAttribute(ATTR_NAME, testname); + rootElement.appendChild(currentTest); + testElements.put(testname, currentTest); + super.testStarted(testname); + } + + public void testEnded(String testname) { + Element currentTest = (Element) testElements.get(testname); + // with a TestSetup, startTest and endTest are not called. + if (currentTest == null){ + testStarted(testname); + currentTest = (Element) testElements.get(testname); + } + Long l = (Long) testStarts.get(testname); + float time = ((System.currentTimeMillis()-l.longValue()) / 1000.0f); + currentTest.setAttribute(ATTR_TIME, Float.toString(time)); + super.testEnded(testname); + // remove the test objects + testStarts.remove(testname); + testElements.remove(testname); + } + + public void testFailed(int status, String testname, String trace) { + if (testname != null) { + testEnded(testname); + } + String type = status == STATUS_FAILURE ? FAILURE : ERROR; + Element nested = doc.createElement(type); + Element currentTest = null; + if (testname != null) { + currentTest = (Element) testElements.get(testname); + } else { + currentTest = rootElement; + } + + currentTest.appendChild(nested); + + String[] args = parseFirstLine(trace); + if (args[1] != null && args[1].length() > 0) { + nested.setAttribute(ATTR_MESSAGE, args[1]); + } + nested.setAttribute(ATTR_TYPE, args[0]); + Text text = doc.createTextNode(trace); + nested.appendChild(text); + super.testFailed(status, testname, trace); + } + + public void testRunStarted(int testcount) { + super.testRunStarted(testcount); + } + + public void testRunEnded(long elapsedtime) { + super.testRunEnded(elapsedtime); + } + + public void testRunStopped(long elapsedtime) { + super.testRunStopped(elapsedtime); + } + + private static DocumentBuilder getDocumentBuilder() { + try { + return DocumentBuilderFactory.newInstance().newDocumentBuilder(); + } catch(Exception exc) { + throw new ExceptionInInitializerError(exc); + } + } + + protected static String[] parseFirstLine(String trace){ + int pos = trace.indexOf('\n'); + if (pos == -1){ + return new String[]{ trace, ""}; + } + String line = trace.substring(0, pos); + pos = line.indexOf(':'); + if (pos != -1){ + String classname = line.substring(0, pos).trim(); + String message = line.substring(pos + 1).trim(); + return new String[]{ classname, message }; + } + return new String[]{ trace, ""}; + } +}