diff --git a/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/rjunit/formatter/FilterStackFormatter.java b/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/rjunit/formatter/FilterStackFormatter.java
index 4ee0cbb99..253de08a3 100644
--- a/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/rjunit/formatter/FilterStackFormatter.java
+++ b/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/rjunit/formatter/FilterStackFormatter.java
@@ -92,6 +92,8 @@ public class FilterStackFormatter extends FilterFormatter {
"org.apache.tools.ant."
};
+ private final String[] filters = getFilters();
+
/**
* Creates a new FilterStackFormatter
* @param formatter the formatter to be filtered.
@@ -129,12 +131,31 @@ public class FilterStackFormatter extends FilterFormatter {
* @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) {
+ for (int i = 0; i < filters.length; i++) {
+ if (line.indexOf(filters[i]) > 0) {
return false;
}
}
return true;
}
+ /**
+ * @return the filters to use for this
+ */
+ protected static String[] getFilters(){
+ // @fixme hack for now, need something better.
+ // using configuration properties ?
+ String filters = System.getProperty("ant.rjunit.stacktrace.filters");
+ if (filters == null){
+ return DEFAULT_TRACE_FILTERS;
+ }
+ StringTokenizer st = new StringTokenizer(filters, ",");
+ String[] results = new String[ st.countTokens() ];
+ int i = 0;
+ while (st.hasMoreTokens()){
+ results[i++] = st.nextToken();
+ }
+ return results;
+ }
+
}
diff --git a/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/rjunit/formatter/Resources.properties b/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/rjunit/formatter/Resources.properties
index d4a1e4a4b..de49af38c 100644
--- a/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/rjunit/formatter/Resources.properties
+++ b/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/rjunit/formatter/Resources.properties
@@ -1,6 +1,7 @@
# Summary formatter
-suite.summary.msg = TestSuite: {0}\nTests run: {1, number, integer}, Failures: {2, number, integer}, Errors: {3, number, integer}, Time elapsed: {4, number, integer} sec
-run.summary.msg=Tests run: {0, number, integer}, Failures: {1, number, integer}, Errors: {2, number, integer}, Time elapsed: {3, number, integer} sec
+suite.summary.msg = TestSuite: {0}\nTests run: {1, number, integer}, Failures: {2, number, integer}, Errors: {3, number, integer}, Time elapsed: {4, number, integer}s\n
+run.summary.msg=Sullary Tests run: {0, number, integer}, Failures: {1, number, integer}, Errors: {2, number, integer}, Time elapsed: {3, number, integer}s
+
# Brief formatter
brief.status-error.msg = TestCase: {0}\tCaused an ERROR\n{1}\n
brief.status-failure.msg = TestCase: {0}\tFAILED\n{1}\n
diff --git a/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/rjunit/formatter/XMLFormatter.java b/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/rjunit/formatter/XMLFormatter.java
index ea4cbed7d..c0addef1f 100644
--- a/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/rjunit/formatter/XMLFormatter.java
+++ b/proposal/sandbox/junit/src/main/org/apache/tools/ant/taskdefs/optional/rjunit/formatter/XMLFormatter.java
@@ -53,8 +53,10 @@
*/
package org.apache.tools.ant.taskdefs.optional.rjunit.formatter;
-import java.util.Hashtable;
import java.io.IOException;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Properties;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
@@ -62,15 +64,28 @@ import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Text;
-import org.apache.tools.ant.util.DOMElementWriter;
import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.taskdefs.optional.rjunit.JUnitHelper;
import org.apache.tools.ant.taskdefs.optional.rjunit.remote.TestRunEvent;
+import org.apache.tools.ant.taskdefs.optional.rjunit.remote.TestSummary;
+import org.apache.tools.ant.util.DOMElementWriter;
/**
* XML Formatter. Due to the nature of the XML we are forced to store
* everything in memory until it is finished. It might be resource
* intensive when running lots of testcases.
*
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
* @author Stephane Bailliez
*/
public class XMLFormatter extends BaseStreamFormatter {
@@ -133,42 +148,93 @@ public class XMLFormatter extends BaseStreamFormatter {
private Document doc = getDocumentBuilder().newDocument();
/** The wrapper for the whole testsuite. */
- private Element rootElement = doc.createElement(TESTSUITE);
+ private Element rootElement = doc.createElement(TESTSUITES);
+
+ private Element lastTestElement = null;
+ private TestRunEvent lastTestEvent = null;
+ private Element lastSuiteElement = null;
- /** Element for the current test. */
- private Hashtable testElements = new Hashtable();
+ public void onSuiteStarted(TestRunEvent evt) {
+ String fullclassname = evt.getName();
+ int pos = fullclassname.lastIndexOf('.');
- /** Timing helper. */
- private Hashtable testStarts = new Hashtable();
+ // a missing . might imply no package at all. Don't get fooled.
+ String pkgName = (pos == -1) ? "" : fullclassname.substring(0, pos);
+ String classname = (pos == -1) ? fullclassname : fullclassname.substring(pos + 1);
+
+ Element suite = doc.createElement(TESTSUITE);
+ suite.setAttribute(ATTR_NAME, classname);
+ suite.setAttribute(ATTR_PACKAGE, pkgName);
+ rootElement.appendChild(suite);
+ lastSuiteElement = suite;
+ }
+
+ public void onSuiteEnded(TestRunEvent evt) {
+ Element suite = lastSuiteElement;
+ TestSummary summary = evt.getSummary();
+ suite.setAttribute(ATTR_TIME, String.valueOf(summary.elapsedTime()/1000.0f));
+ suite.setAttribute(ATTR_TESTS, String.valueOf(summary.runCount()));
+ suite.setAttribute(ATTR_FAILURES, String.valueOf(summary.failureCount()));
+ suite.setAttribute(ATTR_ERRORS, String.valueOf(summary.errorCount()));
+ lastSuiteElement = null;
+ }
+
+ public void onRunEnded(TestRunEvent evt) {
+ // Output properties
+ Element propsElement = doc.createElement(PROPERTIES);
+ rootElement.appendChild(propsElement);
+ Properties props = evt.getProperties();
+ if (props != null) {
+ Enumeration e = props.propertyNames();
+ while (e.hasMoreElements()) {
+ String name = (String) e.nextElement();
+ Element propElement = doc.createElement(PROPERTY);
+ propElement.setAttribute(ATTR_NAME, name);
+ propElement.setAttribute(ATTR_VALUE, props.getProperty(name));
+ propsElement.appendChild(propElement);
+ }
+ }
+ close();
+ }
+
+ public void onRunStarted(TestRunEvent evt) {
+ //
+ }
+
+ public void onRunStopped(TestRunEvent evt) {
+ // add a stop attribute ?
+ onRunEnded(evt);
+ }
public void onTestStarted(TestRunEvent evt) {
- //@fixme, eh, a testname only can obviouslly be a duplicate...
- testStarts.put(evt.getName(), evt);
- Element currentTest = doc.createElement(TESTCASE);
- currentTest.setAttribute(ATTR_NAME, evt.getName());
- rootElement.appendChild(currentTest);
- testElements.put(evt.getName(), currentTest);
- //removeEvent(evt);
+ Element test = doc.createElement(TESTCASE);
+ String name = JUnitHelper.getTestName(evt.getName());
+ test.setAttribute(ATTR_NAME, name);
+ String suiteName = JUnitHelper.getSuiteName(evt.getName());
+ lastSuiteElement.appendChild(test);
+ lastTestElement = test;
+ lastTestEvent = evt;
}
public void onTestEnded(TestRunEvent evt) {
- Element currentTest = (Element) testElements.get(evt.getName());
// with a TestSetup, startTest and endTest are not called.
- if (currentTest == null) {
+ if (lastTestEvent == null) {
onTestStarted(evt);
- currentTest = (Element) testElements.get(evt.getName());
}
- TestRunEvent start = (TestRunEvent)testStarts.get(evt.getName());
- float time = ((evt.getTimeStamp() - start.getTimeStamp()) / 1000.0f);
- currentTest.setAttribute(ATTR_TIME, Float.toString(time));
- removeEvent(evt);
+ float time = (evt.getTimeStamp() - lastTestEvent.getTimeStamp()) / 1000.0f;
+ lastTestElement.setAttribute(ATTR_TIME, Float.toString(time));
+ lastTestElement = null;
+ lastTestEvent = null;
+ }
+
+ public void onTestError(TestRunEvent evt) {
+ onTestFailure(evt);
}
public void onTestFailure(TestRunEvent evt) {
String type = evt.getType() == TestRunEvent.TEST_FAILURE ? FAILURE : ERROR;
Element nested = doc.createElement(type);
- Element currentTest = (Element) testElements.get(evt.getName());
- currentTest.appendChild(nested);
+ lastTestElement.appendChild(nested);
String[] args = parseFirstLine(evt.getStackTrace());
if (args[1] != null && args[1].length() > 0) {
@@ -177,12 +243,7 @@ public class XMLFormatter extends BaseStreamFormatter {
nested.setAttribute(ATTR_TYPE, args[0]);
Text text = doc.createTextNode(evt.getStackTrace());
nested.appendChild(text);
- removeEvent(evt);
- }
-
- protected void removeEvent(TestRunEvent evt){
- testStarts.remove(evt.getName());
- testElements.remove(evt.getName());
+ onTestEnded(evt);
}
protected void close() {
@@ -191,7 +252,7 @@ public class XMLFormatter extends BaseStreamFormatter {
getWriter().println("");
try {
domWriter.write(rootElement, getWriter(), 0, " ");
- } catch (IOException e){
+ } catch (IOException e) {
throw new BuildException(e);
} finally {
super.close();
@@ -212,7 +273,7 @@ public class XMLFormatter extends BaseStreamFormatter {
return new String[]{trace, ""};
}
String line = trace.substring(0, pos);
- pos = line.indexOf(':');
+ pos = line.indexOf(": ");
if (pos != -1) {
String classname = line.substring(0, pos).trim();
String message = line.substring(pos + 1).trim();