--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tsrc/qtestutils/src/testrunner.cpp Fri Sep 17 08:28:43 2010 +0300
@@ -0,0 +1,217 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#include "testrunner.h"
+#include <QtTest/QtTest>
+#include <QDir>
+#include <stdio.h>
+
+const char testCaseElement[] = "TestCase";
+const char testFunctionElement[] = "TestFunction";
+const char incidentElement[] = "Incident";
+const char descriptionElement[] = "Description";
+const char nameAttr[] = "name";
+const char typeAttr[] = "type";
+const char fileAttr[] = "file";
+const char lineAttr[] = "line";
+const char attrValueFail[] = "fail";
+
+
+TestRunner::TestRunner(const QString& name, const QString& combinedOutputFileName)
+: mTestCount(0),
+ mParsingIncidentElement(false),
+ mParsingDescriptionElement(false),
+ mCurrentTestFailed(false),
+ mCurrentTestFailureLine(0),
+ mCombinedOutputFileName(combinedOutputFileName)
+{
+ mTestRunParams.append(name);
+ mTestRunParams.append("-xml");
+ mTestRunParams.append("-o");
+ mHomeDir = QDir::homePath();
+ mTestRunParams.append(QString()); // Initial result file name
+
+ if (!mHomeDir.endsWith(QString::fromAscii("/")))
+ mHomeDir += QString::fromAscii("/");
+}
+
+TestRunner::~TestRunner()
+{
+}
+
+int TestRunner::runTests(QObject& testObject)
+{
+ QString className(testObject.metaObject()->className());
+ printf("Running tests for %s ... ", className.toUtf8().data());
+ QString resultFileName = mHomeDir + className + ".xml";
+ mTestRunParams.replace(mTestRunParams.count()-1,resultFileName);
+ int errorsBefore = mErrors.count();
+ int error = QTest::qExec(&testObject, mTestRunParams);
+ parse(resultFileName);
+ mResultFiles.append(resultFileName);
+ printf("Failures: %d\n",mErrors.count()-errorsBefore);
+ fflush(stdout);
+ return error;
+}
+
+void TestRunner::printResults()
+{
+ printf("\nTests executed: %d\n",mTestCount);
+ if (mErrors.count() > 0) {
+ printf("Failures (%d):\n", mErrors.count());
+ foreach(QString error, mErrors) {
+ printf("\n%s", error.toUtf8().data());
+ }
+ printf("\n");
+ } else {
+ printf("All passed.\n\n");
+ }
+ fflush(stdout);
+
+ combineResults();
+}
+
+void TestRunner::parse(const QString& fileName)
+{
+ QFile file(fileName);
+ QXmlInputSource inputSource(&file);
+ QXmlSimpleReader reader;
+ reader.setContentHandler(this);
+ reader.parse(inputSource);
+}
+
+bool TestRunner::startElement(
+ const QString& /*namespaceURI*/,
+ const QString& /*localName*/,
+ const QString& qName,
+ const QXmlAttributes& atts)
+{
+ if (qName == QString::fromAscii(testFunctionElement)) {
+ mTestCount++;
+ mCurrentTestName = atts.value(QString::fromAscii(nameAttr));
+ return true;
+ }
+ if (qName == QString::fromAscii(incidentElement)) {
+ mParsingIncidentElement = true;
+ if (atts.value(QString::fromAscii(typeAttr)) == QString::fromAscii(attrValueFail)) {
+ mCurrentTestFailed = true;
+ mCurrentTestFile = atts.value(QString::fromAscii(fileAttr));
+ mCurrentTestFailureLine = atts.value(QString::fromAscii(lineAttr)).toInt();
+ }
+ return true;
+ }
+ mParsingDescriptionElement =
+ (qName == QString::fromAscii(descriptionElement));
+ return true;
+}
+
+bool TestRunner::endElement(
+ const QString& /*namespaceURI*/,
+ const QString& /*localName*/,
+ const QString& qName)
+{
+ if (qName == QString::fromAscii(incidentElement)) {
+ mParsingIncidentElement = false;
+ mCurrentTestFailed = false;
+ return true;
+ }
+ if (qName == QString::fromAscii(descriptionElement)) {
+ mParsingDescriptionElement = false;
+ }
+ return true;
+}
+
+bool TestRunner::characters(const QString& ch)
+{
+ if (mParsingIncidentElement &&
+ mParsingDescriptionElement &&
+ mCurrentTestFailed) {
+ QByteArray testResult = mCurrentTestName.toAscii() + " failed:\n";
+ testResult += "File: ";
+ testResult += mCurrentTestFile.toAscii();
+ testResult += "\n";
+ testResult += "Line: ";
+ testResult += QByteArray::number(mCurrentTestFailureLine);
+ testResult += "\n";
+ testResult += "Reason: ";
+ testResult += ch.toAscii();
+ testResult += "\n";
+ mErrors.append(QString::fromAscii(testResult.data()));
+ }
+ return true;
+}
+
+void TestRunner::combineResults()
+{
+ if ( mCombinedOutputFileName.isEmpty() ){
+ return;
+ }
+ if ( !mCombinedOutputFileName.contains(QString::fromAscii("/")) ){
+ mCombinedOutputFileName.prepend( mHomeDir );
+ }
+ QFile file(mCombinedOutputFileName);
+ if (!file.open(QIODevice::WriteOnly)){
+ return;
+ }
+
+ QXmlStreamWriter writer(&file);
+ writer.setAutoFormatting(true);
+ writer.writeStartDocument();
+ QString caseName;
+ foreach ( QString resultFile, mResultFiles ){
+ QFile readFile( resultFile );
+ if ( resultFile != mCombinedOutputFileName && readFile.open(QIODevice::ReadOnly) ){
+ QXmlStreamReader reader(&readFile);
+ appendToXml(writer, reader, caseName);
+ readFile.close();
+ }
+ }
+ writer.writeEndDocument();
+ file.close();
+}
+
+void TestRunner::appendToXml(QXmlStreamWriter& writer, QXmlStreamReader& reader, QString& caseName)
+{
+ while (!reader.atEnd()) {
+ QXmlStreamReader::TokenType type = reader.readNext();
+ if ( type == QXmlStreamReader::StartDocument ||
+ type == QXmlStreamReader::EndDocument ){
+ // Ignored
+ } else if ( reader.name() == testCaseElement ){
+ if ( type == QXmlStreamReader::StartElement ){
+ QString tempCaseName = reader.attributes().value(nameAttr).toString();
+ if ( caseName.isEmpty() && type == QXmlStreamReader::StartElement){
+ writer.writeStartElement(testCaseElement);
+ writer.writeAttribute(nameAttr, mTestRunParams.at(0));
+ }
+ caseName = tempCaseName;
+ }
+ } else if ( type == QXmlStreamReader::StartElement ) {
+ if ( reader.name() == testFunctionElement ){
+ QString tempFuncName = reader.attributes().value(nameAttr).toString();
+ if ( !tempFuncName.isEmpty() ){
+ writer.writeStartElement(testFunctionElement);
+ writer.writeAttribute(nameAttr, caseName + "::" + tempFuncName);
+ }
+ } else {
+ writer.writeCurrentToken( reader );
+ }
+ } else {
+ writer.writeCurrentToken( reader );
+ }
+ }
+}