From 1cf0f396733095c4b11db973212d4de53bf2f44d Mon Sep 17 00:00:00 2001 From: Rhys Weatherley Date: Mon, 6 Dec 2010 10:48:52 +1000 Subject: Replace TestReport with TestResult --- src/imports/testlib/TestCase.qml | 225 +++++++++++++++++----------- src/imports/testlib/main.cpp | 7 +- src/imports/testlib/testlogger.js | 78 +--------- src/quicktestlib/qdeclarativetest.cpp | 61 ++------ src/quicktestlib/qdeclarativetestreport.cpp | 168 --------------------- src/quicktestlib/qdeclarativetestreport_p.h | 77 ---------- src/quicktestlib/qdeclarativetestresult.cpp | 109 ++++++++------ src/quicktestlib/qdeclarativetestresult_p.h | 11 +- src/quicktestlib/quicktestlib.pro | 2 - 9 files changed, 228 insertions(+), 510 deletions(-) delete mode 100644 src/quicktestlib/qdeclarativetestreport.cpp delete mode 100644 src/quicktestlib/qdeclarativetestreport_p.h diff --git a/src/imports/testlib/TestCase.qml b/src/imports/testlib/TestCase.qml index 61a2ff9..f6a026f 100644 --- a/src/imports/testlib/TestCase.qml +++ b/src/imports/testlib/TestCase.qml @@ -64,156 +64,207 @@ Item { property bool optional: false // Internal private state - property string currentTestCase - property bool expectingFail - property string expectFailMsg property bool prevWhen: true property int testId: -1 + property variant testCaseResult - TestReport { id: reporter } + TestResult { id: results } function fail(msg) { if (!msg) msg = ""; - if (expectingFail) { - TestLogger.log_expect_fail(currentTestCase, expectFailMsg, msg) - throw new Error("QtTest::expect_fail") - } else { - TestLogger.log_fail(currentTestCase, msg) - throw new Error("QtTest::fail") - } - } - - function fail2(msg, msg2) { - if (msg) - fail(msg + ": " + msg2) - else - fail(msg2) + results.fail(msg) + throw new Error("QtTest::fail") } function verify(cond, msg) { - if (!cond) - fail(msg) + if (!msg) + msg = ""; + if (!results.verify(cond, msg)) + throw new Error("QtTest::fail") } function compare(actual, expected, msg) { + var act = actual + var exp = expected + var success = false if (typeof actual == "number" && typeof expected == "number") { // Use a fuzzy compare if the two values are floats if (Math.abs(actual - expected) <= 0.00001) - return + success = true } else if (typeof actual == "object" && typeof expected == "object") { // Does the expected value look like a vector3d? if ("x" in expected && "y" in expected && "z" in expected) { if (Math.abs(actual.x - expected.x) <= 0.00001 && Math.abs(actual.y - expected.y) <= 0.00001 && - Math.abs(actual.z - expected.z) <= 0.00001) - return - fail2(msg, "actual: Qt.vector3d(" + - actual.x + ", " + actual.y + ", " + actual.z + - "), expected: Qt.vector3d(" + - expected.x + ", " + expected.y + ", " + expected.z + - ")") - return + Math.abs(actual.z - expected.z) <= 0.00001) { + success = true + } else { + act = "Qt.vector3d(" + actual.x + ", " + + actual.y + ", " + actual.z + ")" + exp = "Qt.vector3d(" + expected.x + ", " + + expected.y + ", " + expected.z + ")" + } + } else if (actual == expected) { + success = true } - if (actual == expected) - return } else if (actual == expected) { - return + success = true } - fail2(msg, "actual: " + actual + ", expected: " + expected) + if (!msg) + msg = "" + if (!results.compare(success, msg, act, exp)) + throw new Error("QtTest::fail") } function skip(msg) { - TestLogger.log_skip(currentTestCase, msg) + if (!msg) + msg = "" + results.skipSingle(msg) throw new Error("QtTest::skip") } - function expectFail(msg) { - expectingFail = true - expectFailMsg = msg + function skipAll(msg) { + if (!msg) + msg = "" + results.skipAll(msg) + throw new Error("QtTest::skip") } - property variant testCaseResult + function expectFail(tag, msg) { + if (!tag) + tag = "" + if (!msg) + msg = "" + if (!results.expectFail(tag, msg)) + throw new Error("QtTest::expectFail") + } - function runInternal(prop, dataDriven, arg, tag) { - currentTestCase = TestLogger.log_prefixed_name(name, prop) - if (dataDriven && tag) - currentTestCase += " [" + tag + "]" - expectingFail = false - var success = true + function expectFailContinue(tag, msg) { + if (!tag) + tag = "" + if (!msg) + msg = "" + if (!results.expectFailContinue(tag, msg)) + throw new Error("QtTest::expectFail") + } + + function warn(msg) { + if (!msg) + msg = "" + results.warn(msg); + } + + // Functions that can be overridden in subclasses for init/cleanup duties. + function initTestCase() {} + function cleanupTestCase() {} + function init() {} + function cleanup() {} + + function runInternal(prop, arg) { try { testCaseResult = testCase[prop](arg) - if (expectingFail) { - success = false - TestLogger.log_expect_fail_pass(currentTestCase) - } else if (!dataDriven) { - TestLogger.log_pass(currentTestCase) - } } catch (e) { testCaseResult = [] - if (e.message == "QtTest::fail") { - success = false - } else if (e.message.indexOf("QtTest::") != 0) { + if (e.message.indexOf("QtTest::") != 0) { // Test threw an unrecognized exception - fail. - TestLogger.log_fail(currentTestCase, e.message) - success = false + fail(e.message) } } - return success + return !results.dataFailed + } + + function runFunction(prop, arg) { + results.functionType = TestResult.InitFunc + runInternal("init") + if (!results.skipped) { + results.functionType = TestResult.Func + runInternal(prop, arg) + results.functionType = TestResult.CleanupFunc + runInternal("cleanup") + } + results.functionType = TestResult.NoWhere } function run() { - TestLogger.log_start_test(reporter) - var success = true + if (TestLogger.log_start_test()) { + results.reset() + results.testCaseName = name + results.startLogging() + } else { + results.testCaseName = name + } running = true + + // Run the initTestCase function. + results.functionName = "initTestCase" + results.functionType = TestResult.InitFunc + var runTests = true + if (!runInternal("initTestCase")) + runTests = false + results.finishTestFunction() + + // Run the test methods. var testList = [] - for (var prop in testCase) { - if (prop.indexOf("test_") != 0) - continue - var tail = prop.lastIndexOf("_data"); - if (tail != -1 && tail == (prop.length - 5)) - continue - testList.push(prop) + if (runTests) { + for (var prop in testCase) { + if (prop.indexOf("test_") != 0) + continue + var tail = prop.lastIndexOf("_data"); + if (tail != -1 && tail == (prop.length - 5)) + continue + testList.push(prop) + } + testList.sort() } - testList.sort() for (var index in testList) { var prop = testList[index] var datafunc = prop + "_data" + results.functionName = prop if (datafunc in testCase) { - if (runInternal(datafunc, true)) { + results.functionType = TestResult.DataFunc + if (runInternal(datafunc)) { var table = testCaseResult - var successThis = true var haveData = false + results.initTestTable() for (var index in table) { haveData = true var row = table[index] - if (!runInternal(prop, true, row, row.tag)) - successThis = false + if (!row.tag) + row.tag = "row " + index // Must have something + results.dataTag = row.tag + runFunction(prop, row) } if (!haveData) - TestLogger.log_message("WARNING: no data supplied for " + prop + "() by " + datafunc + "()") - if (successThis) { - var prefix; - if (name) - prefix = name + "::" - currentTestCase = prefix + prop + "()" - TestLogger.log_pass(currentTestCase) - } else { - success = false - } - } else { - success = false + results.warn("no data supplied for " + prop + "() by " + datafunc + "()") + results.clearTestTable() } } else { - if (!runInternal(prop, false)) - success = false + runFunction(prop) } + results.finishTestFunction() + results.skipped = false + results.dataTag = "" } - currentTestCase = "" + + // Run the cleanupTestCase function. + results.skipped = false + results.functionName = "cleanupTestCase" + results.functionType = TestResult.CleanupFunc + runInternal("cleanupTestCase") + + // Clean up and exit. running = false completed = true - TestLogger.log_complete_test(testId, reporter) - return success + results.finishTestFunction() + results.functionName = "" + + // Stop if there are no more tests to be run. + if (!TestLogger.log_complete_test(testId)) { + results.stopLogging() + Qt.quit() + } + results.testCaseName = "" } onWhenChanged: { diff --git a/src/imports/testlib/main.cpp b/src/imports/testlib/main.cpp index 3eabbe8..f599d2c 100644 --- a/src/imports/testlib/main.cpp +++ b/src/imports/testlib/main.cpp @@ -40,10 +40,13 @@ ****************************************************************************/ #include -#include "qdeclarativetestreport_p.h" +#include +#include "qdeclarativetestresult_p.h" QT_BEGIN_NAMESPACE +QML_DECLARE_TYPE(QDeclarativeTestResult) + class QTestQmlModule : public QDeclarativeExtensionPlugin { Q_OBJECT @@ -51,7 +54,7 @@ public: virtual void registerTypes(const char *uri) { Q_ASSERT(QLatin1String(uri) == QLatin1String("QtTest")); - qmlRegisterType(uri,1,0,"TestReport"); + qmlRegisterType(uri,1,0,"TestResult"); } }; diff --git a/src/imports/testlib/testlogger.js b/src/imports/testlib/testlogger.js index f556497..7fd33ca 100644 --- a/src/imports/testlib/testlogger.js +++ b/src/imports/testlib/testlogger.js @@ -49,67 +49,16 @@ function log_init_results() { if (!Qt.testResults) { Qt.testResults = { - suiteName: "", reportedStart: false, - numPassed: 0, - numFailed: 0, - numSkipped: 0, nextId: 0, - testCases: [], - reporter: null + testCases: [] } } } -function log_fail(testcase, msg) -{ - if (!msg) - msg = "" - Qt.testResults.reporter.log_fail(testcase, msg); - ++Qt.testResults.numFailed -} - -function log_expect_fail(testcase, expectmsg, msg) -{ - if (!msg) - msg = "" - if (expectmsg) - Qt.testResults.reporter.log_expect_fail(testcase, expectmsg + " " + msg); - else - Qt.testResults.reporter.log_expect_fail(testcase, msg); - ++Qt.testResults.numPassed -} - -function log_expect_fail_pass(testcase) -{ - Qt.testResults.reporter.log_expect_fail_pass(testcase); - ++Qt.testResults.numFailed -} - -function log_skip(testcase, msg) -{ - if (!msg) - msg = "" - Qt.testResults.reporter.log_skip(testcase, msg); - ++Qt.testResults.numSkipped -} - -function log_pass(testcase) -{ - Qt.testResults.reporter.log_pass(testcase); - ++Qt.testResults.numPassed -} - -function log_message(msg) -{ - Qt.testResults.reporter.log_message(msg); -} - function log_register_test(name) { log_init_results() - if (name && !Qt.testResults.suiteName) - Qt.testResults.suiteName = name var testId = Qt.testResults.nextId++ Qt.testResults.testCases.push(testId) return testId @@ -131,34 +80,19 @@ function log_mandatory_test(testId) Qt.testResults.testCases.push(testId) } -function log_start_test(reporter) +function log_start_test() { log_init_results() - Qt.testResults.reporter = reporter if (Qt.testResults.reportedStart) - return + return false Qt.testResults.reportedStart = true + return true } -function log_complete_test(testId, reporter) +function log_complete_test(testId) { var index = Qt.testResults.testCases.indexOf(testId) if (index >= 0) Qt.testResults.testCases.splice(index, 1) - if (!Qt.testResults.testCases.length) { - reporter.report(Qt.testResults.numPassed, - Qt.testResults.numFailed, - Qt.testResults.numSkipped) - Qt.quit() - } -} - -function log_prefixed_name(name, funcname) -{ - if (!name) - name = Qt.testResults.suiteName - if (name) - return name + "::" + funcname + "()" - else - return funcname + "()" + return Qt.testResults.testCases.length > 0 } diff --git a/src/quicktestlib/qdeclarativetest.cpp b/src/quicktestlib/qdeclarativetest.cpp index 09a262f..67e8d70 100644 --- a/src/quicktestlib/qdeclarativetest.cpp +++ b/src/quicktestlib/qdeclarativetest.cpp @@ -40,7 +40,7 @@ ****************************************************************************/ #include "qdeclarativetest.h" -#include "qdeclarativetestreport_p.h" +#include "qdeclarativetestresult_p.h" #include #include #include @@ -58,13 +58,6 @@ QT_BEGIN_NAMESPACE -// Defined in qdeclarativetestreport.cpp. -extern bool qtest_quick_xmlOutput; -extern int qtest_quick_passed; -extern int qtest_quick_failed; -extern int qtest_quick_skipped; -extern FILE *qtest_quick_stream; - class QTestQuitObject : public QObject { Q_OBJECT @@ -82,14 +75,8 @@ int qtest_quick_main(int argc, char **argv, const char *name, const char *source QApplication app(argc, argv); // Parse the command-line arguments. - const char *filename = 0; - for (int index = 1; index < argc; ++index) { - QString arg = QString::fromLocal8Bit(argv[index]); - if (arg == QLatin1String("-xml")) - qtest_quick_xmlOutput = true; - else if (arg == QLatin1String("-o") && (index + 1) < argc) - filename = argv[++index]; - } + QDeclarativeTestResult::parseArgs(argc, argv); + QDeclarativeTestResult::setProgramName(name); // Determine where to look for the test data. On a device it will // typically be necessary to set QTEST_QUICK_SOURCE_DIR. @@ -109,31 +96,11 @@ int qtest_quick_main(int argc, char **argv, const char *name, const char *source if (!entries.contains(QLatin1String("."))) entries.append(QLatin1String(".")); - if (filename) { - qtest_quick_stream = fopen(filename, "w"); - if (!qtest_quick_stream) { - perror(filename); - return 1; - } - } else { - qtest_quick_stream = stdout; - } - - if (qtest_quick_xmlOutput) { - fprintf(qtest_quick_stream, "\n" - "\n", name); - fprintf(qtest_quick_stream, "\n" - " %s\n" - " %s\n" - "\n", qVersion(), qVersion()); - } else { - fprintf(qtest_quick_stream, "********* Start testing of %s *********\n", name); - } - // Scan through all of the "tst_*.qml" files in the subdirectories // and run each of them in turn with a QDeclarativeView. QStringList filters; filters += QLatin1String("tst_*.qml"); + bool compileFail = false; foreach (QString name, entries) { QDir subdir(testPath + QDir::separator() + name); QStringList files = subdir.entryList(filters, QDir::Files); @@ -153,7 +120,7 @@ int qtest_quick_main(int argc, char **argv, const char *name, const char *source view.setSource(QUrl::fromLocalFile(fi.absoluteFilePath())); if (view.status() == QDeclarativeView::Error) { // Error compiling the test - flag failure and continue. - ++qtest_quick_failed; + compileFail = true; continue; } if (!quitobj.hasQuit) { @@ -168,18 +135,14 @@ int qtest_quick_main(int argc, char **argv, const char *name, const char *source } } - if (qtest_quick_xmlOutput) { - fprintf(qtest_quick_stream, "\n"); - } else { - fprintf(qtest_quick_stream, "Totals: %d passed, %d failed, %d skipped\n", - qtest_quick_passed, qtest_quick_failed, qtest_quick_skipped); - fprintf(qtest_quick_stream, "********* Finished testing of %s *********\n", name); - } - - if (filename) - fclose(qtest_quick_stream); + // Flush the current logging stream. + QDeclarativeTestResult::setProgramName(0); - return qtest_quick_failed != 0; + // Return the number of failures as the exit code. + int code = QDeclarativeTestResult::exitCode(); + if (!code && compileFail) + ++code; + return code; } QT_END_NAMESPACE diff --git a/src/quicktestlib/qdeclarativetestreport.cpp b/src/quicktestlib/qdeclarativetestreport.cpp deleted file mode 100644 index df9605b..0000000 --- a/src/quicktestlib/qdeclarativetestreport.cpp +++ /dev/null @@ -1,168 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qdeclarativetestreport_p.h" -#include -#include - -QT_BEGIN_NAMESPACE - -bool qtest_quick_xmlOutput = false; -int qtest_quick_passed = 0; -int qtest_quick_failed = 0; -int qtest_quick_skipped = 0; -FILE *qtest_quick_stream = 0; - -void QDeclarativeTestReport::report(int pass, int fail, int skip) -{ - qtest_quick_passed += pass; - qtest_quick_failed += fail; - qtest_quick_skipped += skip; -} - -void QDeclarativeTestReport::log_fail(const QString &testCase, const QString &message) -{ - if (!qtest_quick_stream) - qtest_quick_stream = stdout; - if (qtest_quick_xmlOutput) { - log_incident("fail", testCase, message); - } else if (!message.isEmpty()) { - fprintf(qtest_quick_stream, "FAIL! : %s %s\n", - testCase.toLatin1().constData(), - message.toLatin1().constData()); - } else { - fprintf(qtest_quick_stream, "FAIL! : %s\n", testCase.toLatin1().constData()); - } -} - -void QDeclarativeTestReport::log_expect_fail - (const QString &testCase, const QString &message) -{ - if (!qtest_quick_stream) - qtest_quick_stream = stdout; - if (qtest_quick_xmlOutput) { - log_incident("xfail", testCase, message); - } else if (!message.isEmpty()) { - fprintf(qtest_quick_stream, "XFAIL : %s %s\n", - testCase.toLatin1().constData(), - message.toLatin1().constData()); - } else { - fprintf(qtest_quick_stream, "XFAIL : %s\n", testCase.toLatin1().constData()); - } -} - -void QDeclarativeTestReport::log_expect_fail_pass(const QString &testCase) -{ - if (!qtest_quick_stream) - qtest_quick_stream = stdout; - if (qtest_quick_xmlOutput) - log_incident("xpass", testCase, QString()); - else - fprintf(qtest_quick_stream, "XPASS : %s\n", testCase.toLatin1().constData()); -} - -void QDeclarativeTestReport::log_skip(const QString &testCase, const QString &message) -{ - if (!qtest_quick_stream) - qtest_quick_stream = stdout; - if (qtest_quick_xmlOutput) { - log_incident("skip", testCase, message); - } else if (!message.isEmpty()) { - fprintf(qtest_quick_stream, "SKIP : %s %s\n", - testCase.toLatin1().constData(), - message.toLatin1().constData()); - } else { - fprintf(qtest_quick_stream, "SKIP : %s\n", testCase.toLatin1().constData()); - } -} - -void QDeclarativeTestReport::log_pass(const QString &testCase) -{ - if (!qtest_quick_stream) - qtest_quick_stream = stdout; - if (qtest_quick_xmlOutput) - log_incident("pass", testCase, QString()); - else - fprintf(qtest_quick_stream, "PASS : %s\n", testCase.toLatin1().constData()); -} - -void QDeclarativeTestReport::log_message(const QString &message) -{ - if (!qtest_quick_stream) - qtest_quick_stream = stdout; - if (!qtest_quick_xmlOutput) - fprintf(qtest_quick_stream, "%s\n", message.toLatin1().constData()); -} - -void QDeclarativeTestReport::log_incident - (const char *type, const QString &testCase, const QString &message) -{ - QString name(testCase); - QString tag; - name.replace(QLatin1String("()"), QLatin1String("")); - name.replace(QLatin1String("::"), QLatin1String("__")); - int tagIndex = name.indexOf(QLatin1String(" [")); - if (tagIndex >= 0) { - tag = name.mid(tagIndex + 2); - if (tag.endsWith(QLatin1String("]"))) - tag = tag.left(tag.length() - 1); - name = name.left(tagIndex); - } - fprintf(qtest_quick_stream, "\n", - Qt::escape(name).toLatin1().constData()); - if (message.isEmpty() && tag.isEmpty()) { - fprintf(qtest_quick_stream, "\n", type); - } else { - fprintf(qtest_quick_stream, "\n", type); - if (!tag.isEmpty()) { - fprintf(qtest_quick_stream, " %s\n", - Qt::escape(tag).toLatin1().constData()); - } - if (!message.isEmpty()) { - fprintf(qtest_quick_stream, " %s\n", - Qt::escape(message).toLatin1().constData()); - } - fprintf(qtest_quick_stream, "\n"); - } - fprintf(qtest_quick_stream, "\n"); -} - -QT_END_NAMESPACE diff --git a/src/quicktestlib/qdeclarativetestreport_p.h b/src/quicktestlib/qdeclarativetestreport_p.h deleted file mode 100644 index 9535184..0000000 --- a/src/quicktestlib/qdeclarativetestreport_p.h +++ /dev/null @@ -1,77 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QDECLARATIVETESTREPORT_P_H -#define QDECLARATIVETESTREPORT_P_H - -#include "quicktestglobal.h" -#include -#include -#include - -QT_BEGIN_NAMESPACE - -class Q_TEST_QUICK_EXPORT QDeclarativeTestReport : public QObject -{ - Q_OBJECT -public: - QDeclarativeTestReport(QObject *parent = 0) : QObject(parent) {} - -public Q_SLOTS: - void report(int pass, int fail, int skip); - void log_fail(const QString &testCase, const QString &message); - void log_expect_fail - (const QString &testCase, const QString &message); - void log_expect_fail_pass(const QString &testCase); - void log_skip(const QString &testCase, const QString &message); - void log_pass(const QString &testCase); - void log_message(const QString &message); - -private: - void log_incident(const char *type, const QString &testCase, - const QString &message); -}; - -QML_DECLARE_TYPE(QDeclarativeTestReport) - -QT_END_NAMESPACE - -#endif diff --git a/src/quicktestlib/qdeclarativetestresult.cpp b/src/quicktestlib/qdeclarativetestresult.cpp index 0cc68e9..691b4a9 100644 --- a/src/quicktestlib/qdeclarativetestresult.cpp +++ b/src/quicktestlib/qdeclarativetestresult.cpp @@ -51,6 +51,9 @@ QT_BEGIN_NAMESPACE +static const char *globalProgramName = 0; +static bool loggingStarted = false; + class QDeclarativeTestResultPrivate { public: @@ -66,7 +69,6 @@ public: QByteArray intern(const QString &str); void updateTestObjectName(); - QString programName; QString testCaseName; QString functionName; QSet internedStrings; @@ -88,21 +90,13 @@ void QDeclarativeTestResultPrivate::updateTestObjectName() // functions as "testCase__function". if (QTestLog::logMode() == QTestLog::Plain) { if (testCaseName.isEmpty()) { - if (programName.isEmpty()) { - QTestResult::setCurrentTestObject(0); - } else { - QTestResult::setCurrentTestObject - (intern(programName).constData()); - } + QTestResult::setCurrentTestObject(globalProgramName); } else if (QTestLog::logMode() == QTestLog::Plain) { QTestResult::setCurrentTestObject (intern(testCaseName).constData()); } - } else if (programName.isEmpty()) { - QTestResult::setCurrentTestObject(0); } else { - QTestResult::setCurrentTestObject - (intern(programName).constData()); + QTestResult::setCurrentTestObject(globalProgramName); } } @@ -115,38 +109,13 @@ QDeclarativeTestResult::~QDeclarativeTestResult() { } -/*! - \qmlproperty string TestResult::programName - - This property defines the name of the test program that - is running the test cases. If this string is set to empty, - then all TestCase elements have been executed and the program - is about to exit. - - \sa testCaseName, functionName -*/ -QString QDeclarativeTestResult::programName() const -{ - Q_D(const QDeclarativeTestResult); - return d->programName; -} - -void QDeclarativeTestResult::setProgramName(const QString &name) -{ - Q_D(QDeclarativeTestResult); - d->programName = name; - d->updateTestObjectName(); - emit programNameChanged(); -} - /*! \qmlproperty string TestResult::testCaseName This property defines the name of current TestCase element - that is running test cases. If this string is empty, then - programName will be used instead. + that is running test cases. - \sa programName, functionName + \sa functionName */ QString QDeclarativeTestResult::testCaseName() const { @@ -169,7 +138,7 @@ void QDeclarativeTestResult::setTestCaseName(const QString &name) within a TestCase element that is running. If this string is empty, then no function is currently running. - \sa programName, testCaseName + \sa testCaseName */ QString QDeclarativeTestResult::functionName() const { @@ -183,10 +152,9 @@ void QDeclarativeTestResult::setFunctionName(const QString &name) if (!name.isEmpty()) { // In plain logging mode, we use the function name directly. // In XML logging mode, we use "testCase__functionName" as the - // programName is acting as the class name. + // program name is acting as the class name. if (QTestLog::logMode() == QTestLog::Plain || - d->testCaseName.isEmpty() || - d->testCaseName == d->programName) { + d->testCaseName.isEmpty()) { QTestResult::setCurrentTestFunction (d->intern(name).constData()); } else { @@ -327,40 +295,51 @@ int QDeclarativeTestResult::skipCount() const */ void QDeclarativeTestResult::reset() { - QTestResult::reset(); + if (!globalProgramName) // Only if run via qmlviewer. + QTestResult::reset(); } /*! \qmlmethod TestResult::startLogging() Starts logging to the test output stream and writes the - test header for programName. + test header. \sa stopLogging() */ void QDeclarativeTestResult::startLogging() { - // The program name is used for logging headers and footers. + // The program name is used for logging headers and footers if it + // is set. Otherwise the test case name is used. Q_D(QDeclarativeTestResult); + if (loggingStarted) + return; const char *saved = QTestResult::currentTestObjectName(); - QTestResult::setCurrentTestObject(d->intern(d->programName).constData()); + if (globalProgramName) { + QTestResult::setCurrentTestObject(globalProgramName); + } else { + QTestResult::setCurrentTestObject + (d->intern(d->testCaseName).constData()); + } QTestLog::startLogging(); QTestResult::setCurrentTestObject(saved); + loggingStarted = true; } /*! \qmlmethod TestResult::stopLogging() - Writes the test footer for programName to the test - output stream and then stops logging. + Writes the test footer to the test output stream and then stops logging. \sa startLogging() */ void QDeclarativeTestResult::stopLogging() { Q_D(QDeclarativeTestResult); + if (globalProgramName) + return; // Logging will be stopped by setProgramName(0). const char *saved = QTestResult::currentTestObjectName(); - QTestResult::setCurrentTestObject(d->intern(d->programName).constData()); + QTestResult::setCurrentTestObject(d->intern(d->testCaseName).constData()); QTestLog::stopLogging(); QTestResult::setCurrentTestObject(saved); } @@ -446,4 +425,36 @@ void QDeclarativeTestResult::warn(const QString &message) QTestLog::warn(message.toLatin1().constData()); } +namespace QTest { + void qtest_qParseArgs(int argc, char *argv[]); +}; + +void QDeclarativeTestResult::parseArgs(int argc, char *argv[]) +{ + QTest::qtest_qParseArgs(argc, argv); +} + +void QDeclarativeTestResult::setProgramName(const char *name) +{ + if (name) { + QTestResult::reset(); + } else if (!name && loggingStarted) { + QTestResult::setCurrentTestObject(globalProgramName); + QTestLog::stopLogging(); + QTestResult::setCurrentTestObject(0); + } + globalProgramName = name; +} + +int QDeclarativeTestResult::exitCode() +{ +#if defined(QTEST_NOEXITCODE) + return 0; +#else + // make sure our exit code is never going above 127 + // since that could wrap and indicate 0 test fails + return qMin(QTestResult::failCount(), 127); +#endif +} + QT_END_NAMESPACE diff --git a/src/quicktestlib/qdeclarativetestresult_p.h b/src/quicktestlib/qdeclarativetestresult_p.h index c6720e0..3b0b592 100644 --- a/src/quicktestlib/qdeclarativetestresult_p.h +++ b/src/quicktestlib/qdeclarativetestresult_p.h @@ -55,7 +55,6 @@ class Q_TEST_QUICK_EXPORT QDeclarativeTestResult : public QObject { Q_OBJECT Q_ENUMS(FunctionType) - Q_PROPERTY(QString programName READ programName WRITE setProgramName NOTIFY programNameChanged) Q_PROPERTY(QString testCaseName READ testCaseName WRITE setTestCaseName NOTIFY testCaseNameChanged) Q_PROPERTY(QString functionName READ functionName WRITE setFunctionName NOTIFY functionNameChanged) Q_PROPERTY(FunctionType functionType READ functionType WRITE setFunctionType NOTIFY functionTypeChanged) @@ -80,9 +79,6 @@ public: CleanupFunc = 4 }; - QString programName() const; - void setProgramName(const QString &name); - QString testCaseName() const; void setTestCaseName(const QString &name); @@ -126,6 +122,13 @@ public Q_SLOTS: bool expectFailContinue(const QString &tag, const QString &comment); void warn(const QString &message); + +public: + // Helper functions for the C++ main() shell. + static void parseArgs(int argc, char *argv[]); + static void setProgramName(const char *name); + static int exitCode(); + Q_SIGNALS: void programNameChanged(); void testCaseNameChanged(); diff --git a/src/quicktestlib/quicktestlib.pro b/src/quicktestlib/quicktestlib.pro index e57d34a..bd29bdf 100644 --- a/src/quicktestlib/quicktestlib.pro +++ b/src/quicktestlib/quicktestlib.pro @@ -26,13 +26,11 @@ symbian { SOURCES += \ qdeclarativetest.cpp \ - qdeclarativetestreport.cpp \ qdeclarativetestresult.cpp HEADERS += \ quicktestglobal.h \ qdeclarativetest.h PRIVATE_HEADERS += \ - qdeclarativetestreport_p.h \ qdeclarativetestresult_p.h PUBLIC_HEADERS += $$HEADERS -- cgit v1.2.3