From 9b7b26ca50b0700aea9e756551dfec1cf098f4cd Mon Sep 17 00:00:00 2001 From: Venugopal Shivashankar Date: Fri, 9 Nov 2018 15:26:36 +0100 Subject: [PATCH 1/7] Doc: Use \section1 to clearly identify the different parts The \section1 titles should help the reader relate parts of the document to the three steps outlined in the beginning. Task-number: QTBUG-68733 Change-Id: I1bf5adbc2f2629ecd36465ffeb0ade1ebbf961cb Reviewed-by: Paul Wicking Reviewed-by: Mitch Curtis --- .../src/qmllanguageref/modules/qqmlextensionplugin.qdocinc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/qml/doc/src/qmllanguageref/modules/qqmlextensionplugin.qdocinc b/src/qml/doc/src/qmllanguageref/modules/qqmlextensionplugin.qdocinc index 7c1d65b095..01e81e7c19 100644 --- a/src/qml/doc/src/qmllanguageref/modules/qqmlextensionplugin.qdocinc +++ b/src/qml/doc/src/qmllanguageref/modules/qqmlextensionplugin.qdocinc @@ -23,7 +23,7 @@ plugins. Library plugins should limit themselves to registering types, as any manipulation of the engine's root context may cause conflicts or other issues in the library user's code. -\section1 Plugin Example +\section1 TimeExample QML extension plugin Suppose there is a new \c TimeModel C++ class that should be made available as a new QML type. It provides the current time through \c hour and \c minute @@ -47,6 +47,8 @@ imported correctly by any QML components that use this plugin. The \l{Defining QML Types from C++} article has more information about registering C++ types into the runtime. +\section1 Project settings for the plugin + Additionally, the project file (\c .pro) defines the project as a plugin library, specifies it should be built into the \c imports/TimeExample directory, and registers the plugin target name and various other details: @@ -61,6 +63,8 @@ TARGET = qmlqtimeexampleplugin SOURCES += qexampleqmlplugin.cpp \endcode +\section1 Plugin definition in the qmldir + Finally, a \l{Module Definition qmldir Files}{qmldir file} is required in the \c imports/TimeExample directory to describe the plugin and the types that it exports. The plugin includes a \c Clock.qml file along with the \c qmlqtimeexampleplugin From e12dc7910aaeb6e71275115c30a0eb227ac3b403 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 6 Nov 2018 14:18:23 +0100 Subject: [PATCH 2/7] macOS: Remove blacklist entries for no longer supported OS versions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes: QTBUG-60518 Change-Id: If41b3c7b3ca4ca9a48692cbb2753b47492693e83 Reviewed-by: Timur Pocheptsov Reviewed-by: Morten Johan Sørvig --- tests/auto/quick/qquickfocusscope/BLACKLIST | 2 -- tests/auto/quick/qquicklistview/BLACKLIST | 2 -- 2 files changed, 4 deletions(-) delete mode 100644 tests/auto/quick/qquickfocusscope/BLACKLIST diff --git a/tests/auto/quick/qquickfocusscope/BLACKLIST b/tests/auto/quick/qquickfocusscope/BLACKLIST deleted file mode 100644 index cc3c8b6e8a..0000000000 --- a/tests/auto/quick/qquickfocusscope/BLACKLIST +++ /dev/null @@ -1,2 +0,0 @@ -[canvasFocus] -osx-10.11 diff --git a/tests/auto/quick/qquicklistview/BLACKLIST b/tests/auto/quick/qquicklistview/BLACKLIST index 8cf8a57eee..15aea4be19 100644 --- a/tests/auto/quick/qquicklistview/BLACKLIST +++ b/tests/auto/quick/qquicklistview/BLACKLIST @@ -6,5 +6,3 @@ osx [populateTransitions] opensuse-42.1 #QTBUG-65964 -[QTBUG_34576_velocityZero] -osx-10.11 ci From 16e3859af180b28157f39ad5d1f77ff3571753a2 Mon Sep 17 00:00:00 2001 From: Kirill Burtsev Date: Mon, 8 Oct 2018 11:10:50 +0200 Subject: [PATCH 3/7] Qt Quick Test: support tags filter on tests run Implemented logic for filtering tests with 'case::function:tag' run syntax. Fixes: QTBUG-71645 Change-Id: I9243636b098b4e9ccb4c74d08679bbbb9f3e8a65 Reviewed-by: Mitch Curtis --- src/imports/testlib/TestCase.qml | 72 ++++++++++++++----- src/imports/testlib/plugins.qmltypes | 1 + src/qmltest/quicktestresult.cpp | 10 +++ src/qmltest/quicktestresult_p.h | 2 + .../testfiltering/tst_testfiltering.cpp | 60 ++++++++++++++++ 5 files changed, 126 insertions(+), 19 deletions(-) diff --git a/src/imports/testlib/TestCase.qml b/src/imports/testlib/TestCase.qml index fd91add04e..266e3111bb 100644 --- a/src/imports/testlib/TestCase.qml +++ b/src/imports/testlib/TestCase.qml @@ -1787,17 +1787,28 @@ Item { running = true // Check the run list to see if this class is mentioned. - var functionsToRun = qtest_results.functionsToRun - if (functionsToRun.length > 0) { + let checkNames = false + let testsToRun = {} // explicitly provided function names to run and their tags for data-driven tests + + if (qtest_results.functionsToRun.length > 0) { + checkNames = true 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 - } + for (var index in qtest_results.functionsToRun) { + let caseFuncName = qtest_results.functionsToRun[index] + if (caseFuncName.indexOf(name + "::") != 0) + continue + + found = true + let funcName = caseFuncName.substring(name.length + 2) + + if (!(funcName in testsToRun)) + testsToRun[funcName] = [] + + let tagName = qtest_results.tagsToRun[index] + if (tagName.length > 0) // empty tags mean run all rows + testsToRun[funcName].push(tagName) } } if (!found) { @@ -1809,7 +1820,6 @@ Item { qtest_results.testCaseName = "" return } - functionsToRun = list } // Run the initTestCase function. @@ -1834,17 +1844,15 @@ Item { } testList.sort() } - var checkNames = (functionsToRun.length > 0) + for (var index in testList) { var prop = testList[index] + + if (checkNames && !(prop in testsToRun)) + continue + 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)) @@ -1854,12 +1862,22 @@ Item { if (qtest_runInternal(datafunc)) { var table = qtest_testCaseResult var haveData = false + + let checkTags = (checkNames && testsToRun[prop].length > 0) + qtest_results.initTestTable() for (var index in table) { haveData = true var row = table[index] if (!row.tag) row.tag = "row " + index // Must have something + if (checkTags) { + let tags = testsToRun[prop] + let tagIdx = tags.indexOf(row.tag) + if (tagIdx < 0) + continue + tags.splice(tagIdx, 1) + } qtest_results.dataTag = row.tag if (isBenchmark) qtest_runBenchmarkFunction(prop, row) @@ -1884,6 +1902,9 @@ Item { } qtest_results.finishTestFunction() qtest_results.skipped = false + + if (checkNames && testsToRun[prop].length <= 0) + delete testsToRun[prop] } // Run the cleanupTestCase function. @@ -1892,8 +1913,21 @@ Item { 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) + if (checkNames) { + let missingTests = [] + for (var func in testsToRun) { + let caseFuncName = name + '::' + func + let tags = testsToRun[func] + if (tags.length <= 0) + missingTests.push(caseFuncName) + else + for (var i in tags) + missingTests.push(caseFuncName + ':' + tags[i]) + } + missingTests.sort() + if (missingTests.length > 0) + qtest_results.fail("Could not find test functions: " + missingTests, "", 0) + } // Clean up and exit. running = false diff --git a/src/imports/testlib/plugins.qmltypes b/src/imports/testlib/plugins.qmltypes index 56b4ecf662..e51371d176 100644 --- a/src/imports/testlib/plugins.qmltypes +++ b/src/imports/testlib/plugins.qmltypes @@ -195,6 +195,7 @@ Module { Property { name: "failCount"; type: "int"; isReadonly: true } Property { name: "skipCount"; type: "int"; isReadonly: true } Property { name: "functionsToRun"; type: "QStringList"; isReadonly: true } + Property { name: "tagsToRun"; type: "QStringList"; isReadonly: true } Signal { name: "programNameChanged" } Method { name: "reset" } Method { name: "startLogging" } diff --git a/src/qmltest/quicktestresult.cpp b/src/qmltest/quicktestresult.cpp index 3b854dfccd..3225dc95cd 100644 --- a/src/qmltest/quicktestresult.cpp +++ b/src/qmltest/quicktestresult.cpp @@ -380,6 +380,16 @@ QStringList QuickTestResult::functionsToRun() const return QTest::testFunctions; } +/*! + \qmlproperty list TestResult::tagsToRun + + This property returns the list of test function's data tags to be run +*/ +QStringList QuickTestResult::tagsToRun() const +{ + return QTest::testTags; +} + /*! \qmlmethod TestResult::reset() diff --git a/src/qmltest/quicktestresult_p.h b/src/qmltest/quicktestresult_p.h index f222cd3e87..b2eeefdfff 100644 --- a/src/qmltest/quicktestresult_p.h +++ b/src/qmltest/quicktestresult_p.h @@ -76,6 +76,7 @@ class Q_QUICK_TEST_EXPORT QuickTestResult : public QObject Q_PROPERTY(int failCount READ failCount) Q_PROPERTY(int skipCount READ skipCount) Q_PROPERTY(QStringList functionsToRun READ functionsToRun) + Q_PROPERTY(QStringList tagsToRun READ tagsToRun) public: QuickTestResult(QObject *parent = nullptr); ~QuickTestResult() override; @@ -107,6 +108,7 @@ public: int skipCount() const; QStringList functionsToRun() const; + QStringList tagsToRun() const; public Q_SLOTS: void reset(); diff --git a/tests/auto/quicktest/testfiltering/tst_testfiltering.cpp b/tests/auto/quicktest/testfiltering/tst_testfiltering.cpp index 8817adb3bc..1db3d5be57 100644 --- a/tests/auto/quicktest/testfiltering/tst_testfiltering.cpp +++ b/tests/auto/quicktest/testfiltering/tst_testfiltering.cpp @@ -38,6 +38,10 @@ private slots: void twoFilters(); void twoFiltersWithOneMatch(); void manyFilters(); + void filterTestWithDefaultDataTags(); + void filterTestWithDataTags(); + void filterTestByDataTag(); + void filterInvalidDataTag(); }; @@ -131,6 +135,62 @@ void tst_TestFiltering::manyFilters() QCOMPARE(process.exitCode(), 0); } +void tst_TestFiltering::filterTestWithDefaultDataTags() +{ + QProcess process; + process.start(testExe, { QLatin1String("Third::test_default_tags"), }); + + QVERIFY(process.waitForFinished()); + + const QString output = process.readAll(); + QVERIFY(output.contains(QLatin1String("Totals: 5 passed"))); + QVERIFY(output.contains(QLatin1String(" 2 skipped"))); + QCOMPARE(process.exitStatus(), QProcess::NormalExit); + QCOMPARE(process.exitCode(), 0); +} + +void tst_TestFiltering::filterTestWithDataTags() +{ + QProcess process; + process.start(testExe, { QLatin1String("Third::test_tags"), }); + + QVERIFY(process.waitForFinished()); + + const QString output = process.readAll(); + QVERIFY(output.contains(QLatin1String("Totals: 4 passed"))); + QVERIFY(output.contains(QLatin1String(" 1 skipped"))); + QCOMPARE(process.exitStatus(), QProcess::NormalExit); + QCOMPARE(process.exitCode(), 0); +} + +void tst_TestFiltering::filterTestByDataTag() +{ + QProcess process; + process.start(testExe, { QLatin1String("Third::test_default_tags:init_2"), + QLatin1String("Third::test_default_tags:skip_3"), + QLatin1String("Third::test_tags:baz"), + QLatin1String("Third::test_tags:bar"), }); + + QVERIFY(process.waitForFinished()); + + const QString output = process.readAll(); + QVERIFY(output.contains(QLatin1String("Totals: 4 passed"))); + QVERIFY(output.contains(QLatin1String(" 2 skipped"))); + QCOMPARE(process.exitStatus(), QProcess::NormalExit); + QCOMPARE(process.exitCode(), 0); +} + +void tst_TestFiltering::filterInvalidDataTag() +{ + QProcess process; + process.start(testExe, { QLatin1String("Third::test_tags:invalid_tag") }); + + QVERIFY(process.waitForFinished()); + + QCOMPARE(process.exitStatus(), QProcess::NormalExit); + QCOMPARE(process.exitCode(), 1); +} + QTEST_MAIN(tst_TestFiltering); #include "tst_testfiltering.moc" From e668e12c58c489bda79cc3c116719369cdb06650 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Wed, 14 Nov 2018 14:58:06 +0100 Subject: [PATCH 4/7] QML Inspector: Use Qt5-style connection highlight.h doesn't have a slots section anymore, so the Qt4-style connect produces a runtime warning and the text doesn't disappear. Change-Id: Idacd3552df75179566b9efe43192c9c95dbd6f96 Reviewed-by: Michael Brasser --- src/plugins/qmltooling/qmldbg_inspector/highlight.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/qmltooling/qmldbg_inspector/highlight.cpp b/src/plugins/qmltooling/qmldbg_inspector/highlight.cpp index 0d6cd45354..c4d7872162 100644 --- a/src/plugins/qmltooling/qmldbg_inspector/highlight.cpp +++ b/src/plugins/qmltooling/qmldbg_inspector/highlight.cpp @@ -188,7 +188,7 @@ void SelectionHighlight::showName(const QPointF &displayPoint) { m_displayPoint = displayPoint; m_nameDisplayActive = true; - QTimer::singleShot(1500, this, SLOT(disableNameDisplay())); + QTimer::singleShot(1500, this, &SelectionHighlight::disableNameDisplay); update(); } From 0647853c1659515684da1fb0f44d12eac993dc69 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Thu, 1 Nov 2018 11:02:35 +0100 Subject: [PATCH 5/7] Qml Tooling: Fix crash in QQmlProfilerService test The event counting for failure diagnostics had an off-by-one error. Change-Id: I7f652680a4d154a0624dbfd51af0b026f89cc7ad Reviewed-by: Michael Brasser --- .../debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp b/tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp index 7fc43671c2..9d76158c5b 100644 --- a/tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp +++ b/tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp @@ -373,7 +373,7 @@ bool tst_QQmlProfilerService::verify(tst_QQmlProfilerService::MessageListType ty return false; } - uint position = expectedPosition; + int position = expectedPosition; qint64 timestamp = target->at(expectedPosition).timestamp(); while (position > 0 && target->at(position - 1).timestamp() == timestamp) --position; @@ -448,7 +448,7 @@ bool tst_QQmlProfilerService::verify(tst_QQmlProfilerService::MessageListType ty } return true; - } while (target->at(++position).timestamp() == timestamp); + } while (++position < target->length() && target->at(position).timestamp() == timestamp); foreach (const QString &message, warnings) qWarning() << message.toLocal8Bit().constData(); From 71645c45b9880d1a349c9a41a73d455f31c9de75 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Thu, 1 Nov 2018 10:58:31 +0100 Subject: [PATCH 6/7] Qml Tooling: Correctly sort debug messages into traces Debug messages are sent from a different debug service and generally arrive before they are "due". Therefore we buffer them and pass them on when the trace has advanced to their position. However, we forgot some places where we needed to check if there are pending debug messages to be sent. Change-Id: Ia6263086a9d06ae7c77c9e2afa85e6e1d8c8a19b Reviewed-by: Michael Brasser --- src/qmldebug/qqmlprofilerclient.cpp | 16 +++++++++++----- src/qmldebug/qqmlprofilerclient_p_p.h | 1 + 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/qmldebug/qqmlprofilerclient.cpp b/src/qmldebug/qqmlprofilerclient.cpp index 73db2ad94d..5477af89d4 100644 --- a/src/qmldebug/qqmlprofilerclient.cpp +++ b/src/qmldebug/qqmlprofilerclient.cpp @@ -94,12 +94,17 @@ int QQmlProfilerClientPrivate::resolveStackTop() } void QQmlProfilerClientPrivate::forwardEvents(const QQmlProfilerEvent &last) +{ + forwardDebugMessages(last.timestamp()); + eventReceiver->addEvent(last); +} + +void QQmlProfilerClientPrivate::forwardDebugMessages(qint64 untilTimestamp) { while (!pendingDebugMessages.isEmpty() - && pendingDebugMessages.front().timestamp() <= last.timestamp()) { + && pendingDebugMessages.front().timestamp() <= untilTimestamp) { eventReceiver->addEvent(pendingDebugMessages.dequeue()); } - eventReceiver->addEvent(last); } void QQmlProfilerClientPrivate::processCurrentEvent() @@ -142,7 +147,7 @@ void QQmlProfilerClientPrivate::processCurrentEvent() int typeIndex = resolveType(currentEvent); currentEvent.event.setTypeIndex(typeIndex); if (rangesInProgress.isEmpty()) - eventReceiver->addEvent(currentEvent.event); + forwardEvents(currentEvent.event); else pendingMessages.enqueue(currentEvent.event); break; @@ -228,8 +233,7 @@ void QQmlProfilerClientPrivate::finalize() currentEvent.event.setTimestamp(maximumTime); processCurrentEvent(); } - while (!pendingDebugMessages.isEmpty()) - eventReceiver->addEvent(pendingDebugMessages.dequeue()); + forwardDebugMessages(std::numeric_limits::max()); } @@ -345,12 +349,14 @@ void QQmlProfilerClient::messageReceived(const QByteArray &data) && d->currentEvent.type.detailType() == StartTrace) { const QList engineIds = d->currentEvent.event.numbers, qint32>(); d->trackedEngines.append(engineIds); + d->forwardDebugMessages(d->currentEvent.event.timestamp()); emit traceStarted(d->currentEvent.event.timestamp(), engineIds); } else if (d->currentEvent.type.message() == Event && d->currentEvent.type.detailType() == EndTrace) { const QList engineIds = d->currentEvent.event.numbers, qint32>(); for (int engineId : engineIds) d->trackedEngines.removeAll(engineId); + d->forwardDebugMessages(d->currentEvent.event.timestamp()); emit traceFinished(d->currentEvent.event.timestamp(), engineIds); } else if (d->updateFeatures(d->currentEvent.type.feature())) { d->processCurrentEvent(); diff --git a/src/qmldebug/qqmlprofilerclient_p_p.h b/src/qmldebug/qqmlprofilerclient_p_p.h index df73209858..52d42eae82 100644 --- a/src/qmldebug/qqmlprofilerclient_p_p.h +++ b/src/qmldebug/qqmlprofilerclient_p_p.h @@ -86,6 +86,7 @@ public: int resolveType(const QQmlProfilerTypedEvent &type); int resolveStackTop(); void forwardEvents(const QQmlProfilerEvent &last); + void forwardDebugMessages(qint64 untilTimestamp); void processCurrentEvent(); void finalize(); From 87265c7ab8743ece92262cd6b79bbba9dddd1fe1 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Thu, 1 Nov 2018 11:06:34 +0100 Subject: [PATCH 7/7] Qml Tooling: Test that trace events arrive in chronological order The QML profiler trace client should resolve any deviations from chronological order. Trace receivers should not need to deal with this. Change-Id: I9bbb387bbb5c0b7da9f2b508d228665af9f27d4c Reviewed-by: Michael Brasser --- .../qqmlprofilerservice/tst_qqmlprofilerservice.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp b/tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp index 9d76158c5b..1783ded9d6 100644 --- a/tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp +++ b/tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp @@ -69,6 +69,9 @@ public: int numLoadedEventTypes() const override; void addEventType(const QQmlProfilerEventType &type) override; void addEvent(const QQmlProfilerEvent &event) override; + +private: + qint64 lastTimestamp = -1; }; void QQmlProfilerTestClient::startTrace(qint64 timestamp, const QList &engineIds) @@ -102,6 +105,9 @@ void QQmlProfilerTestClient::addEvent(const QQmlProfilerEvent &event) const QQmlProfilerEventType &type = types[typeIndex]; + QVERIFY(event.timestamp() >= lastTimestamp); + lastTimestamp = event.timestamp(); + switch (type.message()) { case Event: { switch (type.detailType()) {