001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.nbbuild;
043:
044: import java.io.File;
045: import java.io.FileOutputStream;
046: import java.io.IOException;
047: import java.io.OutputStream;
048: import java.util.Map;
049: import org.apache.tools.ant.BuildException;
050: import org.apache.tools.ant.Task;
051: import org.w3c.dom.Document;
052: import org.w3c.dom.Element;
053:
054: /**
055: * Utility permitting Ant tasks to write out JUnit-format reports rather than aborting the build.
056: */
057: public class JUnitReportWriter {
058:
059: private JUnitReportWriter() {
060: }
061:
062: /**
063: * Possibly write out a report.
064: * @param task the Ant task doing the work (will be used as a class name for the "test", among other purposes)
065: * @param reportFile an XML file to create with the report; if null, and there were some failures,
066: * throw a {@link BuildException} instead
067: * @param pseudoTests the results of the "tests", as a map from test name (e.g. <samp>testSomething</samp>)
068: * to either null (success) or a (possibly multiline) failure message;
069: * use of a {@link java.util.LinkedHashMap} to preserve order is recommended
070: * @throws BuildException in case <code>reportFile</code> was null
071: * and <code>pseudoTests</code> contained some non-null values
072: */
073: public static void writeReport(Task task, File reportFile,
074: Map<String, String> pseudoTests) throws BuildException {
075: if (reportFile == null) {
076: StringBuilder errors = new StringBuilder();
077: for (Map.Entry<String, String> entry : pseudoTests
078: .entrySet()) {
079: String msg = entry.getValue();
080: if (msg != null) {
081: errors.append("\n" + entry.getKey() + ": " + msg);
082: }
083: }
084: if (errors.length() > 0) {
085: throw new BuildException("Some tests failed:" + errors,
086: task.getLocation());
087: } else {
088: task.log("All tests passed");
089: }
090: } else {
091: Document reportDoc = XMLUtil.createDocument("testsuite");
092: Element testsuite = reportDoc.getDocumentElement();
093: int failures = 0;
094: testsuite.setAttribute("errors", "0");
095: testsuite.setAttribute("time", "0.0");
096: testsuite.setAttribute("name", task.getClass().getName()); // http://www.nabble.com/difference-in-junit-publisher-and-ant-junitreport-tf4308604.html#a12265700
097: for (Map.Entry<String, String> entry : pseudoTests
098: .entrySet()) {
099: Element testcase = reportDoc.createElement("testcase");
100: testsuite.appendChild(testcase);
101: testcase.setAttribute("classname", task.getClass()
102: .getName());
103: testcase.setAttribute("name", entry.getKey());
104: testcase.setAttribute("time", "0.0");
105: String msg = entry.getValue();
106: if (msg != null) {
107: failures++;
108: Element failure = reportDoc
109: .createElement("failure");
110: testcase.appendChild(failure);
111: failure.setAttribute("type",
112: "junit.framework.AssertionFailedError");
113: failure.setAttribute("message", msg.replaceFirst(
114: "(?s)\n.*", ""));
115: failure.appendChild(reportDoc.createTextNode(msg));
116: }
117: }
118: testsuite.setAttribute("failures", Integer
119: .toString(failures));
120: testsuite.setAttribute("tests", Integer
121: .toString(pseudoTests.size()));
122: try {
123: OutputStream os = new FileOutputStream(reportFile);
124: try {
125: XMLUtil.write(reportDoc, os);
126: } finally {
127: os.close();
128: }
129: } catch (IOException x) {
130: throw new BuildException("Could not write "
131: + reportFile + ": " + x, x, task.getLocation());
132: }
133: task.log(reportFile + ": " + failures + " failures out of "
134: + pseudoTests.size() + " tests");
135: }
136: }
137:
138: }
|