diff options
author | Sascha Kolewa <sascha.kolewa@nokia.com> | 2010-12-20 16:26:28 +0100 |
---|---|---|
committer | Sascha Kolewa <sascha.kolewa@nokia.com> | 2010-12-20 16:26:28 +0100 |
commit | 7497c2f9161991f5ec1ef25101788f8ca0f2bdce (patch) | |
tree | fbc13c4632737912f7a06f06b71284ee8a4c62c3 | |
parent | fc40195166040af252146dcea627c590e8f101e0 (diff) | |
parent | 276354547cedabe3b41795793f3f94387f15a7ac (diff) |
Merge branch 'master' of git://scm.dev.nokia.troll.no/research/qtest-qml into Extend_compare_for_objects_and_arrays
-rw-r--r-- | src/imports/testlib/TestCase.qml | 84 | ||||
-rw-r--r-- | src/imports/testlib/testcase.qdoc | 28 | ||||
-rw-r--r-- | src/quicktestlib/quicktest.cpp | 8 | ||||
-rw-r--r-- | src/quicktestlib/quicktestresult.cpp | 35 | ||||
-rw-r--r-- | src/quicktestlib/quicktestresult_p.h | 4 | ||||
-rw-r--r-- | src/quicktestlib/testlib/qtestcase.cpp | 42 | ||||
-rw-r--r-- | src/quicktestlib/testlib/qtestoptions_p.h | 67 | ||||
-rw-r--r-- | tests/qmlauto/selftests/tst_selftests.qml | 3 | ||||
-rw-r--r-- | tests/qmlexample/tst_basic.qml | 2 |
9 files changed, 240 insertions, 33 deletions
diff --git a/src/imports/testlib/TestCase.qml b/src/imports/testlib/TestCase.qml index 0212c83..1165c3a 100644 --- a/src/imports/testlib/TestCase.qml +++ b/src/imports/testlib/TestCase.qml @@ -135,8 +135,12 @@ Item { var act = qtest_formatValue(actual) var exp = qtest_formatValue(expected) var success = qtest_compareInternal(actual, expected) - if (msg === undefined) - msg = "" + if (msg === undefined) { + if (success) + msg = "COMPARE()" + else + msg = "Compared values are not the same" + } if (!qtest_results.compare(success, msg, act, exp, Qt.qtest_caller_file(), Qt.qtest_caller_line())) throw new Error("QtQuickTest::fail") } @@ -174,19 +178,27 @@ Item { } function expectFail(tag, msg) { - if (tag === undefined) + if (tag === undefined) { + warn("tag argument missing from expectFail()") tag = "" - if (msg === undefined) + } + if (msg === undefined) { + warn("message argument missing from expectFail()") msg = "" + } if (!qtest_results.expectFail(tag, msg, Qt.qtest_caller_file(), Qt.qtest_caller_line())) throw new Error("QtQuickTest::expectFail") } function expectFailContinue(tag, msg) { - if (tag === undefined) + if (tag === undefined) { + warn("tag argument missing from expectFailContinue()") tag = "" - if (msg === undefined) + } + if (msg === undefined) { + warn("message argument missing from expectFailContinue()") msg = "" + } if (!qtest_results.expectFailContinue(tag, msg, Qt.qtest_caller_file(), Qt.qtest_caller_line())) throw new Error("QtQuickTest::expectFail") } @@ -355,6 +367,11 @@ Item { } function qtest_run() { + if (Qt.qtest_printAvailableFunctions) { + completed = true + return + } + if (TestLogger.log_start_test()) { qtest_results.reset() qtest_results.testCaseName = name @@ -364,6 +381,32 @@ Item { } running = true + // Check the run list to see if this class is mentioned. + var functionsToRun = qtest_results.functionsToRun + if (functionsToRun.length > 0) { + var found = false + var list = [] + if (name.length > 0) { + var prefix = name + "::" + for (var index in functionsToRun) { + if (functionsToRun[index].indexOf(prefix) == 0) { + list.push(functionsToRun[index]) + found = true + } + } + } + if (!found) { + completed = true + if (!TestLogger.log_complete_test(qtest_testId)) { + qtest_results.stopLogging() + Qt.quit() + } + qtest_results.testCaseName = "" + return + } + functionsToRun = list + } + // Run the initTestCase function. qtest_results.functionName = "initTestCase" qtest_results.functionType = TestResult.InitFunc @@ -385,10 +428,17 @@ Item { } testList.sort() } + var checkNames = (functionsToRun.length > 0) for (var index in testList) { var prop = testList[index] var datafunc = prop + "_data" var isBenchmark = (prop.indexOf("benchmark_") == 0) + if (checkNames) { + var index = functionsToRun.indexOf(name + "::" + prop) + if (index < 0) + continue + functionsToRun.splice(index, 1) + } qtest_results.functionName = prop if (datafunc in testCase) { qtest_results.functionType = TestResult.DataFunc @@ -427,6 +477,10 @@ Item { qtest_results.functionType = TestResult.CleanupFunc qtest_runInternal("cleanupTestCase") + // Complain about missing functions that we were supposed to run. + if (functionsToRun.length > 0) + qtest_results.fail("Could not find functions: " + functionsToRun, "", 0) + // Clean up and exit. running = false completed = true @@ -469,6 +523,24 @@ Item { } Component.onCompleted: { + if (Qt.qtest_printAvailableFunctions) { + var testList = [] + for (var prop in testCase) { + if (prop.indexOf("test_") != 0 && prop.indexOf("benchmark_") != 0) + continue + var tail = prop.lastIndexOf("_data"); + if (tail != -1 && tail == (prop.length - 5)) + continue + // Note: cannot run functions in TestCase elements + // that lack a name. + if (name.length > 0) + testList.push(name + "::" + prop + "()") + } + testList.sort() + for (var index in testList) + console.log(testList[index]) + return + } qtest_testId = TestLogger.log_register_test(name) if (optional) TestLogger.log_optional_test(qtest_testId) diff --git a/src/imports/testlib/testcase.qdoc b/src/imports/testlib/testcase.qdoc index 4e95c5e..bb7044f 100644 --- a/src/imports/testlib/testcase.qdoc +++ b/src/imports/testlib/testcase.qdoc @@ -78,7 +78,7 @@ FAIL! : MathTests::test_fail() 2 + 2 = 5 Actual (): 4 Expected (): 5 - Loc: [file:///.../tst_math.qml(12)] + Loc: [/home/.../tst_math.qml(12)] PASS : MathTests::test_math() PASS : MathTests::cleanupTestCase() Totals: 3 passed, 1 failed, 0 skipped @@ -378,24 +378,30 @@ */ /*! - \qmlmethod TestCase::expectFail(tag, message = "") + \qmlmethod TestCase::expectFail(tag, message) In a data-driven test, marks the row associated with \a tag as - expected to fail. When the fail occurs, display the optional - \a message, abort the test, and mark the test as passing. - Similar to \c{QEXPECT_FAIL(tag, message, Abort)} in C++. + expected to fail. When the fail occurs, display the \a message, + abort the test, and mark the test as passing. Similar to + \c{QEXPECT_FAIL(tag, message, Abort)} in C++. + + If the test is not data-driven, then \a tag must be set to + the empty string. \sa expectFailContinue() */ /*! - \qmlmethod TestCase::expectFailContinue(tag, message = "") + \qmlmethod TestCase::expectFailContinue(tag, message) In a data-driven test, marks the row associated with \a tag as - expected to fail. When the fail occurs, display the optional - \a message, and then continue the test. Similar to + expected to fail. When the fail occurs, display the \a message, + and then continue the test. Similar to \c{QEXPECT_FAIL(tag, message, Continue)} in C++. + If the test is not data-driven, then \a tag must be set to + the empty string. + \sa expectFail() */ @@ -411,9 +417,9 @@ /*! \qmlmethod TestCase::ignoreWarning(message) - Marks \a message as an ignored message. When it occurs, the message - will not be printed and the test passes. If the message does not - occur, then the test will fail. Similar to + Marks \a message as an ignored warning message. When it occurs, + the warning will not be printed and the test passes. If the message + does not occur, then the test will fail. Similar to \c{QTest::ignoreMessage(QtWarningMsg, message)} in C++. \sa warn() diff --git a/src/quicktestlib/quicktest.cpp b/src/quicktestlib/quicktest.cpp index 826c90f..718c6e9 100644 --- a/src/quicktestlib/quicktest.cpp +++ b/src/quicktestlib/quicktest.cpp @@ -42,6 +42,7 @@ #include "quicktest.h" #include "quicktestresult_p.h" #include "qtestsystem.h" +#include "qtestoptions_p.h" #include <QApplication> #include <QtDeclarative/qdeclarative.h> #include <QtDeclarative/qdeclarativeview.h> @@ -199,7 +200,10 @@ int quick_test_main(int argc, char **argv, const char *name, quick_test_viewport QScriptValue qtObject = engine->globalObject().property(QLatin1String("Qt")); qtObject.setProperty - (QLatin1String("qtest_wrapper"), engine->newVariant(true)); + (QLatin1String("qtest_wrapper"), QScriptValue(true)); + qtObject.setProperty + (QLatin1String("qtest_printAvailableFunctions"), + QScriptValue(QTest::printAvailableFunctions)); foreach (QString path, imports) view.engine()->addImportPath(path); QString path = fi.absoluteFilePath(); @@ -207,6 +211,8 @@ int quick_test_main(int argc, char **argv, const char *name, quick_test_viewport view.setSource(QUrl(QLatin1String("qrc:") + path.mid(2))); else view.setSource(QUrl::fromLocalFile(path)); + if (QTest::printAvailableFunctions) + continue; if (view.status() == QDeclarativeView::Error) { // Error compiling the test - flag failure in the log and continue. QList<QDeclarativeError> errors = view.errors(); diff --git a/src/quicktestlib/quicktestresult.cpp b/src/quicktestlib/quicktestresult.cpp index 285a26b..0ceb191 100644 --- a/src/quicktestlib/quicktestresult.cpp +++ b/src/quicktestlib/quicktestresult.cpp @@ -45,6 +45,7 @@ #include "qtestresult_p.h" #include "qtesttable_p.h" #include "qtestlog_p.h" +#include "qtestoptions_p.h" #include "qbenchmark.h" #include "qbenchmark_p.h" #include <QtCore/qset.h> @@ -306,6 +307,16 @@ int QuickTestResult::skipCount() const } /*! + \qmlproperty list<string> TestResult::functionsToRun + + This property returns the list of function names to be run. +*/ +QStringList QuickTestResult::functionsToRun() const +{ + return QTest::testFunctions; +} + +/*! \qmlmethod TestResult::reset() Resets all pass/fail/skip counters and prepare for testing. @@ -398,7 +409,7 @@ void QuickTestResult::fail bool QuickTestResult::verify (bool success, const QString &message, const QString &file, int line) { - if (message.isEmpty()) { + if (!success && message.isEmpty()) { return QTestResult::verify (success, "verify()", "", qtest_fixFile(file).toLatin1().constData(), line); @@ -414,12 +425,18 @@ bool QuickTestResult::compare const QString &val1, const QString &val2, const QString &file, int line) { - return QTestResult::compare - (success, message.toLocal8Bit().constData(), - QTest::toString(val1.toLatin1().constData()), - QTest::toString(val2.toLatin1().constData()), - "", "", - qtest_fixFile(file).toLatin1().constData(), line); + if (success) { + return QTestResult::compare + (success, message.toLocal8Bit().constData(), + qtest_fixFile(file).toLatin1().constData(), line); + } else { + return QTestResult::compare + (success, message.toLocal8Bit().constData(), + QTest::toString(val1.toLatin1().constData()), + QTest::toString(val2.toLatin1().constData()), + "", "", + qtest_fixFile(file).toLatin1().constData(), line); + } } void QuickTestResult::skipSingle @@ -577,14 +594,14 @@ void QuickTestResult::stopBenchmark() } namespace QTest { - void qtest_qParseArgs(int argc, char *argv[]); + void qtest_qParseArgs(int argc, char *argv[], bool qml); }; void QuickTestResult::parseArgs(int argc, char *argv[]) { if (!QBenchmarkGlobalData::current) QBenchmarkGlobalData::current = &globalBenchmarkData; - QTest::qtest_qParseArgs(argc, argv); + QTest::qtest_qParseArgs(argc, argv, true); } void QuickTestResult::setProgramName(const char *name) diff --git a/src/quicktestlib/quicktestresult_p.h b/src/quicktestlib/quicktestresult_p.h index a3c67be..d9ae694 100644 --- a/src/quicktestlib/quicktestresult_p.h +++ b/src/quicktestlib/quicktestresult_p.h @@ -45,6 +45,7 @@ #include <QtQuickTest/quicktestglobal.h> #include <QtCore/qobject.h> #include <QtCore/qstring.h> +#include <QtCore/qstringlist.h> #include <QtCore/qscopedpointer.h> QT_BEGIN_NAMESPACE @@ -65,6 +66,7 @@ class Q_QUICK_TEST_EXPORT QuickTestResult : public QObject Q_PROPERTY(int passCount READ passCount) Q_PROPERTY(int failCount READ failCount) Q_PROPERTY(int skipCount READ skipCount) + Q_PROPERTY(QStringList functionsToRun READ functionsToRun) public: QuickTestResult(QObject *parent = 0); ~QuickTestResult(); @@ -108,6 +110,8 @@ public: int failCount() const; int skipCount() const; + QStringList functionsToRun() const; + public Q_SLOTS: void reset(); diff --git a/src/quicktestlib/testlib/qtestcase.cpp b/src/quicktestlib/testlib/qtestcase.cpp index c66ed8d..093da04 100644 --- a/src/quicktestlib/testlib/qtestcase.cpp +++ b/src/quicktestlib/testlib/qtestcase.cpp @@ -952,6 +952,10 @@ static bool isValidSlot(const QMetaMethod &sl) return true; } +bool printAvailableFunctions = false; +QStringList testFunctions; +QStringList testTags; + static void qPrintTestSlots() { for (int i = 0; i < QTest::currentTestObject->metaObject()->methodCount(); ++i) { @@ -972,7 +976,7 @@ static int qToInt(char *str) return l; } -void qtest_qParseArgs(int argc, char *argv[]) +void qtest_qParseArgs(int argc, char *argv[], bool qml) { lastTestFuncIdx = -1; @@ -1021,8 +1025,12 @@ void qtest_qParseArgs(int argc, char *argv[]) "%s", argv[0], testOptions); exit(0); } else if (strcmp(argv[i], "-functions") == 0) { - qPrintTestSlots(); - exit(0); + if (qml) { + QTest::printAvailableFunctions = true; + } else { + qPrintTestSlots(); + exit(0); + } } else if(strcmp(argv[i], "-xunitxml") == 0){ QTestLog::setLogMode(QTestLog::XunitXML); } else if (strcmp(argv[i], "-xml") == 0) { @@ -1142,6 +1150,32 @@ void qtest_qParseArgs(int argc, char *argv[]) } else if (argv[i][0] == '-') { printf("Unknown option: '%s'\n\n%s", argv[i], testOptions); exit(1); + } else if (qml) { + // We can't check the availability of test functions until + // we load the QML files. So just store the data for now. + int colon = -1; + int off; + for(off = 0; *(argv[i]+off); ++off) { + if (*(argv[i]+off) == ':') { + if (*(argv[i]+off+1) == ':') { + // "::" is used as a test name separator. + // e.g. "ClickTests::test_click:row1". + ++off; + } else { + colon = off; + break; + } + } + } + if (colon == -1) { + QTest::testFunctions += QString::fromLatin1(argv[i]); + QTest::testTags += QString(); + } else { + QTest::testFunctions += + QString::fromLatin1(argv[i], colon); + QTest::testTags += + QString::fromLatin1(argv[i] + colon + 1); + } } else { int colon = -1; char buf[512], *data=0; @@ -1691,7 +1725,7 @@ int QTest::qExec(QObject *testObject, int argc, char **argv) QTEST_ASSERT(metaObject); QTestResult::setCurrentTestObject(metaObject->className()); - qtest_qParseArgs(argc, argv); + qtest_qParseArgs(argc, argv, false); #ifdef QTESTLIB_USE_VALGRIND if (QBenchmarkGlobalData::current->mode() == QBenchmarkGlobalData::CallgrindParentProcess) { const QStringList origAppArgs(QCoreApplication::arguments()); diff --git a/src/quicktestlib/testlib/qtestoptions_p.h b/src/quicktestlib/testlib/qtestoptions_p.h new file mode 100644 index 0000000..2af40ef --- /dev/null +++ b/src/quicktestlib/testlib/qtestoptions_p.h @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** 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 QtTest module 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 QTESTOPTIONS_P_H +#define QTESTOPTIONS_P_H + +#include "qtest_global.h" + +#include <QtCore/qstring.h> +#include <QtCore/qstringlist.h> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Test) + +namespace QTest +{ + extern Q_TESTLIB_EXPORT bool printAvailableFunctions; + extern Q_TESTLIB_EXPORT QStringList testFunctions; + extern Q_TESTLIB_EXPORT QStringList testTags; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/tests/qmlauto/selftests/tst_selftests.qml b/tests/qmlauto/selftests/tst_selftests.qml index c26250d..bcf53b9 100644 --- a/tests/qmlauto/selftests/tst_selftests.qml +++ b/tests/qmlauto/selftests/tst_selftests.qml @@ -52,6 +52,7 @@ TestCase { property string failmsg: "cleaned" property string actual: "" property string expected: "" + property variant functionsToRun: [] function fail(msg, file, line) { failmsg = msg @@ -208,7 +209,7 @@ TestCase { testCase.compare("abcdef", 42) } catch (e) { compare(e.message, "QtQuickTest::fail") - compare(functions.failmsg, "") + compare(functions.failmsg, "Compared values are not the same") compare(functions.actual, "abcdef") compare(functions.expected, "42") caught = true diff --git a/tests/qmlexample/tst_basic.qml b/tests/qmlexample/tst_basic.qml index d905d9b..07d5a9d 100644 --- a/tests/qmlexample/tst_basic.qml +++ b/tests/qmlexample/tst_basic.qml @@ -58,7 +58,7 @@ TestCase { } function test_expecting() { - expectFail("this is the fail we wanted") + expectFail("", "this is the fail we wanted") verify(false) } |