blob: 29c64831275f3d1c7f0041885673c7d8703dee69 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2007, 2016 IBM Corporation and others.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.dltk.internal.testing.model;
import java.io.IOException;
import org.eclipse.core.runtime.Assert;
import org.eclipse.dltk.core.IScriptProject;
import org.eclipse.dltk.testing.ITestSession;
import org.eclipse.dltk.testing.model.ITestElement;
import org.eclipse.dltk.testing.model.ITestElement.FailureTrace;
import org.eclipse.dltk.testing.model.ITestElement.ProgressState;
import org.eclipse.dltk.testing.model.ITestElement.Result;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.DTDHandler;
import org.xml.sax.EntityResolver;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.AttributesImpl;
import java.text.DecimalFormat;
import java.text.NumberFormat;
public class TestRunSessionSerializer implements XMLReader {
private static final String EMPTY= ""; //$NON-NLS-1$
private static final String CDATA= "CDATA"; //$NON-NLS-1$
private static final Attributes NO_ATTS= new AttributesImpl();
private final TestRunSession fTestRunSession;
private ContentHandler fHandler;
private ErrorHandler fErrorHandler;
private final NumberFormat timeFormat= new DecimalFormat("0.0##"); //$NON-NLS-1$ // not localized, parseable by Double.parseDouble(..)
/**
* @param testRunSession the test run session to serialize
*/
public TestRunSessionSerializer(TestRunSession testRunSession) {
Assert.isNotNull(testRunSession);
fTestRunSession= testRunSession;
}
@Override
public void parse(InputSource input) throws IOException, SAXException {
if (fHandler == null)
throw new SAXException("ContentHandler missing"); //$NON-NLS-1$
fHandler.startDocument();
handleTestRun(fTestRunSession);
fHandler.endDocument();
}
private void handleTestRun(ITestSession testRunSession) throws SAXException {
AttributesImpl atts= new AttributesImpl();
addCDATA(atts, IXMLTags.ATTR_NAME, fTestRunSession.getTestRunName());
IScriptProject project= fTestRunSession.getLaunchedProject();
if (project != null)
addCDATA(atts, IXMLTags.ATTR_PROJECT, project.getElementName());
addCDATA(atts, IXMLTags.ATTR_TESTS, fTestRunSession.getTotalCount());
addCDATA(atts, IXMLTags.ATTR_STARTED, fTestRunSession.getStartedCount());
addCDATA(atts, IXMLTags.ATTR_FAILURES, fTestRunSession.getFailureCount());
addCDATA(atts, IXMLTags.ATTR_ERRORS, fTestRunSession.getErrorCount());
addCDATA(atts, IXMLTags.ATTR_IGNORED, fTestRunSession.getIgnoredCount());
startElement(IXMLTags.NODE_TESTRUN, atts);
TestRoot testRoot= fTestRunSession.getTestRoot();
ITestElement[] topSuites= testRoot.getChildren();
for (int i= 0; i < topSuites.length; i++) {
handleTestElement(topSuites[i]);
}
endElement(IXMLTags.NODE_TESTRUN);
}
private void handleTestElement(ITestElement testElement) throws SAXException {
if (testElement instanceof TestCategoryElement) {
TestCategoryElement category = (TestCategoryElement) testElement;
AttributesImpl atts = new AttributesImpl();
addCDATA(atts, IXMLTags.ATTR_ID, category.getId());
addCDATA(atts, IXMLTags.ATTR_NAME, category.getCategoryName());
startElement(IXMLTags.NODE_CATEGORY, atts);
ITestElement[] children = category.getChildren();
for (int i = 0; i < children.length; i++) {
handleTestElement(children[i]);
}
endElement(IXMLTags.NODE_CATEGORY);
}
else if (testElement instanceof TestSuiteElement) {
TestSuiteElement testSuiteElement= (TestSuiteElement) testElement;
AttributesImpl atts= new AttributesImpl();
addCDATA(atts, IXMLTags.ATTR_NAME, testSuiteElement.getSuiteTypeName());
if (! Double.isNaN(testSuiteElement.getElapsedTimeInSeconds()))
addCDATA(atts, IXMLTags.ATTR_TIME, timeFormat.format(testSuiteElement.getElapsedTimeInSeconds()));
if (testElement.getProgressState() != ProgressState.COMPLETED || testElement.getTestResult(false) != Result.UNDEFINED)
addCDATA(atts, IXMLTags.ATTR_INCOMPLETE, Boolean.TRUE.toString());
startElement(IXMLTags.NODE_TESTSUITE, atts);
addFailure(testElement);
ITestElement[] children= testSuiteElement.getChildren();
for (int i= 0; i < children.length; i++) {
handleTestElement(children[i]);
}
endElement(IXMLTags.NODE_TESTSUITE);
} else if (testElement instanceof TestCaseElement) {
TestCaseElement testCaseElement= (TestCaseElement) testElement;
AttributesImpl atts= new AttributesImpl();
addCDATA(atts, IXMLTags.ATTR_NAME, testCaseElement.getTestName());
if (! Double.isNaN(testCaseElement.getElapsedTimeInSeconds()))
addCDATA(atts, IXMLTags.ATTR_TIME, timeFormat.format(testCaseElement.getElapsedTimeInSeconds()));
if (testElement.getProgressState() != ProgressState.COMPLETED)
addCDATA(atts, IXMLTags.ATTR_INCOMPLETE, Boolean.TRUE.toString());
if (testCaseElement.isIgnored())
addCDATA(atts, IXMLTags.ATTR_IGNORED, Boolean.TRUE.toString());
startElement(IXMLTags.NODE_TESTCASE, atts);
addFailure(testElement);
endElement(IXMLTags.NODE_TESTCASE);
} else {
throw new IllegalStateException(String.valueOf(testElement));
}
}
private void addFailure(ITestElement testElement) throws SAXException {
FailureTrace failureTrace= testElement.getFailureTrace();
if (failureTrace != null) {
AttributesImpl failureAtts= new AttributesImpl();
// addCDATA(failureAtts, IXMLTags.ATTR_MESSAGE, xx);
// addCDATA(failureAtts, IXMLTags.ATTR_TYPE, xx);
String failureKind= testElement.getTestResult(false) == Result.ERROR ? IXMLTags.NODE_ERROR : IXMLTags.NODE_FAILURE;
startElement(failureKind, failureAtts);
String expected= failureTrace.getExpected();
String actual= failureTrace.getActual();
if (expected != null) {
startElement(IXMLTags.NODE_EXPECTED, NO_ATTS);
fHandler.characters(expected.toCharArray(), 0, expected.length());
endElement(IXMLTags.NODE_EXPECTED);
}
if (actual != null) {
startElement(IXMLTags.NODE_ACTUAL, NO_ATTS);
fHandler.characters(actual.toCharArray(), 0, actual.length());
endElement(IXMLTags.NODE_ACTUAL);
}
String trace= failureTrace.getTrace();
fHandler.characters(trace.toCharArray(), 0, trace.length());
endElement(failureKind);
}
}
private void startElement(String name, Attributes atts) throws SAXException {
fHandler.startElement(EMPTY, name, name, atts);
}
private void endElement(String name) throws SAXException {
fHandler.endElement(EMPTY, name, name);
}
private static void addCDATA(AttributesImpl atts, String name, int value) {
addCDATA(atts, name, Integer.toString(value));
}
private static void addCDATA(AttributesImpl atts, String name, String value) {
atts.addAttribute(EMPTY, EMPTY, name, CDATA, value);
}
@Override
public void setContentHandler(ContentHandler handler) {
this.fHandler= handler;
}
@Override
public ContentHandler getContentHandler() {
return fHandler;
}
@Override
public void setErrorHandler(ErrorHandler handler) {
fErrorHandler= handler;
}
@Override
public ErrorHandler getErrorHandler() {
return fErrorHandler;
}
// ignored:
@Override
public void parse(String systemId) throws IOException, SAXException {
}
@Override
public void setDTDHandler(DTDHandler handler) {
}
@Override
public DTDHandler getDTDHandler() {
return null;
}
@Override
public void setEntityResolver(EntityResolver resolver) {
}
@Override
public EntityResolver getEntityResolver() {
return null;
}
@Override
public void setProperty(java.lang.String name, java.lang.Object value) {
}
@Override
public Object getProperty(java.lang.String name) {
return null;
}
@Override
public void setFeature(java.lang.String name, boolean value) {
}
@Override
public boolean getFeature(java.lang.String name) {
return false;
}
}