/* Copyright (C) 2009 Mobile Sorcery AB This program is free software; you can redistribute it and/or modify it under the terms of the Eclipse Public License v1.0. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Eclipse Public License v1.0 for more details. You should have received a copy of the Eclipse Public License v1.0 along with this program. It is also available at http://www.eclipse.org/legal/epl-v10.html */ /** * */ package com.mobilesorcery.sdk.testing.emulator; import java.io.InputStream; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.xml.sax.Attributes; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.XMLReader; import org.xml.sax.helpers.DefaultHandler; import com.mobilesorcery.sdk.testing.AssertionFailed; import com.mobilesorcery.sdk.testing.ITestSession; import com.mobilesorcery.sdk.testing.ITestSuite; import com.mobilesorcery.sdk.testing.Test; import com.mobilesorcery.sdk.testing.TestResult; import com.mobilesorcery.sdk.testing.TestSession; import com.mobilesorcery.sdk.testing.TestSuite; class XMLTestReportParser extends DefaultHandler { /** * */ private final EmulatorTestSession emulatorTestSession; final static String FILE_ATTR = "file"; final static String LINE_ATTR = "line"; //final static String DEFINE_TEST = "define-test"; //final static String DEFINE_SUITE = "define-suite"; final static String TEST_RESULT = "test"; final static String SUITE_RESULT = "suite"; final static String NAME_ATTR = "name"; final static String TIME = "time"; final static String ELAPSED_ATTR = "elapsed"; final static String LOCATION = "location"; final static String EXPECTED = "expected"; final static String ACTUAL = "actual"; private ITestSession session; private ITestSuite currentSuite; private StringBuffer currentTestMessage; private Test currentTest; private int currentTestTime; private String currentTag = null; private AssertionFailed currentAssertionFailed; public XMLTestReportParser(EmulatorTestSession emulatorTestSession, TestSession session) { this.emulatorTestSession = emulatorTestSession; this.session = session; } public void parse(final InputStream input) { Thread thread = new Thread(new Runnable() { public void run() { try { SAXParserFactory spf = SAXParserFactory.newInstance(); spf.setValidating(false); spf.setNamespaceAware(true); SAXParser sp = spf.newSAXParser(); final XMLReader xr = sp.getXMLReader(); xr.setContentHandler(XMLTestReportParser.this); xr.parse(new InputSource(input)); } catch (Exception e) { XMLTestReportParser.this.emulatorTestSession.reportSessionError(e); } } }); thread.start(); } public void startElement(String uri, String name, String qName, Attributes atts) { currentTag = name; String nameAttr = atts.getValue(NAME_ATTR); if (SUITE_RESULT.equals(name)) { currentSuite = new TestSuite(nameAttr); session.addTest(currentSuite); // No test result is reported for suites, but for individual tests } else if (TEST_RESULT.equals(name)) { Test test = new Test(nameAttr); currentTest = test; currentTestMessage = new StringBuffer(); currentTestTime = 0; if (currentSuite == null) { throw new IllegalStateException("Internal error: A test must belong to a suite"); } currentSuite.addTest(test); session.getTestResult().startTest(test); } else if (LOCATION.equals(name)) { String line = atts.getValue(LINE_ATTR); String file = atts.getValue(FILE_ATTR); session.getTestResult().setProperty(currentTest, LINE_ATTR, line); session.getTestResult().setProperty(currentTest, FILE_ATTR, file); } else if (TIME.equals(name)) { String testTimeStr = atts.getValue(ELAPSED_ATTR); try { currentTestTime = testTimeStr == null ? TestResult.TIME_UNDEFINED : Integer.parseInt(testTimeStr); } catch (NumberFormatException e) { currentTestTime = TestResult.TIME_UNDEFINED; } } } public void endElement(String uri, String name, String qName) throws SAXException { if (TEST_RESULT.equals(name)) { session.getTestResult().endTest(currentTest, currentTestTime); if (currentAssertionFailed != null) { session.getTestResult().addFailure(currentTest, currentAssertionFailed); } else if (currentTestMessage != null && currentTestMessage.toString().trim().startsWith("failed:")) { session.getTestResult().addFailure(currentTest, currentTestMessage.toString()); } } } public void characters(char ch[], int start, int length) { if (EXPECTED.equals(currentTag)) { StringBuffer currentExpected = new StringBuffer(); if (currentAssertionFailed != null) { currentExpected.append(currentAssertionFailed.expected()); } currentExpected.append(ch, start, length); currentAssertionFailed = new AssertionFailed(currentExpected, currentAssertionFailed == null ? "" : currentAssertionFailed.actual()); } else if (ACTUAL.equals(currentTag)) { StringBuffer currentActual = new StringBuffer(); if (currentAssertionFailed != null) { currentActual.append(currentAssertionFailed.actual()); } currentActual.append(ch, start, length); currentAssertionFailed = new AssertionFailed(currentAssertionFailed == null ? "" : currentAssertionFailed.expected(), currentActual); } else if (TEST_RESULT.equals(currentTag)) { currentTestMessage.append(ch, start, length); } } }