Merge remote-tracking branch 'origin/5.12' into dev
Change-Id: I34aa0c2eb178862b40e63b62c6daa056e5e204c6
This commit is contained in:
commit
0ae32e678e
|
@ -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])
|
||||
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
|
||||
|
|
|
@ -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" }
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<qint64>::max());
|
||||
}
|
||||
|
||||
|
||||
|
@ -345,12 +349,14 @@ void QQmlProfilerClient::messageReceived(const QByteArray &data)
|
|||
&& d->currentEvent.type.detailType() == StartTrace) {
|
||||
const QList<int> engineIds = d->currentEvent.event.numbers<QList<int>, 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<int> engineIds = d->currentEvent.event.numbers<QList<int>, 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();
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -380,6 +380,16 @@ QStringList QuickTestResult::functionsToRun() const
|
|||
return QTest::testFunctions;
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlproperty list<string> 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()
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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<int> &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()) {
|
||||
|
@ -373,7 +379,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 +454,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();
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
[canvasFocus]
|
||||
osx-10.11
|
|
@ -6,5 +6,3 @@ osx
|
|||
[populateTransitions]
|
||||
opensuse-42.1
|
||||
#QTBUG-65964
|
||||
[QTBUG_34576_velocityZero]
|
||||
osx-10.11 ci
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in New Issue