diff options
Diffstat (limited to 'tests')
56 files changed, 1747 insertions, 271 deletions
diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro index 1e80f1bf65..f9c1fcce91 100644 --- a/tests/auto/auto.pro +++ b/tests/auto/auto.pro @@ -18,4 +18,7 @@ qtHaveModule(gui):qtConfig(opengl(es1|es2)?) { # console applications not supported uikit: SUBDIRS -= qmltest +# Restricted sub-set for now +boot2qt: SUBDIRS = qml + installed_cmake.depends = cmake diff --git a/tests/auto/particles/qquickparticlesystem/data/crashaffectors.qml b/tests/auto/particles/qquickparticlesystem/data/crashaffectors.qml new file mode 100644 index 0000000000..de105916a7 --- /dev/null +++ b/tests/auto/particles/qquickparticlesystem/data/crashaffectors.qml @@ -0,0 +1,43 @@ +/**************************************************************************** +** +** Copyright (C) 2017 reMarkable A/S +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** 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 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.6 +import QtQuick.Particles 2.0 + +ParticleSystem { + running: false + Affector { Component.onCompleted: destroy() } + Emitter { + Timer { interval: 1; running: true; onTriggered: parent.lifeSpan = 1 } + } +} diff --git a/tests/auto/particles/qquickparticlesystem/tst_qquickparticlesystem.cpp b/tests/auto/particles/qquickparticlesystem/tst_qquickparticlesystem.cpp index 5c82b946e5..5f9db12144 100644 --- a/tests/auto/particles/qquickparticlesystem/tst_qquickparticlesystem.cpp +++ b/tests/auto/particles/qquickparticlesystem/tst_qquickparticlesystem.cpp @@ -42,6 +42,7 @@ public: private slots: void initTestCase(); void test_basic(); + void test_affectorscrash(); }; void tst_qquickparticlesystem::initTestCase() @@ -78,6 +79,12 @@ void tst_qquickparticlesystem::test_basic() delete view; QVERIFY(extremelyFuzzyCompare(stillAlive, 500, 5));//Small simulation variance is permissible. } +void tst_qquickparticlesystem::test_affectorscrash() +{ + QScopedPointer<QQuickView> view (createView(testFileUrl("crashaffectors.qml"), 600)); + + // This should have crashed by now +} QTEST_MAIN(tst_qquickparticlesystem); diff --git a/tests/auto/qml/debugger/qdebugmessageservice/tst_qdebugmessageservice.cpp b/tests/auto/qml/debugger/qdebugmessageservice/tst_qdebugmessageservice.cpp index 8be82c30f9..f193d3928a 100644 --- a/tests/auto/qml/debugger/qdebugmessageservice/tst_qdebugmessageservice.cpp +++ b/tests/auto/qml/debugger/qdebugmessageservice/tst_qdebugmessageservice.cpp @@ -135,7 +135,7 @@ void QQmlDebugMsgClient::messageReceived(const QByteArray &data) QVERIFY(ds.atEnd()); QVERIFY(type >= QtDebugMsg); - QVERIFY(type <= QtFatalMsg); + QVERIFY(type <= QtInfoMsg); QVERIFY(timestamp > 0); LogEntry entry((QtMsgType)type, QString::fromUtf8(message)); diff --git a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/tst_qqmldebugjs.cpp b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/tst_qqmldebugjs.cpp index 31b8d63ec2..d248cf9708 100644 --- a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/tst_qqmldebugjs.cpp +++ b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/tst_qqmldebugjs.cpp @@ -257,7 +257,7 @@ public: stringify = jsEngine.evaluate(QLatin1String("JSON.stringify")); } - void connect(); + void connect(bool redundantRefs = false, bool namesAsObjects = false); void interrupt(); void continueDebugging(StepAction stepAction); @@ -304,9 +304,13 @@ public: }; -void QJSDebugClient::connect() +void QJSDebugClient::connect(bool redundantRefs, bool namesAsObjects) { - sendMessage(packMessage(CONNECT)); + QJSValue jsonVal = parser.call(QJSValueList() << QLatin1String("{}")); + jsonVal.setProperty("redundantRefs", QJSValue(redundantRefs)); + jsonVal.setProperty("namesAsObjects", QJSValue(namesAsObjects)); + sendMessage(packMessage(CONNECT, + stringify.call(QJSValueList() << jsonVal).toString().toUtf8())); } void QJSDebugClient::interrupt() @@ -870,8 +874,10 @@ void tst_QQmlDebugJS::interrupt() //void connect() QFETCH(bool, qmlscene); + QFETCH(bool, redundantRefs); + QFETCH(bool, namesAsObjects); init(qmlscene); - client->connect(); + client->connect(redundantRefs, namesAsObjects); client->interrupt(); QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(interruptRequested()))); @@ -882,8 +888,10 @@ void tst_QQmlDebugJS::getVersion() //void version() QFETCH(bool, qmlscene); + QFETCH(bool, redundantRefs); + QFETCH(bool, namesAsObjects); init(qmlscene); - client->connect(); + client->connect(redundantRefs, namesAsObjects); QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(connected()))); client->version(); @@ -894,9 +902,11 @@ void tst_QQmlDebugJS::getVersionWhenAttaching() { //void version() QFETCH(bool, qmlscene); + QFETCH(bool, redundantRefs); + QFETCH(bool, namesAsObjects); init(qmlscene, QLatin1String(TIMER_QMLFILE), false); - client->connect(); + client->connect(redundantRefs, namesAsObjects); client->version(); QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result()))); @@ -907,8 +917,10 @@ void tst_QQmlDebugJS::disconnect() //void disconnect() QFETCH(bool, qmlscene); + QFETCH(bool, redundantRefs); + QFETCH(bool, namesAsObjects); init(qmlscene); - client->connect(); + client->connect(redundantRefs, namesAsObjects); client->disconnect(); QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result()))); @@ -918,12 +930,14 @@ void tst_QQmlDebugJS::setBreakpointInScriptOnCompleted() { //void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1) QFETCH(bool, qmlscene); + QFETCH(bool, redundantRefs); + QFETCH(bool, namesAsObjects); int sourceLine = 34; init(qmlscene, ONCOMPLETED_QMLFILE); client->setBreakpoint(QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true); - client->connect(); + client->connect(redundantRefs, namesAsObjects); QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); QString jsonString(client->response); @@ -939,12 +953,14 @@ void tst_QQmlDebugJS::setBreakpointInScriptOnComponentCreated() { //void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1) QFETCH(bool, qmlscene); + QFETCH(bool, redundantRefs); + QFETCH(bool, namesAsObjects); int sourceLine = 34; init(qmlscene, CREATECOMPONENT_QMLFILE); client->setBreakpoint(QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true); - client->connect(); + client->connect(redundantRefs, namesAsObjects); QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); QString jsonString(client->response); @@ -959,10 +975,12 @@ void tst_QQmlDebugJS::setBreakpointInScriptOnComponentCreated() void tst_QQmlDebugJS::setBreakpointInScriptOnTimerCallback() { QFETCH(bool, qmlscene); + QFETCH(bool, redundantRefs); + QFETCH(bool, namesAsObjects); int sourceLine = 35; init(qmlscene, TIMER_QMLFILE); - client->connect(); + client->connect(redundantRefs, namesAsObjects); //We can set the breakpoint after connect() here because the timer is repeating and if we miss //its first iteration we can still catch the second one. client->setBreakpoint(QLatin1String(TIMER_QMLFILE), sourceLine, -1, true); @@ -981,12 +999,14 @@ void tst_QQmlDebugJS::setBreakpointInScriptInDifferentFile() { //void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1) QFETCH(bool, qmlscene); + QFETCH(bool, redundantRefs); + QFETCH(bool, namesAsObjects); int sourceLine = 31; init(qmlscene, LOADJSFILE_QMLFILE); client->setBreakpoint(QLatin1String(TEST_JSFILE), sourceLine, -1, true); - client->connect(); + client->connect(redundantRefs, namesAsObjects); QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); QString jsonString(client->response); @@ -1002,13 +1022,15 @@ void tst_QQmlDebugJS::setBreakpointInScriptOnComment() { //void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1) QFETCH(bool, qmlscene); + QFETCH(bool, redundantRefs); + QFETCH(bool, namesAsObjects); int sourceLine = 34; int actualLine = 36; init(qmlscene, BREAKPOINTRELOCATION_QMLFILE); client->setBreakpoint(QLatin1String(BREAKPOINTRELOCATION_QMLFILE), sourceLine, -1, true); - client->connect(); + client->connect(redundantRefs, namesAsObjects); QEXPECT_FAIL("", "Relocation of breakpoints is disabled right now", Abort); QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()), 1)); @@ -1025,13 +1047,15 @@ void tst_QQmlDebugJS::setBreakpointInScriptOnEmptyLine() { //void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1) QFETCH(bool, qmlscene); + QFETCH(bool, redundantRefs); + QFETCH(bool, namesAsObjects); int sourceLine = 35; int actualLine = 36; init(qmlscene, BREAKPOINTRELOCATION_QMLFILE); client->setBreakpoint(QLatin1String(BREAKPOINTRELOCATION_QMLFILE), sourceLine, -1, true); - client->connect(); + client->connect(redundantRefs, namesAsObjects); QEXPECT_FAIL("", "Relocation of breakpoints is disabled right now", Abort); QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()), 1)); @@ -1048,12 +1072,14 @@ void tst_QQmlDebugJS::setBreakpointInScriptOnOptimizedBinding() { //void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1) QFETCH(bool, qmlscene); + QFETCH(bool, redundantRefs); + QFETCH(bool, namesAsObjects); int sourceLine = 39; init(qmlscene, BREAKPOINTRELOCATION_QMLFILE); client->setBreakpoint(QLatin1String(BREAKPOINTRELOCATION_QMLFILE), sourceLine, -1, true); - client->connect(); + client->connect(redundantRefs, namesAsObjects); QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); QString jsonString(client->response); @@ -1068,11 +1094,13 @@ void tst_QQmlDebugJS::setBreakpointInScriptOnOptimizedBinding() void tst_QQmlDebugJS::setBreakpointInScriptWithCondition() { QFETCH(bool, qmlscene); + QFETCH(bool, redundantRefs); + QFETCH(bool, namesAsObjects); int out = 10; int sourceLine = 37; init(qmlscene, CONDITION_QMLFILE); - client->connect(); + client->connect(redundantRefs, namesAsObjects); //The breakpoint is in a timer loop so we can set it after connect(). client->setBreakpoint(QLatin1String(CONDITION_QMLFILE), sourceLine, 1, true, QLatin1String("a > 10")); QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); @@ -1105,12 +1133,14 @@ void tst_QQmlDebugJS::setBreakpointInScriptWithCondition() void tst_QQmlDebugJS::setBreakpointInScriptThatQuits() { QFETCH(bool, qmlscene); + QFETCH(bool, redundantRefs); + QFETCH(bool, namesAsObjects); init(qmlscene, QUIT_QMLFILE); int sourceLine = 36; client->setBreakpoint(QLatin1String(QUIT_QMLFILE), sourceLine, -1, true); - client->connect(); + client->connect(redundantRefs, namesAsObjects); QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); QString jsonString(client->response); @@ -1147,12 +1177,14 @@ void tst_QQmlDebugJS::clearBreakpoint() { //void clearBreakpoint(int breakpoint); QFETCH(bool, qmlscene); + QFETCH(bool, redundantRefs); + QFETCH(bool, namesAsObjects); int sourceLine1 = 37; int sourceLine2 = 38; init(qmlscene, CHANGEBREAKPOINT_QMLFILE); - client->connect(); + client->connect(redundantRefs, namesAsObjects); //The breakpoints are in a timer loop so we can set them after connect(). //Furthermore the breakpoints should be hit in the right order because setting of breakpoints //can only occur in the QML event loop. (see QCOMPARE for sourceLine2 below) @@ -1195,10 +1227,12 @@ void tst_QQmlDebugJS::setExceptionBreak() { //void setExceptionBreak(QString type, bool enabled = false); QFETCH(bool, qmlscene); + QFETCH(bool, redundantRefs); + QFETCH(bool, namesAsObjects); init(qmlscene, EXCEPTION_QMLFILE); client->setExceptionBreak(QJSDebugClient::All,true); - client->connect(); + client->connect(redundantRefs, namesAsObjects); QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); } @@ -1206,12 +1240,14 @@ void tst_QQmlDebugJS::stepNext() { //void continueDebugging(StepAction stepAction, int stepCount = 1); QFETCH(bool, qmlscene); + QFETCH(bool, redundantRefs); + QFETCH(bool, namesAsObjects); int sourceLine = 37; init(qmlscene, STEPACTION_QMLFILE); client->setBreakpoint(QLatin1String(STEPACTION_QMLFILE), sourceLine, -1, true); - client->connect(); + client->connect(redundantRefs, namesAsObjects); QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); client->continueDebugging(QJSDebugClient::Next); @@ -1230,13 +1266,15 @@ void tst_QQmlDebugJS::stepIn() { //void continueDebugging(StepAction stepAction, int stepCount = 1); QFETCH(bool, qmlscene); + QFETCH(bool, redundantRefs); + QFETCH(bool, namesAsObjects); int sourceLine = 41; int actualLine = 37; init(qmlscene, STEPACTION_QMLFILE); client->setBreakpoint(QLatin1String(STEPACTION_QMLFILE), sourceLine, 1, true); - client->connect(); + client->connect(redundantRefs, namesAsObjects); QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); client->continueDebugging(QJSDebugClient::In); @@ -1255,13 +1293,15 @@ void tst_QQmlDebugJS::stepOut() { //void continueDebugging(StepAction stepAction, int stepCount = 1); QFETCH(bool, qmlscene); + QFETCH(bool, redundantRefs); + QFETCH(bool, namesAsObjects); int sourceLine = 37; int actualLine = 41; init(qmlscene, STEPACTION_QMLFILE); client->setBreakpoint(QLatin1String(STEPACTION_QMLFILE), sourceLine, -1, true); - client->connect(); + client->connect(redundantRefs, namesAsObjects); QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); client->continueDebugging(QJSDebugClient::Out); @@ -1280,6 +1320,8 @@ void tst_QQmlDebugJS::continueDebugging() { //void continueDebugging(StepAction stepAction, int stepCount = 1); QFETCH(bool, qmlscene); + QFETCH(bool, redundantRefs); + QFETCH(bool, namesAsObjects); int sourceLine1 = 41; int sourceLine2 = 38; @@ -1287,7 +1329,7 @@ void tst_QQmlDebugJS::continueDebugging() client->setBreakpoint(QLatin1String(STEPACTION_QMLFILE), sourceLine1, -1, true); client->setBreakpoint(QLatin1String(STEPACTION_QMLFILE), sourceLine2, -1, true); - client->connect(); + client->connect(redundantRefs, namesAsObjects); QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); client->continueDebugging(QJSDebugClient::Continue); @@ -1306,12 +1348,14 @@ void tst_QQmlDebugJS::backtrace() { //void backtrace(int fromFrame = -1, int toFrame = -1, bool bottom = false); QFETCH(bool, qmlscene); + QFETCH(bool, redundantRefs); + QFETCH(bool, namesAsObjects); int sourceLine = 34; init(qmlscene, ONCOMPLETED_QMLFILE); client->setBreakpoint(QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true); - client->connect(); + client->connect(redundantRefs, namesAsObjects); QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); client->backtrace(); @@ -1322,12 +1366,14 @@ void tst_QQmlDebugJS::getFrameDetails() { //void frame(int number = -1); QFETCH(bool, qmlscene); + QFETCH(bool, redundantRefs); + QFETCH(bool, namesAsObjects); int sourceLine = 34; init(qmlscene, ONCOMPLETED_QMLFILE); client->setBreakpoint(QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true); - client->connect(); + client->connect(redundantRefs, namesAsObjects); QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); client->frame(); @@ -1338,12 +1384,14 @@ void tst_QQmlDebugJS::getScopeDetails() { //void scope(int number = -1, int frameNumber = -1); QFETCH(bool, qmlscene); + QFETCH(bool, redundantRefs); + QFETCH(bool, namesAsObjects); int sourceLine = 34; init(qmlscene, ONCOMPLETED_QMLFILE); client->setBreakpoint(QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true); - client->connect(); + client->connect(redundantRefs, namesAsObjects); QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); client->scope(); @@ -1374,11 +1422,13 @@ void tst_QQmlDebugJS::evaluateInLocalScope() //void evaluate(QString expr, bool global = false, bool disableBreak = false, int frame = -1, const QVariantMap &addContext = QVariantMap()); QFETCH(bool, qmlscene); + QFETCH(bool, redundantRefs); + QFETCH(bool, namesAsObjects); int sourceLine = 34; init(qmlscene, ONCOMPLETED_QMLFILE); client->setBreakpoint(QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true); - client->connect(); + client->connect(redundantRefs, namesAsObjects); QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); client->frame(); @@ -1461,10 +1511,12 @@ void tst_QQmlDebugJS::getScripts() //void scripts(int types = -1, QList<int> ids = QList<int>(), bool includeSource = false, QVariant filter = QVariant()); QFETCH(bool, qmlscene); + QFETCH(bool, redundantRefs); + QFETCH(bool, namesAsObjects); init(qmlscene); client->setBreakpoint(QString(TEST_QMLFILE), 35, -1, true); - client->connect(); + client->connect(redundantRefs, namesAsObjects); QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); client->scripts(); @@ -1482,8 +1534,16 @@ void tst_QQmlDebugJS::getScripts() void tst_QQmlDebugJS::targetData() { QTest::addColumn<bool>("qmlscene"); - QTest::newRow("custom") << false; - QTest::newRow("qmlscene") << true; + QTest::addColumn<bool>("redundantRefs"); + QTest::addColumn<bool>("namesAsObjects"); + QTest::newRow("custom / redundant / objects") << false << true << true; + QTest::newRow("qmlscene / redundant / objects") << true << true << true; + QTest::newRow("custom / redundant / strings") << false << true << false; + QTest::newRow("qmlscene / redundant / strings") << true << true << false; + QTest::newRow("custom / sparse / objects") << false << false << true; + QTest::newRow("qmlscene / sparse / objects") << true << false << true; + QTest::newRow("custom / sparse / strings") << false << false << false; + QTest::newRow("qmlscene / sparse / strings") << true << false << false; } QTEST_MAIN(tst_QQmlDebugJS) diff --git a/tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp b/tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp index 8c30a82317..d9a4777115 100644 --- a/tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp +++ b/tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp @@ -180,14 +180,9 @@ void tst_QQmlEngineDebugService::recursiveObjectTest( { const QMetaObject *meta = o->metaObject(); - QQmlType *type = QQmlMetaType::qmlType(meta); - QString className = type ? QString(type->qmlTypeName()) - : QString(meta->className()); - className = className.mid(className.lastIndexOf(QLatin1Char('/'))+1); - QCOMPARE(oref.debugId, QQmlDebugService::idForObject(o)); QCOMPARE(oref.name, o->objectName()); - QCOMPARE(oref.className, className); + QCOMPARE(oref.className, QQmlMetaType::prettyTypeName(o)); QCOMPARE(oref.contextDebugId, QQmlDebugService::idForObject( qmlContext(o))); @@ -201,6 +196,7 @@ void tst_QQmlEngineDebugService::recursiveObjectTest( QmlDebugObjectReference cref; foreach (const QmlDebugObjectReference &ref, oref.children) { + QVERIFY(!ref.className.isEmpty()); if (ref.debugId == debugId) { cref = ref; break; @@ -369,6 +365,7 @@ void tst_QQmlEngineDebugService::setMethodBody() { bool success; QmlDebugObjectReference obj = findRootObject(2); + QVERIFY(!obj.className.isEmpty()); QObject *root = m_components.at(2); // Without args @@ -410,6 +407,7 @@ void tst_QQmlEngineDebugService::setMethodBody() void tst_QQmlEngineDebugService::watch_property() { QmlDebugObjectReference obj = findRootObject(); + QVERIFY(!obj.className.isEmpty()); QmlDebugPropertyReference prop = findProperty(obj.properties, "width"); bool success; @@ -454,6 +452,7 @@ void tst_QQmlEngineDebugService::watch_property() void tst_QQmlEngineDebugService::watch_object() { QmlDebugObjectReference obj = findRootObject(); + QVERIFY(!obj.className.isEmpty()); bool success; @@ -519,6 +518,7 @@ void tst_QQmlEngineDebugService::watch_expression() int origWidth = m_rootItem->property("width").toInt(); QmlDebugObjectReference obj = findRootObject(); + QVERIFY(!obj.className.isEmpty()); bool success; @@ -654,6 +654,7 @@ void tst_QQmlEngineDebugService::queryObject() bool success; QmlDebugObjectReference rootObject = findRootObject(); + QVERIFY(!rootObject.className.isEmpty()); QQmlEngineDebugClient *unconnected = new QQmlEngineDebugClient(0); recursive ? unconnected->queryObjectRecursive(rootObject, &success) : unconnected->queryObject(rootObject, &success); @@ -665,6 +666,7 @@ void tst_QQmlEngineDebugService::queryObject() QVERIFY(QQmlDebugTest::waitForSignal(m_dbg, SIGNAL(result()))); QmlDebugObjectReference obj = m_dbg->object(); + QVERIFY(!obj.className.isEmpty()); // check source as defined in main() QmlDebugFileReference source = obj.source; @@ -676,12 +678,15 @@ void tst_QQmlEngineDebugService::queryObject() recursiveObjectTest(m_rootItem, obj, recursive); if (recursive) { - foreach (const QmlDebugObjectReference &child, obj.children) + foreach (const QmlDebugObjectReference &child, obj.children) { + QVERIFY(!child.className.isEmpty()); QVERIFY(child.properties.count() > 0); + } QmlDebugObjectReference rect; QmlDebugObjectReference text; foreach (const QmlDebugObjectReference &child, obj.children) { + QVERIFY(!child.className.isEmpty()); if (child.className == "Rectangle") rect = child; else if (child.className == "Text") @@ -695,8 +700,10 @@ void tst_QQmlEngineDebugService::queryObject() QCOMPARE(findProperty(text.properties, "color").value, qVariantFromValue(QColor("blue"))); } else { - foreach (const QmlDebugObjectReference &child, obj.children) + foreach (const QmlDebugObjectReference &child, obj.children) { + QVERIFY(!child.className.isEmpty()); QCOMPARE(child.properties.count(), 0); + } } } @@ -715,6 +722,7 @@ void tst_QQmlEngineDebugService::queryObjectsForLocation() bool success; QmlDebugObjectReference rootObject = findRootObject(); + QVERIFY(!rootObject.className.isEmpty()); const QString fileName = QFileInfo(rootObject.source.url.toString()).fileName(); int lineNumber = rootObject.source.lineNumber; @@ -737,6 +745,7 @@ void tst_QQmlEngineDebugService::queryObjectsForLocation() QCOMPARE(m_dbg->objects().count(), 1); QmlDebugObjectReference obj = m_dbg->objects().first(); + QVERIFY(!obj.className.isEmpty()); // check source as defined in main() QmlDebugFileReference source = obj.source; @@ -748,12 +757,15 @@ void tst_QQmlEngineDebugService::queryObjectsForLocation() recursiveObjectTest(m_rootItem, obj, recursive); if (recursive) { - foreach (const QmlDebugObjectReference &child, obj.children) + foreach (const QmlDebugObjectReference &child, obj.children) { + QVERIFY(!child.className.isEmpty()); QVERIFY(child.properties.count() > 0); + } QmlDebugObjectReference rect; QmlDebugObjectReference text; foreach (const QmlDebugObjectReference &child, obj.children) { + QVERIFY(!child.className.isEmpty()); if (child.className == "Rectangle") rect = child; else if (child.className == "Text") @@ -767,8 +779,10 @@ void tst_QQmlEngineDebugService::queryObjectsForLocation() QCOMPARE(findProperty(text.properties, "color").value, qVariantFromValue(QColor("blue"))); } else { - foreach (const QmlDebugObjectReference &child, obj.children) + foreach (const QmlDebugObjectReference &child, obj.children) { + QVERIFY(!child.className.isEmpty()); QCOMPARE(child.properties.count(), 0); + } } } @@ -783,6 +797,7 @@ void tst_QQmlEngineDebugService::queryObjectsForLocation_data() void tst_QQmlEngineDebugService::regression_QTCREATORBUG_7451() { QmlDebugObjectReference rootObject = findRootObject(); + QVERIFY(!rootObject.className.isEmpty()); int contextId = rootObject.contextDebugId; QQmlContext *context = qobject_cast<QQmlContext *>(QQmlDebugService::objectForId(contextId)); QQmlComponent component(context->engine()); @@ -809,6 +824,7 @@ void tst_QQmlEngineDebugService::regression_QTCREATORBUG_7451() QVERIFY(QQmlDebugTest::waitForSignal(m_dbg, SIGNAL(result()))); foreach (QmlDebugObjectReference child, rootObject.children) { + QVERIFY(!child.className.isEmpty()); success = false; lineNumber = child.source.lineNumber; columnNumber = child.source.columnNumber; @@ -831,6 +847,7 @@ void tst_QQmlEngineDebugService::regression_QTCREATORBUG_7451() QVERIFY(QQmlDebugTest::waitForSignal(m_dbg, SIGNAL(result()))); foreach (QmlDebugObjectReference child, rootObject.children) { + QVERIFY(!child.className.isEmpty()); success = false; lineNumber = child.source.lineNumber; columnNumber = child.source.columnNumber; @@ -846,6 +863,7 @@ void tst_QQmlEngineDebugService::queryObjectWithNonStreamableTypes() bool success; QmlDebugObjectReference rootObject = findRootObject(4, true); + QVERIFY(!rootObject.className.isEmpty()); QQmlEngineDebugClient *unconnected = new QQmlEngineDebugClient(0); unconnected->queryObject(rootObject, &success); @@ -857,6 +875,7 @@ void tst_QQmlEngineDebugService::queryObjectWithNonStreamableTypes() QVERIFY(QQmlDebugTest::waitForSignal(m_dbg, SIGNAL(result()))); QmlDebugObjectReference obj = m_dbg->object(); + QVERIFY(!obj.className.isEmpty()); QCOMPARE(findProperty(obj.properties, "modelIndex").value, QVariant()); } @@ -950,6 +969,7 @@ void tst_QQmlEngineDebugService::queryExpressionResultBC_data() void tst_QQmlEngineDebugService::setBindingForObject() { QmlDebugObjectReference rootObject = findRootObject(); + QVERIFY(!rootObject.className.isEmpty()); QVERIFY(rootObject.debugId != -1); QmlDebugPropertyReference widthPropertyRef = findProperty(rootObject.properties, "width"); @@ -967,6 +987,7 @@ void tst_QQmlEngineDebugService::setBindingForObject() QCOMPARE(m_dbg->valid(), true); rootObject = findRootObject(); + QVERIFY(!rootObject.className.isEmpty()); widthPropertyRef = findProperty(rootObject.properties, "width"); QCOMPARE(widthPropertyRef.value, QVariant(15)); @@ -982,6 +1003,7 @@ void tst_QQmlEngineDebugService::setBindingForObject() QCOMPARE(m_dbg->valid(), true); rootObject = findRootObject(); + QVERIFY(!rootObject.className.isEmpty()); widthPropertyRef = findProperty(rootObject.properties, "width"); QCOMPARE(widthPropertyRef.value, QVariant(20)); @@ -992,13 +1014,14 @@ void tst_QQmlEngineDebugService::setBindingForObject() // set handler // rootObject = findRootObject(); + QVERIFY(!rootObject.className.isEmpty()); QCOMPARE(rootObject.children.size(), 5); // Rectangle, Text, MouseArea, Component.onCompleted, NonScriptPropertyElement QmlDebugObjectReference mouseAreaObject = rootObject.children.at(2); + QVERIFY(!mouseAreaObject.className.isEmpty()); m_dbg->queryObjectRecursive(mouseAreaObject, &success); QVERIFY(success); QVERIFY(QQmlDebugTest::waitForSignal(m_dbg, SIGNAL(result()))); mouseAreaObject = m_dbg->object(); - QCOMPARE(mouseAreaObject.className, QString("MouseArea")); QmlDebugPropertyReference onEnteredRef = findProperty(mouseAreaObject.properties, "onEntered"); @@ -1015,11 +1038,14 @@ void tst_QQmlEngineDebugService::setBindingForObject() QCOMPARE(m_dbg->valid(), true); rootObject = findRootObject(); + QVERIFY(!rootObject.className.isEmpty()); mouseAreaObject = rootObject.children.at(2); + QVERIFY(!mouseAreaObject.className.isEmpty()); m_dbg->queryObjectRecursive(mouseAreaObject, &success); QVERIFY(success); QVERIFY(QQmlDebugTest::waitForSignal(m_dbg, SIGNAL(result()))); mouseAreaObject = m_dbg->object(); + QVERIFY(!mouseAreaObject.className.isEmpty()); onEnteredRef = findProperty(mouseAreaObject.properties, "onEntered"); QCOMPARE(onEnteredRef.name, QString("onEntered")); QCOMPARE(onEnteredRef.value, QVariant("function() { [code] }")); @@ -1028,6 +1054,7 @@ void tst_QQmlEngineDebugService::setBindingForObject() void tst_QQmlEngineDebugService::resetBindingForObject() { QmlDebugObjectReference rootObject = findRootObject(); + QVERIFY(!rootObject.className.isEmpty()); QVERIFY(rootObject.debugId != -1); QmlDebugPropertyReference widthPropertyRef = findProperty(rootObject.properties, "width"); @@ -1048,6 +1075,7 @@ void tst_QQmlEngineDebugService::resetBindingForObject() QCOMPARE(m_dbg->valid(), true); rootObject = findRootObject(); + QVERIFY(!rootObject.className.isEmpty()); widthPropertyRef = findProperty(rootObject.properties, "width"); QCOMPARE(widthPropertyRef.value, QVariant(0)); @@ -1063,6 +1091,7 @@ void tst_QQmlEngineDebugService::resetBindingForObject() QCOMPARE(m_dbg->valid(), true); rootObject = findRootObject(); + QVERIFY(!rootObject.className.isEmpty()); QmlDebugPropertyReference boldPropertyRef = findProperty(rootObject.properties, "font.bold"); QCOMPARE(boldPropertyRef.value.toBool(), false); @@ -1076,7 +1105,7 @@ void tst_QQmlEngineDebugService::setBindingInStates() const int sourceIndex = 3; QmlDebugObjectReference obj = findRootObject(sourceIndex); - + QVERIFY(!obj.className.isEmpty()); QVERIFY(obj.debugId != -1); QVERIFY(obj.children.count() >= 2); bool success; @@ -1092,6 +1121,7 @@ void tst_QQmlEngineDebugService::setBindingInStates() QVERIFY(QQmlDebugTest::waitForSignal(m_dbg, SIGNAL(result()))); obj = findRootObject(sourceIndex); + QVERIFY(!obj.className.isEmpty()); QCOMPARE(findProperty(obj.properties,"width").value.toInt(),200); @@ -1102,6 +1132,7 @@ void tst_QQmlEngineDebugService::setBindingInStates() obj = findRootObject(sourceIndex, true); + QVERIFY(!obj.className.isEmpty()); QCOMPARE(findProperty(obj.properties,"width").value.toInt(),100); @@ -1111,6 +1142,7 @@ void tst_QQmlEngineDebugService::setBindingInStates() QVERIFY(state.children.count() > 0); QmlDebugObjectReference propertyChange = state.children[0]; + QVERIFY(!propertyChange.className.isEmpty()); QVERIFY(propertyChange.debugId != -1); m_dbg->setBindingForObject(propertyChange.debugId, "width",QVariant(300),true, @@ -1120,6 +1152,7 @@ void tst_QQmlEngineDebugService::setBindingInStates() // check properties changed in state obj = findRootObject(sourceIndex); + QVERIFY(!obj.className.isEmpty()); QCOMPARE(findProperty(obj.properties,"width").value.toInt(),100); @@ -1128,6 +1161,7 @@ void tst_QQmlEngineDebugService::setBindingInStates() QVERIFY(QQmlDebugTest::waitForSignal(m_dbg, SIGNAL(result()))); obj = findRootObject(sourceIndex); + QVERIFY(!obj.className.isEmpty()); QCOMPARE(findProperty(obj.properties,"width").value.toInt(),300); // check changing properties of base state from within a state @@ -1141,6 +1175,7 @@ void tst_QQmlEngineDebugService::setBindingInStates() QVERIFY(QQmlDebugTest::waitForSignal(m_dbg, SIGNAL(result()))); obj = findRootObject(sourceIndex); + QVERIFY(!obj.className.isEmpty()); QCOMPARE(findProperty(obj.properties,"width").value.toInt(),300); m_dbg->queryExpressionResult(obj.debugId,QString("state=\"\""), &success); @@ -1148,6 +1183,7 @@ void tst_QQmlEngineDebugService::setBindingInStates() QVERIFY(QQmlDebugTest::waitForSignal(m_dbg, SIGNAL(result()))); obj = findRootObject(sourceIndex); + QVERIFY(!obj.className.isEmpty()); QCOMPARE(findProperty(obj.properties,"width").value.toInt(), 400); // reset binding while in a state @@ -1156,6 +1192,7 @@ void tst_QQmlEngineDebugService::setBindingInStates() QVERIFY(QQmlDebugTest::waitForSignal(m_dbg, SIGNAL(result()))); obj = findRootObject(sourceIndex); + QVERIFY(!obj.className.isEmpty()); QCOMPARE(findProperty(obj.properties,"width").value.toInt(), 300); m_dbg->resetBindingForObject(propertyChange.debugId, "width", &success); @@ -1164,6 +1201,7 @@ void tst_QQmlEngineDebugService::setBindingInStates() QCOMPARE(m_dbg->valid(), true); obj = findRootObject(sourceIndex); + QVERIFY(!obj.className.isEmpty()); QCOMPARE(findProperty(obj.properties,"width").value.toInt(), 400); // re-add binding @@ -1174,6 +1212,7 @@ void tst_QQmlEngineDebugService::setBindingInStates() QCOMPARE(m_dbg->valid(), true); obj = findRootObject(sourceIndex); + QVERIFY(!obj.className.isEmpty()); QCOMPARE(findProperty(obj.properties,"width").value.toInt(), 300); } @@ -1182,7 +1221,7 @@ void tst_QQmlEngineDebugService::queryObjectTree() const int sourceIndex = 3; QmlDebugObjectReference obj = findRootObject(sourceIndex, true); - + QVERIFY(!obj.className.isEmpty()); QVERIFY(obj.debugId != -1); QVERIFY(obj.children.count() >= 2); @@ -1192,16 +1231,16 @@ void tst_QQmlEngineDebugService::queryObjectTree() QVERIFY(state.children.count() > 0); QmlDebugObjectReference propertyChange = state.children[0]; + QVERIFY(!propertyChange.className.isEmpty()); QVERIFY(propertyChange.debugId != -1); QmlDebugPropertyReference propertyChangeTarget = findProperty(propertyChange.properties,"target"); QCOMPARE(propertyChangeTarget.objectDebugId, propertyChange.debugId); QmlDebugObjectReference targetReference = qvariant_cast<QmlDebugObjectReference>(propertyChangeTarget.value); + QVERIFY(!targetReference.className.isEmpty()); QVERIFY(targetReference.debugId != -1); - - // check transition QmlDebugObjectReference transition = obj.children[0]; QCOMPARE(transition.className, QString("Transition")); @@ -1210,12 +1249,14 @@ void tst_QQmlEngineDebugService::queryObjectTree() QVERIFY(transition.children.count() > 0); QmlDebugObjectReference animation = transition.children[0]; + QVERIFY(!animation.className.isEmpty()); QVERIFY(animation.debugId != -1); QmlDebugPropertyReference animationTarget = findProperty(animation.properties,"target"); QCOMPARE(animationTarget.objectDebugId, animation.debugId); targetReference = qvariant_cast<QmlDebugObjectReference>(animationTarget.value); + QVERIFY(!targetReference.className.isEmpty()); QVERIFY(targetReference.debugId != -1); QCOMPARE(findProperty(animation.properties,"property").value.toString(), QString("width")); diff --git a/tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp b/tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp index 6793596174..584bd10151 100644 --- a/tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp +++ b/tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp @@ -120,7 +120,6 @@ public: typedef QV4DataCollector::Refs Refs; typedef QV4DataCollector::Ref Ref; struct NamedRefs { - QJsonArray refs; QJsonObject scope; int size() const { @@ -131,15 +130,6 @@ public: return scope.contains(name); } - QJsonObject resolveRef(int ref) const { - foreach (const QJsonValue &val, refs) { - QJsonObject obj = val.toObject(); - if (obj.value(QLatin1String("handle")).toInt() == ref) - return obj; - } - return QJsonObject(); - } - #define DUMP_JSON(x) {\ QJsonDocument doc(x);\ qDebug() << #x << "=" << doc.toJson(QJsonDocument::Indented);\ @@ -176,6 +166,7 @@ public: , m_captureContextInfo(false) , m_thrownValue(-1) , collector(engine) + , m_resumeSpeed(QV4Debugger::FullThrottle) , m_debugger(0) { } @@ -208,13 +199,12 @@ public slots: request.expression, &collector); debugger->runInEngine(&job); m_expressionResults << job.returnValue(); - m_expressionRefs << job.refs(); } if (m_captureContextInfo) captureContextInfo(debugger); - debugger->resume(QV4Debugger::FullThrottle); + debugger->resume(m_resumeSpeed); } public: @@ -234,24 +224,17 @@ public: ScopeJob job(&collector, i, 0); debugger->runInEngine(&job); NamedRefs &refs = m_capturedScope.last(); - refs.refs = job.refs(); QJsonObject object = job.returnValue(); object = object.value(QLatin1String("object")).toObject(); - int ref = object.value(QLatin1String("ref")).toInt(); - object = refs.resolveRef(ref); + if (object.contains("ref") && !object.contains("properties")) { + QVERIFY(collector.redundantRefs()); + object = collector.lookupRef(object.value("ref").toInt(), true); + QVERIFY(object.contains("properties")); + } foreach (const QJsonValue &value, object.value(QLatin1String("properties")).toArray()) { QJsonObject property = value.toObject(); QString name = property.value(QLatin1String("name")).toString(); property.remove(QLatin1String("name")); - if (property.contains(QLatin1String("ref"))) { - int childRef = property.value(QLatin1String("ref")).toInt(); - if (childRef >= 0 && refs.refs.size() > childRef) { - property.remove(QLatin1String("ref")); - property.insert(QLatin1String("properties"), - refs.resolveRef(childRef).value( - QLatin1String("properties")).toArray()); - } - } refs.scope.insert(name, property); } } @@ -280,8 +263,8 @@ public: int context; }; QVector<ExpressionRequest> m_expressionRequests; + QV4Debugger::Speed m_resumeSpeed; QList<QJsonObject> m_expressionResults; - QList<QJsonArray> m_expressionRefs; QV4Debugger *m_debugger; // Utility methods: @@ -313,9 +296,13 @@ private slots: void conditionalBreakPointInQml(); // context access: + void readArguments_data() { redundancy_data(); } void readArguments(); + void readLocals_data() { redundancy_data(); } void readLocals(); + void readObject_data() { redundancy_data(); } void readObject(); + void readContextInAllFrames_data() { redundancy_data(); } void readContextInAllFrames(); // exceptions: @@ -323,8 +310,13 @@ private slots: void breakInCatch(); void breakInWith(); + void evaluateExpression_data() { redundancy_data(); } void evaluateExpression(); + void stepToEndOfScript_data() { redundancy_data(); } + void stepToEndOfScript(); + void lastLineOfConditional_data(); + void lastLineOfConditional(); private: QV4Debugger *debugger() const { @@ -338,6 +330,8 @@ private: waitForSignal(m_engine, SIGNAL(evaluateFinished()), /*timeout*/0); } + void redundancy_data(); + TestEngine *m_engine; QV4::ExecutionEngine *m_v4; TestAgent *m_debuggerAgent; @@ -532,6 +526,9 @@ void tst_qv4debugger::conditionalBreakPointInQml() void tst_qv4debugger::readArguments() { + QFETCH(bool, redundantRefs); + m_debuggerAgent->collector.setRedundantRefs(redundantRefs); + m_debuggerAgent->m_captureContextInfo = true; QString script = "function f(a, b, c, d) {\n" @@ -555,6 +552,9 @@ void tst_qv4debugger::readArguments() void tst_qv4debugger::readLocals() { + QFETCH(bool, redundantRefs); + m_debuggerAgent->collector.setRedundantRefs(redundantRefs); + m_debuggerAgent->m_captureContextInfo = true; QString script = "function f(a, b) {\n" @@ -578,6 +578,9 @@ void tst_qv4debugger::readLocals() void tst_qv4debugger::readObject() { + QFETCH(bool, redundantRefs); + m_debuggerAgent->collector.setRedundantRefs(redundantRefs); + m_debuggerAgent->m_captureContextInfo = true; QString script = "function f(a) {\n" @@ -594,6 +597,12 @@ void tst_qv4debugger::readObject() QVERIFY(frame0.contains("b")); QCOMPARE(frame0.type("b"), QStringLiteral("object")); QJsonObject b = frame0.rawValue("b"); + QVERIFY(b.contains(QStringLiteral("ref"))); + QVERIFY(b.contains(QStringLiteral("value"))); + QVERIFY(!b.contains(QStringLiteral("properties"))); + QVERIFY(b.value("value").isDouble()); + QCOMPARE(b.value("value").toInt(), 2); + b = m_debuggerAgent->collector.lookupRef(b.value("ref").toInt(), true); QVERIFY(b.contains(QStringLiteral("properties"))); QVERIFY(b.value("properties").isArray()); QJsonArray b_props = b.value("properties").toArray(); @@ -609,7 +618,8 @@ void tst_qv4debugger::readObject() QCOMPARE(b_tail.value("name").toString(), QStringLiteral("tail")); QVERIFY(b_tail.contains("ref")); - QJsonObject b_tail_value = m_debuggerAgent->collector.lookupRef(b_tail.value("ref").toInt()); + QJsonObject b_tail_value = m_debuggerAgent->collector.lookupRef(b_tail.value("ref").toInt(), + true); QCOMPARE(b_tail_value.value("type").toString(), QStringLiteral("object")); QVERIFY(b_tail_value.contains("properties")); QJsonArray b_tail_props = b_tail_value.value("properties").toArray(); @@ -626,6 +636,9 @@ void tst_qv4debugger::readObject() void tst_qv4debugger::readContextInAllFrames() { + QFETCH(bool, redundantRefs); + m_debuggerAgent->collector.setRedundantRefs(redundantRefs); + m_debuggerAgent->m_captureContextInfo = true; QString script = "function fact(n) {\n" @@ -673,7 +686,8 @@ void tst_qv4debugger::pauseOnThrow() QCOMPARE(m_debuggerAgent->m_pauseReason, QV4Debugger::Throwing); QCOMPARE(m_debuggerAgent->m_stackTrace.size(), 2); QVERIFY(m_debuggerAgent->m_thrownValue >= qint64(0)); - QJsonObject exception = m_debuggerAgent->collector.lookupRef(m_debuggerAgent->m_thrownValue); + QJsonObject exception = m_debuggerAgent->collector.lookupRef(m_debuggerAgent->m_thrownValue, + true); // DUMP_JSON(exception); QCOMPARE(exception.value("type").toString(), QStringLiteral("string")); QCOMPARE(exception.value("value").toString(), QStringLiteral("hard")); @@ -717,6 +731,9 @@ void tst_qv4debugger::breakInWith() void tst_qv4debugger::evaluateExpression() { + QFETCH(bool, redundantRefs); + m_debuggerAgent->collector.setRedundantRefs(redundantRefs); + QString script = "function testFunction() {\n" " var x = 10\n" @@ -745,19 +762,119 @@ void tst_qv4debugger::evaluateExpression() evaluateJavaScript(script, "evaluateExpression"); - QCOMPARE(m_debuggerAgent->m_expressionRefs.count(), 4); - QCOMPARE(m_debuggerAgent->m_expressionRefs[0].size(), 1); - QJsonObject result0 = m_debuggerAgent->m_expressionRefs[0].first().toObject(); + QCOMPARE(m_debuggerAgent->m_expressionResults.count(), 4); + QJsonObject result0 = m_debuggerAgent->m_expressionResults[0]; QCOMPARE(result0.value("type").toString(), QStringLiteral("number")); QCOMPARE(result0.value("value").toInt(), 10); for (int i = 1; i < 4; ++i) { - QCOMPARE(m_debuggerAgent->m_expressionRefs[i].size(), 1); - QJsonObject result1 = m_debuggerAgent->m_expressionRefs[1].first().toObject(); + QJsonObject result1 = m_debuggerAgent->m_expressionResults[i]; QCOMPARE(result1.value("type").toString(), QStringLiteral("number")); QCOMPARE(result1.value("value").toInt(), 20); } } +void tst_qv4debugger::stepToEndOfScript() +{ + QFETCH(bool, redundantRefs); + m_debuggerAgent->collector.setRedundantRefs(redundantRefs); + + QString script = + "var ret = 0;\n" + "ret += 4;\n" + "ret += 1;\n" + "ret += 5;\n"; + + debugger()->addBreakPoint("toEnd", 1); + m_debuggerAgent->m_resumeSpeed = QV4Debugger::StepOver; + evaluateJavaScript(script, "toEnd"); + QVERIFY(m_debuggerAgent->m_wasPaused); + QCOMPARE(m_debuggerAgent->m_pauseReason, QV4Debugger::Step); + QCOMPARE(m_debuggerAgent->m_statesWhenPaused.count(), 5); + for (int i = 0; i < 4; ++i) { + QV4Debugger::ExecutionState state = m_debuggerAgent->m_statesWhenPaused.at(i); + QCOMPARE(state.fileName, QString("toEnd")); + QCOMPARE(state.lineNumber, i + 1); + } + + QV4Debugger::ExecutionState state = m_debuggerAgent->m_statesWhenPaused.at(4); + QCOMPARE(state.fileName, QString("toEnd")); + QCOMPARE(state.lineNumber, -4); // A return instruction without proper line number. +} + +void tst_qv4debugger::lastLineOfConditional_data() +{ + QTest::addColumn<QString>("head"); + QTest::addColumn<QString>("tail"); + QTest::addColumn<int>("breakPoint"); + QTest::addColumn<int>("lastLine"); + + QTest::newRow("for {block}") << "for (var i = 0; i < 10; ++i) {\n" << "}" << 4 << 7; + QTest::newRow("for..in {block}") << "for (var i in [0, 1, 2, 3, 4]) {\n" << "}" << 4 << 7; + QTest::newRow("while {block}") << "while (ret < 10) {\n" << "}" << 4 << 7; + QTest::newRow("do..while {block}") << "do {\n" << "} while (ret < 10);" << 4 << 7; + + QTest::newRow("if true {block}") << "if (true) {\n" << "}" + << 4 << 7; + QTest::newRow("if false {block}") << "if (false) {\n" << "}" + << 2 << 8; + QTest::newRow("if true else {block}") << "if (true) {\n" << "} else {\n ret += 8;\n}" + << 4 << 7; + QTest::newRow("if false else {block}") << "if (false) {\n" << "} else {\n ret += 8;\n}" + << 8 << 9; + + QTest::newRow("for statement") << "for (var i = 0; i < 10; ++i)\n" << "" << 4 << 2; + QTest::newRow("for..in statement") << "for (var i in [0, 1, 2, 3, 4])\n" << "" << 4 << 2; + QTest::newRow("while statement") << "while (ret < 10)\n" << "" << 4 << 2; + QTest::newRow("do..while statement") << "do\n" << "while (ret < 10);" << 4 << 7; + + // For two nested if statements without blocks, we need to map the jump from the inner to the + // outer one on the outer "if". There is just no better place. + QTest::newRow("if true statement") << "if (true)\n" << "" << 4 << 2; + QTest::newRow("if false statement") << "if (false)\n" << "" << 2 << 8; + + // Also two nested ifs without blocks. + QTest::newRow("if true else statement") << "if (true)\n" << "else\n ret += 8;" << 4 << 2; + QTest::newRow("if false else statement") << "if (false)\n" << "else\n ret += 8;" << 8 << 9; +} + +void tst_qv4debugger::lastLineOfConditional() +{ + QFETCH(QString, head); + QFETCH(QString, tail); + QFETCH(int, breakPoint); + QFETCH(int, lastLine); + + QString script = + "var ret = 2;\n" + + head + + " if (ret == 2)\n" + " ret += 4;\n" // breakpoint, then step over + " else\n" + " ret += 1;\n" + + tail + "\n" + + "ret -= 5;"; + + debugger()->addBreakPoint("trueBranch", breakPoint); + m_debuggerAgent->m_resumeSpeed = QV4Debugger::StepOver; + evaluateJavaScript(script, "trueBranch"); + QVERIFY(m_debuggerAgent->m_wasPaused); + QCOMPARE(m_debuggerAgent->m_pauseReason, QV4Debugger::Step); + QVERIFY(m_debuggerAgent->m_statesWhenPaused.count() > 1); + QV4Debugger::ExecutionState firstState = m_debuggerAgent->m_statesWhenPaused.first(); + QCOMPARE(firstState.fileName, QString("trueBranch")); + QCOMPARE(firstState.lineNumber, breakPoint); + QV4Debugger::ExecutionState secondState = m_debuggerAgent->m_statesWhenPaused.at(1); + QCOMPARE(secondState.fileName, QString("trueBranch")); + QCOMPARE(secondState.lineNumber, lastLine); +} + +void tst_qv4debugger::redundancy_data() +{ + QTest::addColumn<bool>("redundantRefs"); + QTest::addRow("redundant") << true; + QTest::addRow("sparse") << false; +} + QTEST_MAIN(tst_qv4debugger) #include "tst_qv4debugger.moc" diff --git a/tests/auto/qml/debugger/shared/qqmlenginedebugclient.cpp b/tests/auto/qml/debugger/shared/qqmlenginedebugclient.cpp index 3e27951d78..c0252a0290 100644 --- a/tests/auto/qml/debugger/shared/qqmlenginedebugclient.cpp +++ b/tests/auto/qml/debugger/shared/qqmlenginedebugclient.cpp @@ -386,6 +386,7 @@ void QQmlEngineDebugClient::decode(QPacket &ds, { QmlDebugObjectReference obj; obj.debugId = prop.value.toInt(); + obj.className = prop.valueTypeName; prop.value = qVariantFromValue(obj); break; } diff --git a/tests/manual/v4/TestExpectations b/tests/auto/qml/ecmascripttests/TestExpectations index 27498de473..27498de473 100644 --- a/tests/manual/v4/TestExpectations +++ b/tests/auto/qml/ecmascripttests/TestExpectations diff --git a/tests/auto/qml/ecmascripttests/ecmascripttests.pro b/tests/auto/qml/ecmascripttests/ecmascripttests.pro new file mode 100644 index 0000000000..6d3ee12307 --- /dev/null +++ b/tests/auto/qml/ecmascripttests/ecmascripttests.pro @@ -0,0 +1,20 @@ +CONFIG += testcase +TARGET = tst_ecmascripttests +QT += testlib +macos:CONFIG -= app_bundle +SOURCES += tst_ecmascripttests.cpp +DEFINES += SRCDIR=\\\"$$PWD\\\" + +TESTSCRIPT=$$PWD/test262.py +isEmpty(V4CMD): V4CMD = qmljs + +checkjittarget.target = check-jit +checkjittarget.commands = python $$TESTSCRIPT --command=$$V4CMD --parallel --with-test-expectations --update-expectations +checkjittarget.depends = all +QMAKE_EXTRA_TARGETS += checkjittarget + +checkmothtarget.target = check-interpreter +checkmothtarget.commands = python $$TESTSCRIPT --command=\"$$V4CMD --interpret\" --parallel --with-test-expectations +checkmothtarget.depends = all +QMAKE_EXTRA_TARGETS += checkmothtarget + diff --git a/tests/auto/qml/ecmascripttests/test262 b/tests/auto/qml/ecmascripttests/test262 new file mode 160000 +Subproject d60c4ed97e69639bc5bc1db43a98828debf80c8 diff --git a/tests/manual/v4/test262.py b/tests/auto/qml/ecmascripttests/test262.py index 3b5bfa119a..99f029cffd 100755 --- a/tests/manual/v4/test262.py +++ b/tests/auto/qml/ecmascripttests/test262.py @@ -555,6 +555,7 @@ class TestSuite(object): print if update_expectations: self.expectations.update(progress) + return progress.failed == 0 def Print(self, tests): cases = self.EnumerateTests(tests) @@ -567,6 +568,7 @@ def Main(): # Uncomment the next line for more logging info. #logging.basicConfig(level=logging.DEBUG) os.environ["TZ"] = "PST8PDT" + os.environ["LANG"] = "en_US.UTF-8" parser = BuildOptions() (options, args) = parser.parse_args() ValidateOptions(options) @@ -578,18 +580,21 @@ def Main(): test_suite.Validate() if options.cat: test_suite.Print(args) + return 0 else: - test_suite.Run(options.command, args, - options.summary or options.full_summary, - options.full_summary, - options.parallel, - options.update_expectations) + if test_suite.Run(options.command, args, + options.summary or options.full_summary, + options.full_summary, + options.parallel, + options.update_expectations): + return 0 + else: + return 1 if __name__ == '__main__': try: - Main() - sys.exit(0) + sys.exit(Main()) except Test262Error, e: print "Error: %s" % e.message sys.exit(1) diff --git a/tests/auto/qml/ecmascripttests/tst_ecmascripttests.cpp b/tests/auto/qml/ecmascripttests/tst_ecmascripttests.cpp new file mode 100644 index 0000000000..5d7009e7c8 --- /dev/null +++ b/tests/auto/qml/ecmascripttests/tst_ecmascripttests.cpp @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include <QtTest/QtTest> +#include <QProcess> +#include <QLibraryInfo> + +class tst_EcmaScriptTests : public QObject +{ + Q_OBJECT +private slots: + void runTests_data(); + void runTests(); +}; + +void tst_EcmaScriptTests::runTests_data() +{ + QTest::addColumn<QString>("qmljsParameter"); + + QTest::newRow("jit") << QStringLiteral("--jit"); + // Not passing yet: QTest::newRow("interpreter") << QStringLiteral("--interpret"); +} + +void tst_EcmaScriptTests::runTests() +{ +#if defined(Q_OS_LINUX) && defined(Q_PROCESSOR_X86_64) + QFETCH(QString, qmljsParameter); + + QProcess process; + process.setProcessChannelMode(QProcess::ForwardedChannels); + process.setWorkingDirectory(QLatin1String(SRCDIR)); + process.setProgram("python"); + process.setArguments(QStringList() << "test262.py" << "--command=" + QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmljs " + qmljsParameter << "--parallel" << "--with-test-expectations"); + + qDebug() << "Going to run" << process.program() << process.arguments() << "in" << process.workingDirectory(); + + process.start(); + QVERIFY(process.waitForStarted()); + const int timeoutInMSecs = 20 * 60 * 1000; + QVERIFY2(process.waitForFinished(timeoutInMSecs), "Tests did not terminate in time -- see output above for details"); + QVERIFY2(process.exitStatus() == QProcess::NormalExit, "Running the test harness failed -- see output above for details"); + QVERIFY2(process.exitCode() == 0, "Tests failed -- see output above for details"); +#else + QSKIP("Currently the ecmascript tests are only run on Linux/x86-64"); +#endif +} + +QTEST_GUILESS_MAIN(tst_EcmaScriptTests) + +#include "tst_ecmascripttests.moc" + diff --git a/tests/auto/qml/qml.pro b/tests/auto/qml/qml.pro index 7d182b7255..59566ad927 100644 --- a/tests/auto/qml/qml.pro +++ b/tests/auto/qml/qml.pro @@ -7,6 +7,9 @@ PUBLICTESTS += \ parserstress \ qjsvalueiterator \ qjsonbinding \ + +!boot2qt { +PUBLICTESTS += \ qmlmin \ qqmlcomponent \ qqmlconsole \ @@ -25,15 +28,22 @@ PUBLICTESTS += \ qquickfolderlistmodel \ qqmlapplicationengine \ qqmlsettings \ - qqmlstatemachine + qqmlstatemachine \ + qmldiskcache +} PRIVATETESTS += \ - animation \ qqmlcpputils \ + qqmldirparser \ + v4misc \ + qmlcachegen + +!boot2qt { +PRIVATETESTS += \ + animation \ qqmlecmascript \ qqmlcontext \ qqmlexpression \ - qqmldirparser \ qqmlglobal \ qqmllanguage \ qqmlopenmetaobject \ @@ -57,12 +67,12 @@ PRIVATETESTS += \ qqmltimer \ qqmlinstantiator \ qqmlenginecleanup \ - v4misc \ qqmltranslation \ qqmlimport \ qqmlobjectmodel \ - qmldiskcache \ - qv4mm + qv4mm \ + ecmascripttests +} qtHaveModule(widgets) { PUBLICTESTS += \ @@ -70,14 +80,17 @@ qtHaveModule(widgets) { qjsvalue } -SUBDIRS += $$PUBLICTESTS \ - qqmlextensionplugin +SUBDIRS += $$PUBLICTESTS SUBDIRS += $$METATYPETESTS -qtConfig(process) { +qtConfig(process):!boot2qt { !contains(QT_CONFIG, no-qml-debug): SUBDIRS += debugger SUBDIRS += qmllint qmlplugindump } +qtConfig(library) { + SUBDIRS += qqmlextensionplugin +} + qtConfig(private_tests): \ SUBDIRS += $$PRIVATETESTS diff --git a/tests/auto/qml/qmlcachegen/qmlcachegen.pro b/tests/auto/qml/qmlcachegen/qmlcachegen.pro new file mode 100644 index 0000000000..8d8b37be15 --- /dev/null +++ b/tests/auto/qml/qmlcachegen/qmlcachegen.pro @@ -0,0 +1,7 @@ +CONFIG += testcase +TARGET = tst_qmlcachegen +macos:CONFIG -= app_bundle + +SOURCES += tst_qmlcachegen.cpp + +QT += core-private qml-private testlib diff --git a/tests/auto/qml/qmlcachegen/tst_qmlcachegen.cpp b/tests/auto/qml/qmlcachegen/tst_qmlcachegen.cpp new file mode 100644 index 0000000000..b7e616a050 --- /dev/null +++ b/tests/auto/qml/qmlcachegen/tst_qmlcachegen.cpp @@ -0,0 +1,163 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <qtest.h> + +#include <QQmlComponent> +#include <QQmlEngine> +#include <QProcess> +#include <QLibraryInfo> +#include <QSysInfo> + +class tst_qmlcachegen: public QObject +{ + Q_OBJECT + +private slots: + void initTestCase(); + + void loadGeneratedFile(); + void translationExpressionSupport(); +}; + +// A wrapper around QQmlComponent to ensure the temporary reference counts +// on the type data as a result of the main thread <> loader thread communication +// are dropped. Regular Synchronous loading will leave us with an event posted +// to the gui thread and an extra refcount that will only be dropped after the +// event delivery. A plain sendPostedEvents() however is insufficient because +// we can't be sure that the event is posted after the constructor finished. +class CleanlyLoadingComponent : public QQmlComponent +{ +public: + CleanlyLoadingComponent(QQmlEngine *engine, const QUrl &url) + : QQmlComponent(engine, url, QQmlComponent::Asynchronous) + { waitForLoad(); } + CleanlyLoadingComponent(QQmlEngine *engine, const QString &fileName) + : QQmlComponent(engine, fileName, QQmlComponent::Asynchronous) + { waitForLoad(); } + + void waitForLoad() + { + QTRY_VERIFY(status() == QQmlComponent::Ready || status() == QQmlComponent::Error); + } +}; + +static bool generateCache(const QString &qmlFileName) +{ + QProcess proc; + proc.setProcessChannelMode(QProcess::ForwardedChannels); + proc.setProgram(QLibraryInfo::location(QLibraryInfo::BinariesPath) + QDir::separator() + QLatin1String("qmlcachegen")); + proc.setArguments(QStringList() << (QLatin1String("--target-architecture=") + QSysInfo::buildCpuArchitecture()) << (QLatin1String("--target-abi=") + QSysInfo::buildAbi()) << qmlFileName); + proc.start(); + if (!proc.waitForFinished()) + return false; + if (proc.exitStatus() != QProcess::NormalExit) + return false; + return proc.exitCode() == 0; +} + +void tst_qmlcachegen::initTestCase() +{ + qputenv("QML_FORCE_DISK_CACHE", "1"); +} + +void tst_qmlcachegen::loadGeneratedFile() +{ + QTemporaryDir tempDir; + QVERIFY(tempDir.isValid()); + + const auto writeTempFile = [&tempDir](const QString &fileName, const char *contents) { + QFile f(tempDir.path() + '/' + fileName); + const bool ok = f.open(QIODevice::WriteOnly | QIODevice::Truncate); + Q_ASSERT(ok); + f.write(contents); + return f.fileName(); + }; + + const QString testFilePath = writeTempFile("test.qml", "import QtQml 2.0\n" + "QtObject {\n" + " property int value: Math.min(100, 42);\n" + "}"); + + QVERIFY(generateCache(testFilePath)); + + const QString cacheFilePath = testFilePath + QLatin1Char('c'); + QVERIFY(QFile::exists(cacheFilePath)); + QVERIFY(QFile::remove(testFilePath)); + + QQmlEngine engine; + CleanlyLoadingComponent component(&engine, QUrl::fromLocalFile(testFilePath)); + QScopedPointer<QObject> obj(component.create()); + QVERIFY(!obj.isNull()); + QCOMPARE(obj->property("value").toInt(), 42); +} + +void tst_qmlcachegen::translationExpressionSupport() +{ + QTemporaryDir tempDir; + QVERIFY(tempDir.isValid()); + + const auto writeTempFile = [&tempDir](const QString &fileName, const char *contents) { + QFile f(tempDir.path() + '/' + fileName); + const bool ok = f.open(QIODevice::WriteOnly | QIODevice::Truncate); + Q_ASSERT(ok); + f.write(contents); + return f.fileName(); + }; + + const QString testFilePath = writeTempFile("test.qml", "import QtQml.Models 2.2\n" + "import QtQml 2.2\n" + "QtObject {\n" + " property ListModel model: ListModel {\n" + " ListElement {\n" + " text: qsTr(\"All\")\n" + " }\n" + " ListElement {\n" + " text: QT_TR_NOOP(\"Ok\")\n" + " }\n" + " }\n" + " property string text: model.get(0).text + \" \" + model.get(1).text\n" + "}"); + + + QVERIFY(generateCache(testFilePath)); + + const QString cacheFilePath = testFilePath + QLatin1Char('c'); + QVERIFY(QFile::exists(cacheFilePath)); + QVERIFY(QFile::remove(testFilePath)); + + QQmlEngine engine; + CleanlyLoadingComponent component(&engine, QUrl::fromLocalFile(testFilePath)); + QScopedPointer<QObject> obj(component.create()); + QVERIFY(!obj.isNull()); + QCOMPARE(obj->property("text").toString(), QString("All Ok")); +} + +QTEST_GUILESS_MAIN(tst_qmlcachegen) + +#include "tst_qmlcachegen.moc" diff --git a/tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp b/tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp index b265607fd1..3402aeebc1 100644 --- a/tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp +++ b/tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp @@ -58,6 +58,7 @@ private slots: void localAliases(); void cacheResources(); void stableOrderOfDependentCompositeTypes(); + void singletonDependency(); }; // A wrapper around QQmlComponent to ensure the temporary reference counts @@ -174,7 +175,7 @@ struct TestCompiler { QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine); QQmlRefPointer<QV4::CompiledData::CompilationUnit> unit = v4->iselFactory->createUnitForLoading(); - return unit->loadFromDisk(QUrl::fromLocalFile(testFilePath), v4->iselFactory.data(), &lastErrorString); + return unit->loadFromDisk(QUrl::fromLocalFile(testFilePath), QFileInfo(testFilePath).lastModified(), v4->iselFactory.data(), &lastErrorString); } void closeMapping() @@ -737,6 +738,58 @@ void tst_qmldiskcache::stableOrderOfDependentCompositeTypes() } } +void tst_qmldiskcache::singletonDependency() +{ + QScopedPointer<QQmlEngine> engine(new QQmlEngine); + + QTemporaryDir tempDir; + QVERIFY(tempDir.isValid()); + + const auto writeTempFile = [&tempDir](const QString &fileName, const char *contents) { + QFile f(tempDir.path() + '/' + fileName); + const bool ok = f.open(QIODevice::WriteOnly | QIODevice::Truncate); + Q_ASSERT(ok); + f.write(contents); + return f.fileName(); + }; + + writeTempFile("MySingleton.qml", "import QtQml 2.0\npragma Singleton\nQtObject { property int value: 42 }"); + writeTempFile("qmldir", "singleton MySingleton 1.0 MySingleton.qml"); + const QString testFilePath = writeTempFile("main.qml", "import QtQml 2.0\nimport \".\"\nQtObject {\n" + " property int value: MySingleton.value\n" + "}"); + + { + CleanlyLoadingComponent component(engine.data(), QUrl::fromLocalFile(testFilePath)); + QScopedPointer<QObject> obj(component.create()); + QVERIFY(!obj.isNull()); + QCOMPARE(obj->property("value").toInt(), 42); + } + + const QString testFileCachePath = testFilePath + QLatin1Char('c'); + QVERIFY(QFile::exists(testFileCachePath)); + QDateTime initialCacheTimeStamp = QFileInfo(testFileCachePath).lastModified(); + + engine.reset(new QQmlEngine); + waitForFileSystem(); + + writeTempFile("MySingleton.qml", "import QtQml 2.0\npragma Singleton\nQtObject { property int value: 100 }"); + waitForFileSystem(); + + { + CleanlyLoadingComponent component(engine.data(), QUrl::fromLocalFile(testFilePath)); + QScopedPointer<QObject> obj(component.create()); + QVERIFY(!obj.isNull()); + QCOMPARE(obj->property("value").toInt(), 100); + } + + { + QVERIFY(QFile::exists(testFileCachePath)); + QDateTime newCacheTimeStamp = QFileInfo(testFileCachePath).lastModified(); + QVERIFY2(newCacheTimeStamp > initialCacheTimeStamp, qPrintable(newCacheTimeStamp.toString())); + } +} + QTEST_MAIN(tst_qmldiskcache) #include "tst_qmldiskcache.moc" diff --git a/tests/auto/qml/qmlmin/tst_qmlmin.cpp b/tests/auto/qml/qmlmin/tst_qmlmin.cpp index 3ed0aa7446..171c2bda8a 100644 --- a/tests/auto/qml/qmlmin/tst_qmlmin.cpp +++ b/tests/auto/qml/qmlmin/tst_qmlmin.cpp @@ -29,7 +29,9 @@ #include <qtest.h> #include <QLibraryInfo> #include <QDir> +#if QT_CONFIG(process) #include <QProcess> +#endif #include <QDebug> #include <QQmlError> #include <cstdlib> @@ -42,7 +44,7 @@ public: private slots: void initTestCase(); -#if !defined(QTEST_CROSS_COMPILED) // sources not available when cross compiled +#if QT_CONFIG(process) && !defined(QTEST_CROSS_COMPILED) // sources not available when cross compiled void qmlMinify_data(); void qmlMinify(); #endif @@ -82,6 +84,7 @@ void tst_qmlmin::initTestCase() excludedDirs << "doc/src/snippets/qtquick1/qtbinding"; excludedDirs << "doc/src/snippets/qtquick1/imports"; excludedDirs << "tests/manual/v4"; + excludedDirs << "tests/auto/qml/ecmascripttests"; excludedDirs << "tests/auto/qml/qmllint"; // Add invalid files (i.e. files with syntax errors) @@ -166,7 +169,7 @@ Examples are any .qml files under the examples/ directory that start with a lower case letter. */ -#if !defined(QTEST_CROSS_COMPILED) // sources not available when cross compiled +#if QT_CONFIG(process) && !defined(QTEST_CROSS_COMPILED) // sources not available when cross compiled void tst_qmlmin::qmlMinify_data() { QTest::addColumn<QString>("file"); @@ -183,7 +186,7 @@ void tst_qmlmin::qmlMinify_data() } #endif -#if !defined(QTEST_CROSS_COMPILED) // sources not available when cross compiled +#if QT_CONFIG(process) && !defined(QTEST_CROSS_COMPILED) // sources not available when cross compiled void tst_qmlmin::qmlMinify() { QFETCH(QString, file); diff --git a/tests/auto/qml/qmlplugindump/tst_qmlplugindump.cpp b/tests/auto/qml/qmlplugindump/tst_qmlplugindump.cpp index 838966e2a0..68e11e3551 100644 --- a/tests/auto/qml/qmlplugindump/tst_qmlplugindump.cpp +++ b/tests/auto/qml/qmlplugindump/tst_qmlplugindump.cpp @@ -105,12 +105,12 @@ void tst_qmlplugindump::singleton() args << QLatin1String("tests.dumper.CompositeSingleton") << QLatin1String("1.0") << QLatin1String("."); dumper.start(qmlplugindumpPath, args); - dumper.waitForFinished(); + QVERIFY2(dumper.waitForStarted(), qPrintable(dumper.errorString())); + QVERIFY2(dumper.waitForFinished(), qPrintable(dumper.errorString())); const QString &result = dumper.readAllStandardOutput(); - qDebug() << "result: " << result; - QVERIFY(result.contains(QLatin1String("exports: [\"Singleton 1.0\"]"))); - QVERIFY(result.contains(QLatin1String("exportMetaObjectRevisions: [0]"))); + QVERIFY2(result.contains(QLatin1String("exports: [\"Singleton 1.0\"]")), qPrintable(result)); + QVERIFY2(result.contains(QLatin1String("exportMetaObjectRevisions: [0]")), qPrintable(result)); } QTEST_MAIN(tst_qmlplugindump) diff --git a/tests/auto/qml/qqmlapplicationengine/tst_qqmlapplicationengine.cpp b/tests/auto/qml/qqmlapplicationengine/tst_qqmlapplicationengine.cpp index 74add85cb0..f7748b2da9 100644 --- a/tests/auto/qml/qqmlapplicationengine/tst_qqmlapplicationengine.cpp +++ b/tests/auto/qml/qqmlapplicationengine/tst_qqmlapplicationengine.cpp @@ -29,7 +29,9 @@ #include "../../shared/util.h" #include <QQmlApplicationEngine> #include <QSignalSpy> +#if QT_CONFIG(process) #include <QProcess> +#endif #include <QDebug> class tst_qqmlapplicationengine : public QQmlDataTest diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp index 91ceed7697..6c9cb331a2 100644 --- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp +++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp @@ -8170,6 +8170,8 @@ void tst_qqmlecmascript::stringify_qtbug_50592() QCOMPARE(obj->property("source").toString(), QString::fromLatin1("http://example.org/some_nonexistant_image.png")); } +// Tests for the JS-only instanceof. Tests for the QML extensions for +// instanceof belong in tst_qqmllanguage! void tst_qqmlecmascript::instanceof_data() { QTest::addColumn<QString>("setupCode"); diff --git a/tests/auto/qml/qqmllanguage/data/instanceOf/CustomMouseArea.qml b/tests/auto/qml/qqmllanguage/data/instanceOf/CustomMouseArea.qml new file mode 100644 index 0000000000..f6ec5848c1 --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/instanceOf/CustomMouseArea.qml @@ -0,0 +1,6 @@ +import QtQuick 2.6 + +MouseArea { + +} + diff --git a/tests/auto/qml/qqmllanguage/data/instanceOf/CustomRectangle.qml b/tests/auto/qml/qqmllanguage/data/instanceOf/CustomRectangle.qml new file mode 100644 index 0000000000..b3fa43a671 --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/instanceOf/CustomRectangle.qml @@ -0,0 +1,4 @@ +import QtQuick 2.6 + +Rectangle { +} diff --git a/tests/auto/qml/qqmllanguage/data/instanceOf/CustomRectangleWithProp.qml b/tests/auto/qml/qqmllanguage/data/instanceOf/CustomRectangleWithProp.qml new file mode 100644 index 0000000000..cf566b9315 --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/instanceOf/CustomRectangleWithProp.qml @@ -0,0 +1,6 @@ +import QtQuick 2.6 + +Rectangle { + property int somethingCustom: 0 +} + diff --git a/tests/auto/qml/qqmllanguage/data/instanceOf/qmldir b/tests/auto/qml/qqmllanguage/data/instanceOf/qmldir new file mode 100644 index 0000000000..144c93d8e3 --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/instanceOf/qmldir @@ -0,0 +1,2 @@ +CustomRectangle 1.0 CustomRectangle.qml +CustomMouseArea 1.0 CustomMouseArea.qml diff --git a/tests/auto/qml/qqmllanguage/data/instanceof_qtqml.qml b/tests/auto/qml/qqmllanguage/data/instanceof_qtqml.qml new file mode 100644 index 0000000000..d74b172cf8 --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/instanceof_qtqml.qml @@ -0,0 +1,13 @@ +import QtQml 2.0 + +QtObject { + id: qtobjectInstance + + property Timer aTimer: Timer { + id: timerInstance + } + + property Connections aConnections: Connections { + id: connectionsInstance + } +} diff --git a/tests/auto/qml/qqmllanguage/data/instanceof_qtqml_qualified.qml b/tests/auto/qml/qqmllanguage/data/instanceof_qtqml_qualified.qml new file mode 100644 index 0000000000..a8e303363e --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/instanceof_qtqml_qualified.qml @@ -0,0 +1,13 @@ +import QtQml 2.0 as QmlImport + +QmlImport.QtObject { + id: qtobjectInstance + + property QmlImport.Timer aTimer: QmlImport.Timer { + id: timerInstance + } + + property QmlImport.Connections aConnections: QmlImport.Connections { + id: connectionsInstance + } +} diff --git a/tests/auto/qml/qqmllanguage/data/instanceof_qtquick.qml b/tests/auto/qml/qqmllanguage/data/instanceof_qtquick.qml new file mode 100644 index 0000000000..9c1808d515 --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/instanceof_qtquick.qml @@ -0,0 +1,14 @@ +import QtQuick 2.0 + +Item { + id: itemInstance + + Rectangle { + id: rectangleInstance + } + + MouseArea { + id: mouseAreaInstance + } +} + diff --git a/tests/auto/qml/qqmllanguage/data/instanceof_qtquick_composite.qml b/tests/auto/qml/qqmllanguage/data/instanceof_qtquick_composite.qml new file mode 100644 index 0000000000..78fc112805 --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/instanceof_qtquick_composite.qml @@ -0,0 +1,26 @@ +import QtQuick 2.0 +import "instanceOf" + +Item { + id: itemInstance + + Rectangle { + id: rectangleInstance + } + + MouseArea { + id: mouseAreaInstance + } + + CustomRectangle { + id: customRectangleInstance + } + CustomRectangleWithProp { + id: customRectangleWithPropInstance + } + CustomMouseArea { + id: customMouseAreaInstance + } +} + + diff --git a/tests/auto/qml/qqmllanguage/data/instanceof_qtquick_composite_qualified.qml b/tests/auto/qml/qqmllanguage/data/instanceof_qtquick_composite_qualified.qml new file mode 100644 index 0000000000..97361b7334 --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/instanceof_qtquick_composite_qualified.qml @@ -0,0 +1,27 @@ +import QtQuick 2.0 as QuickImport +import "instanceOf" as CustomImport + +QuickImport.Item { + id: itemInstance + + QuickImport.Rectangle { + id: rectangleInstance + } + + QuickImport.MouseArea { + id: mouseAreaInstance + } + + CustomImport.CustomRectangle { + id: customRectangleInstance + } + CustomImport.CustomRectangleWithProp { + id: customRectangleWithPropInstance + } + CustomImport.CustomMouseArea { + id: customMouseAreaInstance + } +} + + + diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp index 750c32cc3c..e67fa18309 100644 --- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp +++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp @@ -263,6 +263,9 @@ private slots: void qmlTypeCanBeResolvedByName_data(); void qmlTypeCanBeResolvedByName(); + void instanceof_data(); + void instanceof(); + private: QQmlEngine engine; QStringList defaultImportPathList; @@ -309,7 +312,7 @@ private: if (!errorfile) { \ if (qgetenv("DEBUG") != "" && !component.errors().isEmpty()) \ qWarning() << "Unexpected Errors:" << component.errors(); \ - QVERIFY(!component.isError()); \ + QVERIFY2(!component.isError(), qPrintable(component.errorString())); \ QVERIFY(component.errors().isEmpty()); \ } else { \ DETERMINE_ERRORS(errorfile,expected,actual);\ @@ -4338,6 +4341,200 @@ void tst_qqmllanguage::qmlTypeCanBeResolvedByName() QVERIFY(!o.isNull()); } +// Tests for the QML-only extensions of instanceof. Tests for the regular JS +// instanceof belong in tst_qqmlecmascript! +void tst_qqmllanguage::instanceof_data() +{ + QTest::addColumn<QUrl>("documentToTestIn"); + QTest::addColumn<QVariant>("expectedValue"); + + // so the way this works is that the name of the test tag defines the test + // to run. + // + // the expectedValue is either a boolean true or false for whether the two + // operands are indeed an instanceof each other, or a string for the + // expected error message. + + // assert that basic types don't convert to QObject + QTest::newRow("1 instanceof QtObject") + << testFileUrl("instanceof_qtqml.qml") + << QVariant("TypeError: Type error"); + QTest::newRow("true instanceof QtObject") + << testFileUrl("instanceof_qtqml.qml") + << QVariant("TypeError: Type error"); + QTest::newRow("\"foobar\" instanceof QtObject") + << testFileUrl("instanceof_qtqml.qml") + << QVariant("TypeError: Type error"); + + // assert that Managed don't either + QTest::newRow("new String(\"foobar\") instanceof QtObject") + << testFileUrl("instanceof_qtqml.qml") + << QVariant("TypeError: Type error"); + QTest::newRow("new Object() instanceof QtObject") + << testFileUrl("instanceof_qtqml.qml") + << QVariant("TypeError: Type error"); + QTest::newRow("new Date() instanceof QtObject") + << testFileUrl("instanceof_qtqml.qml") + << QVariant("TypeError: Type error"); + + // test that simple QtQml comparisons work + QTest::newRow("qtobjectInstance instanceof QtObject") + << testFileUrl("instanceof_qtqml.qml") + << QVariant(true); + QTest::newRow("qtobjectInstance instanceof Timer") + << testFileUrl("instanceof_qtqml.qml") + << QVariant(false); + QTest::newRow("timerInstance instanceof QtObject") + << testFileUrl("instanceof_qtqml.qml") + << QVariant(true); + QTest::newRow("timerInstance instanceof Timer") + << testFileUrl("instanceof_qtqml.qml") + << QVariant(true); + QTest::newRow("connectionsInstance instanceof QtObject") + << testFileUrl("instanceof_qtqml.qml") + << QVariant(true); + QTest::newRow("connectionsInstance instanceof Timer") + << testFileUrl("instanceof_qtqml.qml") + << QVariant(false); + QTest::newRow("connectionsInstance instanceof Connections") + << testFileUrl("instanceof_qtqml.qml") + << QVariant(true); + + // make sure they still work when imported with a qualifier + QTest::newRow("qtobjectInstance instanceof QmlImport.QtObject") + << testFileUrl("instanceof_qtqml_qualified.qml") + << QVariant(true); + QTest::newRow("qtobjectInstance instanceof QmlImport.Timer") + << testFileUrl("instanceof_qtqml_qualified.qml") + << QVariant(false); + QTest::newRow("timerInstance instanceof QmlImport.QtObject") + << testFileUrl("instanceof_qtqml_qualified.qml") + << QVariant(true); + QTest::newRow("timerInstance instanceof QmlImport.Timer") + << testFileUrl("instanceof_qtqml_qualified.qml") + << QVariant(true); + QTest::newRow("connectionsInstance instanceof QmlImport.QtObject") + << testFileUrl("instanceof_qtqml_qualified.qml") + << QVariant(true); + QTest::newRow("connectionsInstance instanceof QmlImport.Timer") + << testFileUrl("instanceof_qtqml_qualified.qml") + << QVariant(false); + QTest::newRow("connectionsInstance instanceof QmlImport.Connections") + << testFileUrl("instanceof_qtqml_qualified.qml") + << QVariant(true); + + // test that Quick C++ types work ok + QTest::newRow("itemInstance instanceof QtObject") + << testFileUrl("instanceof_qtquick.qml") + << QVariant(true); + QTest::newRow("itemInstance instanceof Timer") + << testFileUrl("instanceof_qtquick.qml") + << QVariant(false); + QTest::newRow("itemInstance instanceof Rectangle") + << testFileUrl("instanceof_qtquick.qml") + << QVariant(false); + QTest::newRow("rectangleInstance instanceof Item") + << testFileUrl("instanceof_qtquick.qml") + << QVariant(true); + QTest::newRow("rectangleInstance instanceof Rectangle") + << testFileUrl("instanceof_qtquick.qml") + << QVariant(true); + QTest::newRow("rectangleInstance instanceof MouseArea") + << testFileUrl("instanceof_qtquick.qml") + << QVariant(false); + QTest::newRow("mouseAreaInstance instanceof Item") + << testFileUrl("instanceof_qtquick.qml") + << QVariant(true); + QTest::newRow("mouseAreaInstance instanceof Rectangle") + << testFileUrl("instanceof_qtquick.qml") + << QVariant(false); + QTest::newRow("mouseAreaInstance instanceof MouseArea") + << testFileUrl("instanceof_qtquick.qml") + << QVariant(true); + + // test that unqualified quick composite types work ok + QTest::newRow("rectangleInstance instanceof CustomRectangle") + << testFileUrl("instanceof_qtquick_composite.qml") + << QVariant(false); + QTest::newRow("customRectangleInstance instanceof Rectangle") + << testFileUrl("instanceof_qtquick_composite.qml") + << QVariant(true); + QTest::newRow("customRectangleInstance instanceof Item") + << testFileUrl("instanceof_qtquick_composite.qml") + << QVariant(true); + QTest::newRow("customRectangleWithPropInstance instanceof CustomRectangleWithProp") + << testFileUrl("instanceof_qtquick_composite.qml") + << QVariant(true); + QTest::newRow("customRectangleWithPropInstance instanceof CustomRectangle") + << testFileUrl("instanceof_qtquick_composite.qml") + << QVariant(false); // ### XXX: QTBUG-58477 + QTest::newRow("customRectangleWithPropInstance instanceof Rectangle") + << testFileUrl("instanceof_qtquick_composite.qml") + << QVariant(true); + QTest::newRow("customRectangleInstance instanceof MouseArea") + << testFileUrl("instanceof_qtquick_composite.qml") + << QVariant(false); + QTest::newRow("customMouseAreaInstance instanceof MouseArea") + << testFileUrl("instanceof_qtquick_composite.qml") + << QVariant(true); + + // test that they still work when qualified + QTest::newRow("rectangleInstance instanceof CustomImport.CustomRectangle") + << testFileUrl("instanceof_qtquick_composite_qualified.qml") + << QVariant(false); + QTest::newRow("customRectangleInstance instanceof QuickImport.Rectangle") + << testFileUrl("instanceof_qtquick_composite_qualified.qml") + << QVariant(true); + QTest::newRow("customRectangleInstance instanceof QuickImport.Item") + << testFileUrl("instanceof_qtquick_composite_qualified.qml") + << QVariant(true); + QTest::newRow("customRectangleWithPropInstance instanceof CustomImport.CustomRectangleWithProp") + << testFileUrl("instanceof_qtquick_composite_qualified.qml") + << QVariant(true); + QTest::newRow("customRectangleWithPropInstance instanceof CustomImport.CustomRectangle") + << testFileUrl("instanceof_qtquick_composite_qualified.qml") + << QVariant(false); // ### XXX: QTBUG-58477 + QTest::newRow("customRectangleWithPropInstance instanceof QuickImport.Rectangle") + << testFileUrl("instanceof_qtquick_composite_qualified.qml") + << QVariant(true); + QTest::newRow("customRectangleInstance instanceof QuickImport.MouseArea") + << testFileUrl("instanceof_qtquick_composite_qualified.qml") + << QVariant(false); + QTest::newRow("customMouseAreaInstance instanceof QuickImport.MouseArea") + << testFileUrl("instanceof_qtquick_composite_qualified.qml") + << QVariant(true); +} + +void tst_qqmllanguage::instanceof() +{ + QFETCH(QUrl, documentToTestIn); + QFETCH(QVariant, expectedValue); + + QQmlEngine engine; + QQmlComponent component(&engine, documentToTestIn); + VERIFY_ERRORS(0); + + QScopedPointer<QObject> o(component.create()); + QVERIFY(o != 0); + + QQmlExpression expr(engine.contextForObject(o.data()), 0, QString::fromLatin1(QTest::currentDataTag())); + QVariant ret = expr.evaluate(); + + if (expectedValue.type() == QVariant::Bool) { + // no error expected + QVERIFY2(!expr.hasError(), qPrintable(expr.error().description())); + bool returnValue = ret.toBool(); + + if (QTest::currentDataTag() == QLatin1String("customRectangleWithPropInstance instanceof CustomRectangle") || + QTest::currentDataTag() == QLatin1String("customRectangleWithPropInstance instanceof CustomImport.CustomRectangle")) + QEXPECT_FAIL("", "QTBUG-58477: QML type rules are a little lax", Continue); + QCOMPARE(returnValue, expectedValue.toBool()); + } else { + QVERIFY(expr.hasError()); + QCOMPARE(expr.error().description(), expectedValue.toString()); + } +} + QTEST_MAIN(tst_qqmllanguage) #include "tst_qqmllanguage.moc" diff --git a/tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp b/tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp index 9fbd719d7b..30e517c8f9 100644 --- a/tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp +++ b/tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp @@ -52,6 +52,7 @@ private slots: void qmlPropertyValueInterceptorCast(); void qmlType(); void invalidQmlTypeName(); + void prettyTypeName(); void registrationType(); void compositeType(); void externalEnums(); @@ -72,6 +73,16 @@ public: }; QML_DECLARE_TYPE(TestType); +class TestType2 : public QObject +{ + Q_OBJECT +}; + +class TestType3 : public QObject +{ + Q_OBJECT +}; + class ExternalEnums : public QObject { Q_OBJECT @@ -214,13 +225,28 @@ void tst_qqmlmetatype::invalidQmlTypeName() { QStringList currFailures = QQmlMetaType::typeRegistrationFailures(); QCOMPARE(qmlRegisterType<TestType>("TestNamespace", 1, 0, "Test$Type"), -1); // should fail due to invalid QML type name. + QCOMPARE(qmlRegisterType<TestType>("Test", 1, 0, "EndingInSlash/"), -1); QStringList nowFailures = QQmlMetaType::typeRegistrationFailures(); foreach (const QString &f, currFailures) nowFailures.removeOne(f); - QCOMPARE(nowFailures.size(), 1); + QCOMPARE(nowFailures.size(), 2); QCOMPARE(nowFailures.at(0), QStringLiteral("Invalid QML element name \"Test$Type\"")); + QCOMPARE(nowFailures.at(1), QStringLiteral("Invalid QML element name \"EndingInSlash/\"")); +} + +void tst_qqmlmetatype::prettyTypeName() +{ + TestType2 obj2; + QCOMPARE(QQmlMetaType::prettyTypeName(&obj2), QString("TestType2")); + QVERIFY(qmlRegisterType<TestType2>("Test", 1, 0, "") >= 0); + QCOMPARE(QQmlMetaType::prettyTypeName(&obj2), QString("TestType2")); + + TestType3 obj3; + QCOMPARE(QQmlMetaType::prettyTypeName(&obj3), QString("TestType3")); + QVERIFY(qmlRegisterType<TestType3>("Test", 1, 0, "OtherName") >= 0); + QCOMPARE(QQmlMetaType::prettyTypeName(&obj3), QString("OtherName")); } void tst_qqmlmetatype::isList() diff --git a/tests/auto/qml/v4misc/tst_v4misc.cpp b/tests/auto/qml/v4misc/tst_v4misc.cpp index 88b6ae92a8..55a1f65608 100644 --- a/tests/auto/qml/v4misc/tst_v4misc.cpp +++ b/tests/auto/qml/v4misc/tst_v4misc.cpp @@ -26,6 +26,7 @@ ** ****************************************************************************/ +#include <qhashfunctions.h> #include <qtest.h> #define V4_AUTOTEST @@ -46,17 +47,12 @@ private slots: void moveMapping_2(); }; -QT_BEGIN_NAMESPACE -// Avoid QHash randomization so that the temp numbering is stable. -extern Q_CORE_EXPORT QBasicAtomicInt qt_qhash_seed; // from qhash.cpp -QT_END_NAMESPACE - using namespace QT_PREPEND_NAMESPACE(QV4::IR); void tst_v4misc::initTestCase() { - qt_qhash_seed.store(0); - QCOMPARE(qt_qhash_seed.load(), 0); + qSetGlobalQHashSeed(0); + QCOMPARE(qGlobalQHashSeed(), 0); } // split between two ranges diff --git a/tests/auto/qmltest/BLACKLIST b/tests/auto/qmltest/BLACKLIST index c38347b42a..e0a4ce1743 100644 --- a/tests/auto/qmltest/BLACKLIST +++ b/tests/auto/qmltest/BLACKLIST @@ -9,3 +9,8 @@ linux linux [ListView::test_listInteractiveCurrentIndexEnforce] linux +macos-10.12 +[TextEdit::test_textentry] +macos-10.12 +[TextEdit::test_textentry_char] +macos-10.12 diff --git a/tests/auto/qmltest/selftests/tst_selftests.qml b/tests/auto/qmltest/selftests/tst_selftests.qml index 439ea7a70d..5555876014 100644 --- a/tests/auto/qmltest/selftests/tst_selftests.qml +++ b/tests/auto/qmltest/selftests/tst_selftests.qml @@ -167,6 +167,16 @@ TestCase { caught = true } verify(caught) + + caught = false; + try { + testCase.verify(true, "foo", "bar") + } catch (e) { + compare(e.message, "QtQuickTest::fail") + compare(functions.failmsg, "More than two arguments given to verify(). Did you mean tryVerify() or tryCompare()?") + caught = true + } + verify(caught) } function test_compare() { diff --git a/tests/auto/quick/examples/tst_examples.cpp b/tests/auto/quick/examples/tst_examples.cpp index d5c9aaeb90..b6742b9efe 100644 --- a/tests/auto/quick/examples/tst_examples.cpp +++ b/tests/auto/quick/examples/tst_examples.cpp @@ -29,7 +29,6 @@ #include <qtest.h> #include <QLibraryInfo> #include <QDir> -#include <QProcess> #include <QDebug> #include <QtQuick/QQuickItem> #include <QtQuick/QQuickView> diff --git a/tests/auto/quick/nokeywords/tst_nokeywords.cpp b/tests/auto/quick/nokeywords/tst_nokeywords.cpp index ad77743ddd..e6655589a3 100644 --- a/tests/auto/quick/nokeywords/tst_nokeywords.cpp +++ b/tests/auto/quick/nokeywords/tst_nokeywords.cpp @@ -55,7 +55,6 @@ #include <QtQuick/private/qsgdefaultinternalrectanglenode_p.h> #include <QtQuick/private/qsgdepthstencilbuffer_p.h> #include <QtQuick/private/qsgdistancefieldglyphnode_p.h> -#include <QtQuick/private/qsgdistancefieldutil_p.h> #endif #include <QtQuick/private/qsggeometry_p.h> #include <QtQuick/private/qsgnode_p.h> diff --git a/tests/auto/quick/qquickapplication/BLACKLIST b/tests/auto/quick/qquickapplication/BLACKLIST new file mode 100644 index 0000000000..81592db56f --- /dev/null +++ b/tests/auto/quick/qquickapplication/BLACKLIST @@ -0,0 +1,2 @@ +[active] +osx-10.11 diff --git a/tests/auto/quick/qquickflickable/BLACKLIST b/tests/auto/quick/qquickflickable/BLACKLIST index 647bf819a5..f35397f119 100644 --- a/tests/auto/quick/qquickflickable/BLACKLIST +++ b/tests/auto/quick/qquickflickable/BLACKLIST @@ -17,3 +17,5 @@ osx osx-10.10 [flickVelocity] osx-10.10 +[nestedSliderUsingTouch:keepNeither] +ubuntu-16.04 diff --git a/tests/auto/quick/qquickflickable/data/nestedSlider.qml b/tests/auto/quick/qquickflickable/data/nestedSlider.qml new file mode 100644 index 0000000000..2fd0cbfcc8 --- /dev/null +++ b/tests/auto/quick/qquickflickable/data/nestedSlider.qml @@ -0,0 +1,36 @@ +import QtQuick 2.0 +import Test 1.0 + +Flickable { + width: 240 + height: 320 + contentWidth: width * 1.5 + contentHeight: height * 1.5 + contentY: height * 0.25 + + Rectangle { + id: slider + width: 50 + height: 200 + color: "lightgray" + border.color: drag.active ? "green" : "black" + anchors.centerIn: parent + radius: 4 + + TouchDragArea { + id: drag + objectName: "drag" + anchors.fill: parent + } + + Rectangle { + width: parent.width - 2 + height: 20 + radius: 5 + color: "darkgray" + border.color: "black" + x: 1 + y: Math.min(slider.height - height, Math.max(0, drag.pos.y - height / 2)) + } + } +} diff --git a/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp b/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp index 9ead271bfe..ef6e444580 100644 --- a/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp +++ b/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp @@ -46,12 +46,107 @@ using namespace QQuickViewTestUtil; using namespace QQuickVisualTestUtil; +// an abstract Slider which only handles touch events +class TouchDragArea : public QQuickItem +{ + Q_OBJECT + Q_PROPERTY(QPointF pos READ pos NOTIFY posChanged) + Q_PROPERTY(bool active READ active NOTIFY activeChanged) + Q_PROPERTY(bool keepMouseGrab READ keepMouseGrab WRITE setKeepMouseGrab NOTIFY keepMouseGrabChanged) + Q_PROPERTY(bool keepTouchGrab READ keepTouchGrab WRITE setKeepTouchGrab NOTIFY keepTouchGrabChanged) + +public: + TouchDragArea(QQuickItem *parent = 0) + : QQuickItem(parent) + , touchEvents(0) + , touchUpdates(0) + , touchReleases(0) + , ungrabs(0) + , m_active(false) + { } + + QPointF pos() const { return m_pos; } + + bool active() const { return m_active; } + + void setKeepMouseGrab(bool keepMouseGrab) + { + QQuickItem::setKeepMouseGrab(keepMouseGrab); + emit keepMouseGrabChanged(); + } + + void setKeepTouchGrab(bool keepTouchGrab) + { + QQuickItem::setKeepTouchGrab(keepTouchGrab); + emit keepTouchGrabChanged(); + } + + int touchEvents; + int touchUpdates; + int touchReleases; + int ungrabs; + QVector<Qt::TouchPointState> touchPointStates; + +protected: + void touchEvent(QTouchEvent *ev) override + { + QCOMPARE(ev->touchPoints().count(), 1); + auto touchpoint = ev->touchPoints().first(); + switch (touchpoint.state()) { + case Qt::TouchPointPressed: + QVERIFY(!m_active); + m_active = true; + emit activeChanged(); + grabTouchPoints(QVector<int>() << touchpoint.id()); + break; + case Qt::TouchPointMoved: + ++touchUpdates; + break; + case Qt::TouchPointReleased: + QVERIFY(m_active); + m_active = false; + ++touchReleases; + emit activeChanged(); + case Qt::TouchPointStationary: + break; + } + touchPointStates << touchpoint.state(); + ++touchEvents; + m_pos = touchpoint.pos(); + emit posChanged(); + } + + void touchUngrabEvent() override + { + ++ungrabs; + QVERIFY(m_active); + emit ungrabbed(); + m_active = false; + emit activeChanged(); + } + +signals: + void ungrabbed(); + void posChanged(); + void keepMouseGrabChanged(); + void keepTouchGrabChanged(); + void activeChanged(); + +private: + QPointF m_pos; + bool m_active; +}; + class tst_qquickflickable : public QQmlDataTest { Q_OBJECT public: + tst_qquickflickable() + : touchDevice(QTest::createTouchDevice()) + {} private slots: + void initTestCase() override; void create(); void horizontalViewportSize(); void verticalViewportSize(); @@ -89,6 +184,8 @@ private slots: void stopAtBounds(); void stopAtBounds_data(); void nestedMouseAreaUsingTouch(); + void nestedSliderUsingTouch(); + void nestedSliderUsingTouch_data(); void pressDelayWithLoader(); void movementFromProgrammaticFlick(); void cleanup(); @@ -101,9 +198,16 @@ private slots: void overshoot_reentrant(); private: - void flickWithTouch(QQuickWindow *window, QTouchDevice *touchDevice, const QPoint &from, const QPoint &to); + void flickWithTouch(QQuickWindow *window, const QPoint &from, const QPoint &to); + QTouchDevice *touchDevice; }; +void tst_qquickflickable::initTestCase() +{ + QQmlDataTest::initTestCase(); + qmlRegisterType<TouchDragArea>("Test",1,0,"TouchDragArea"); +} + void tst_qquickflickable::cleanup() { QVERIFY(QGuiApplication::topLevelWindows().isEmpty()); @@ -1530,12 +1634,6 @@ void tst_qquickflickable::clickAndDragWhenTransformed() void tst_qquickflickable::flickTwiceUsingTouches() { - QTouchDevice *touchDevice = new QTouchDevice; - touchDevice->setName("Fake Touchscreen"); - touchDevice->setType(QTouchDevice::TouchScreen); - touchDevice->setCapabilities(QTouchDevice::Position); - QWindowSystemInterface::registerTouchDevice(touchDevice); - QScopedPointer<QQuickView> window(new QQuickView); window->setSource(testFileUrl("longList.qml")); QTRY_COMPARE(window->status(), QQuickView::Ready); @@ -1548,7 +1646,7 @@ void tst_qquickflickable::flickTwiceUsingTouches() QVERIFY(flickable != 0); QCOMPARE(flickable->contentY(), 0.0f); - flickWithTouch(window.data(), touchDevice, QPoint(100, 400), QPoint(100, 240)); + flickWithTouch(window.data(), QPoint(100, 400), QPoint(100, 240)); qreal contentYAfterFirstFlick = flickable->contentY(); qDebug() << "contentYAfterFirstFlick " << contentYAfterFirstFlick; @@ -1556,7 +1654,7 @@ void tst_qquickflickable::flickTwiceUsingTouches() // Wait until view stops moving QTRY_VERIFY(!flickable->isMoving()); - flickWithTouch(window.data(), touchDevice, QPoint(100, 400), QPoint(100, 240)); + flickWithTouch(window.data(), QPoint(100, 400), QPoint(100, 240)); // In the original bug, that second flick would cause Flickable to halt immediately qreal contentYAfterSecondFlick = flickable->contentY(); @@ -1564,7 +1662,7 @@ void tst_qquickflickable::flickTwiceUsingTouches() QTRY_VERIFY(contentYAfterSecondFlick > (contentYAfterFirstFlick + 80.0f)); } -void tst_qquickflickable::flickWithTouch(QQuickWindow *window, QTouchDevice *touchDevice, const QPoint &from, const QPoint &to) +void tst_qquickflickable::flickWithTouch(QQuickWindow *window, const QPoint &from, const QPoint &to) { QTest::touchEvent(window, touchDevice).press(0, from, window); QQuickTouchUtils::flush(window); @@ -1869,12 +1967,6 @@ void tst_qquickflickable::stopAtBounds() void tst_qquickflickable::nestedMouseAreaUsingTouch() { - QTouchDevice *touchDevice = new QTouchDevice; - touchDevice->setName("Fake Touchscreen"); - touchDevice->setType(QTouchDevice::TouchScreen); - touchDevice->setCapabilities(QTouchDevice::Position); - QWindowSystemInterface::registerTouchDevice(touchDevice); - QScopedPointer<QQuickView> window(new QQuickView); window->setSource(testFileUrl("nestedmousearea.qml")); QTRY_COMPARE(window->status(), QQuickView::Ready); @@ -1887,7 +1979,7 @@ void tst_qquickflickable::nestedMouseAreaUsingTouch() QVERIFY(flickable != 0); QCOMPARE(flickable->contentY(), 50.0f); - flickWithTouch(window.data(), touchDevice, QPoint(100, 300), QPoint(100, 200)); + flickWithTouch(window.data(), QPoint(100, 300), QPoint(100, 200)); // flickable should not have moved QCOMPARE(flickable->contentY(), 50.0); @@ -1897,6 +1989,65 @@ void tst_qquickflickable::nestedMouseAreaUsingTouch() QVERIFY(nested->y() < 100.0); } +void tst_qquickflickable::nestedSliderUsingTouch_data() +{ + QTest::addColumn<bool>("keepMouseGrab"); + QTest::addColumn<bool>("keepTouchGrab"); + QTest::addColumn<int>("updates"); + QTest::addColumn<int>("releases"); + QTest::addColumn<int>("ungrabs"); + + QTest::newRow("keepBoth") << true << true << 8 << 1 << 0; + QTest::newRow("keepMouse") << true << false << 8 << 1 << 0; + QTest::newRow("keepTouch") << false << true << 8 << 1 << 0; + QTest::newRow("keepNeither") << false << false << 6 << 0 << 1; +} + +void tst_qquickflickable::nestedSliderUsingTouch() +{ + QFETCH(bool, keepMouseGrab); + QFETCH(bool, keepTouchGrab); + QFETCH(int, updates); + QFETCH(int, releases); + QFETCH(int, ungrabs); + + QQuickView *window = new QQuickView; + QScopedPointer<QQuickView> windowPtr(window); + windowPtr->setSource(testFileUrl("nestedSlider.qml")); + QTRY_COMPARE(window->status(), QQuickView::Ready); + QQuickViewTestUtil::centerOnScreen(window); + QQuickViewTestUtil::moveMouseAway(window); + window->show(); + QVERIFY(QTest::qWaitForWindowActive(window)); + QVERIFY(window->rootObject() != 0); + + QQuickFlickable *flickable = qobject_cast<QQuickFlickable*>(window->rootObject()); + QVERIFY(flickable); + + TouchDragArea *tda = flickable->findChild<TouchDragArea*>("drag"); + QVERIFY(tda); + + // Drag down and a little to the right: flickable will steal the grab only if tda allows it + const int dragThreshold = qApp->styleHints()->startDragDistance(); + tda->setKeepMouseGrab(keepMouseGrab); + tda->setKeepTouchGrab(keepTouchGrab); + QPoint p0 = tda->mapToScene(QPoint(20, 20)).toPoint(); + QTest::touchEvent(window, touchDevice).press(0, p0, window); + QQuickTouchUtils::flush(window); + for (int i = 0; i < 8; ++i) { + p0 += QPoint(dragThreshold / 6, dragThreshold / 4); + QTest::touchEvent(window, touchDevice).move(0, p0, window); + QQuickTouchUtils::flush(window); + } + QCOMPARE(tda->active(), !ungrabs); + QTest::touchEvent(window, touchDevice).release(0, p0, window); + QQuickTouchUtils::flush(window); + QTRY_COMPARE(tda->touchPointStates.first(), Qt::TouchPointPressed); + QTRY_COMPARE(tda->touchUpdates, updates); + QTRY_COMPARE(tda->touchReleases, releases); + QTRY_COMPARE(tda->ungrabs, ungrabs); +} + // QTBUG-31328 void tst_qquickflickable::pressDelayWithLoader() { @@ -2065,6 +2216,7 @@ Q_DECLARE_METATYPE(QQuickFlickable::BoundsBehavior) void tst_qquickflickable::overshoot() { QFETCH(QQuickFlickable::BoundsBehavior, boundsBehavior); + QFETCH(int, boundsMovement); QScopedPointer<QQuickView> window(new QQuickView); window->setSource(testFileUrl("overshoot.qml")); @@ -2081,6 +2233,7 @@ void tst_qquickflickable::overshoot() QCOMPARE(flickable->contentHeight(), 400.0); flickable->setBoundsBehavior(boundsBehavior); + flickable->setBoundsMovement(QQuickFlickable::BoundsMovement(boundsMovement)); // drag past the beginning QTest::mousePress(window.data(), Qt::LeftButton, 0, QPoint(10, 10)); @@ -2089,23 +2242,30 @@ void tst_qquickflickable::overshoot() QTest::mouseMove(window.data(), QPoint(40, 40)); QTest::mouseRelease(window.data(), Qt::LeftButton, 0, QPoint(50, 50)); + if ((boundsMovement == QQuickFlickable::FollowBoundsBehavior) && (boundsBehavior & QQuickFlickable::DragOverBounds)) { + QVERIFY(flickable->property("minContentX").toReal() < 0.0); + QVERIFY(flickable->property("minContentY").toReal() < 0.0); + } else { + QCOMPARE(flickable->property("minContentX").toReal(), 0.0); + QCOMPARE(flickable->property("minContentY").toReal(), 0.0); + } if (boundsBehavior & QQuickFlickable::DragOverBounds) { - QVERIFY(flickable->property("minVerticalOvershoot").toReal() < 0.0); QVERIFY(flickable->property("minHorizontalOvershoot").toReal() < 0.0); - QCOMPARE(flickable->property("minContentY").toReal(), - flickable->property("minVerticalOvershoot").toReal()); - QCOMPARE(flickable->property("minContentX").toReal(), - flickable->property("minHorizontalOvershoot").toReal()); + QVERIFY(flickable->property("minVerticalOvershoot").toReal() < 0.0); } else { - QCOMPARE(flickable->property("minContentY").toReal(), 0.0); - QCOMPARE(flickable->property("minContentX").toReal(), 0.0); - QCOMPARE(flickable->property("minVerticalOvershoot").toReal(), 0.0); QCOMPARE(flickable->property("minHorizontalOvershoot").toReal(), 0.0); + QCOMPARE(flickable->property("minVerticalOvershoot").toReal(), 0.0); + } + if (bool(boundsMovement == QQuickFlickable::FollowBoundsBehavior) == bool(boundsBehavior & QQuickFlickable::DragOverBounds)) { + QCOMPARE(flickable->property("minContentX").toReal(), + flickable->property("minHorizontalOvershoot").toReal()); + QCOMPARE(flickable->property("minContentY").toReal(), + flickable->property("minVerticalOvershoot").toReal()); } - QCOMPARE(flickable->property("maxContentY").toReal(), 0.0); QCOMPARE(flickable->property("maxContentX").toReal(), 0.0); - QCOMPARE(flickable->property("maxVerticalOvershoot").toReal(), 0.0); + QCOMPARE(flickable->property("maxContentY").toReal(), 0.0); QCOMPARE(flickable->property("maxHorizontalOvershoot").toReal(), 0.0); + QCOMPARE(flickable->property("maxVerticalOvershoot").toReal(), 0.0); flickable->setContentX(20.0); flickable->setContentY(20.0); @@ -2115,23 +2275,30 @@ void tst_qquickflickable::overshoot() flick(window.data(), QPoint(10, 10), QPoint(50, 50), 100); QTRY_VERIFY(!flickable->property("flicking").toBool()); + if ((boundsMovement == QQuickFlickable::FollowBoundsBehavior) && (boundsBehavior & QQuickFlickable::OvershootBounds)) { + QVERIFY(flickable->property("minContentX").toReal() < 0.0); + QVERIFY(flickable->property("minContentY").toReal() < 0.0); + } else { + QCOMPARE(flickable->property("minContentX").toReal(), 0.0); + QCOMPARE(flickable->property("minContentY").toReal(), 0.0); + } if (boundsBehavior & QQuickFlickable::OvershootBounds) { - QVERIFY(flickable->property("minVerticalOvershoot").toReal() < 0.0); QVERIFY(flickable->property("minHorizontalOvershoot").toReal() < 0.0); - QCOMPARE(flickable->property("minContentY").toReal(), - flickable->property("minVerticalOvershoot").toReal()); - QCOMPARE(flickable->property("minContentX").toReal(), - flickable->property("minHorizontalOvershoot").toReal()); + QVERIFY(flickable->property("minVerticalOvershoot").toReal() < 0.0); } else { - QCOMPARE(flickable->property("minContentY").toReal(), 0.0); - QCOMPARE(flickable->property("minContentX").toReal(), 0.0); - QCOMPARE(flickable->property("minVerticalOvershoot").toReal(), 0.0); QCOMPARE(flickable->property("minHorizontalOvershoot").toReal(), 0.0); + QCOMPARE(flickable->property("minVerticalOvershoot").toReal(), 0.0); + } + if ((boundsMovement == QQuickFlickable::FollowBoundsBehavior) == (boundsBehavior & QQuickFlickable::OvershootBounds)) { + QCOMPARE(flickable->property("minContentX").toReal(), + flickable->property("minHorizontalOvershoot").toReal()); + QCOMPARE(flickable->property("minContentY").toReal(), + flickable->property("minVerticalOvershoot").toReal()); } - QCOMPARE(flickable->property("maxContentY").toReal(), 20.0); QCOMPARE(flickable->property("maxContentX").toReal(), 20.0); - QCOMPARE(flickable->property("maxVerticalOvershoot").toReal(), 0.0); + QCOMPARE(flickable->property("maxContentY").toReal(), 20.0); QCOMPARE(flickable->property("maxHorizontalOvershoot").toReal(), 0.0); + QCOMPARE(flickable->property("maxVerticalOvershoot").toReal(), 0.0); flickable->setContentX(200.0); flickable->setContentY(200.0); @@ -2144,23 +2311,30 @@ void tst_qquickflickable::overshoot() QTest::mouseMove(window.data(), QPoint(20, 20)); QTest::mouseRelease(window.data(), Qt::LeftButton, 0, QPoint(10, 10)); + if ((boundsMovement == QQuickFlickable::FollowBoundsBehavior) && (boundsBehavior & QQuickFlickable::DragOverBounds)) { + QVERIFY(flickable->property("maxContentX").toReal() > 200.0); + QVERIFY(flickable->property("maxContentX").toReal() > 200.0); + } else { + QCOMPARE(flickable->property("maxContentX").toReal(), 200.0); + QCOMPARE(flickable->property("maxContentY").toReal(), 200.0); + } if (boundsBehavior & QQuickFlickable::DragOverBounds) { - QVERIFY(flickable->property("maxVerticalOvershoot").toReal() > 0.0); QVERIFY(flickable->property("maxHorizontalOvershoot").toReal() > 0.0); - QCOMPARE(flickable->property("maxContentY").toReal() - 200.0, - flickable->property("maxVerticalOvershoot").toReal()); - QCOMPARE(flickable->property("maxContentX").toReal() - 200.0, - flickable->property("maxHorizontalOvershoot").toReal()); + QVERIFY(flickable->property("maxVerticalOvershoot").toReal() > 0.0); } else { - QCOMPARE(flickable->property("maxContentY").toReal(), 200.0); - QCOMPARE(flickable->property("maxContentX").toReal(), 200.0); - QCOMPARE(flickable->property("maxVerticalOvershoot").toReal(), 0.0); QCOMPARE(flickable->property("maxHorizontalOvershoot").toReal(), 0.0); + QCOMPARE(flickable->property("maxVerticalOvershoot").toReal(), 0.0); + } + if ((boundsMovement == QQuickFlickable::FollowBoundsBehavior) == (boundsBehavior & QQuickFlickable::DragOverBounds)) { + QCOMPARE(flickable->property("maxContentX").toReal() - 200.0, + flickable->property("maxHorizontalOvershoot").toReal()); + QCOMPARE(flickable->property("maxContentY").toReal() - 200.0, + flickable->property("maxVerticalOvershoot").toReal()); } - QCOMPARE(flickable->property("minContentY").toReal(), 200.0); QCOMPARE(flickable->property("minContentX").toReal(), 200.0); - QCOMPARE(flickable->property("minVerticalOvershoot").toReal(), 0.0); + QCOMPARE(flickable->property("minContentY").toReal(), 200.0); QCOMPARE(flickable->property("minHorizontalOvershoot").toReal(), 0.0); + QCOMPARE(flickable->property("minVerticalOvershoot").toReal(), 0.0); flickable->setContentX(180.0); flickable->setContentY(180.0); @@ -2170,37 +2344,59 @@ void tst_qquickflickable::overshoot() flick(window.data(), QPoint(50, 50), QPoint(10, 10), 100); QTRY_VERIFY(!flickable->property("flicking").toBool()); + if ((boundsMovement == QQuickFlickable::FollowBoundsBehavior) && (boundsBehavior & QQuickFlickable::OvershootBounds)) { + QVERIFY(flickable->property("maxContentX").toReal() > 200.0); + QVERIFY(flickable->property("maxContentY").toReal() > 200.0); + } else { + QCOMPARE(flickable->property("maxContentX").toReal(), 200.0); + QCOMPARE(flickable->property("maxContentY").toReal(), 200.0); + } if (boundsBehavior & QQuickFlickable::OvershootBounds) { - QVERIFY(flickable->property("maxVerticalOvershoot").toReal() > 0.0); QVERIFY(flickable->property("maxHorizontalOvershoot").toReal() > 0.0); - QCOMPARE(flickable->property("maxContentY").toReal() - 200.0, - flickable->property("maxVerticalOvershoot").toReal()); - QCOMPARE(flickable->property("maxContentX").toReal() - 200.0, - flickable->property("maxHorizontalOvershoot").toReal()); + QVERIFY(flickable->property("maxVerticalOvershoot").toReal() > 0.0); } else { - QCOMPARE(flickable->property("maxContentY").toReal(), 200.0); - QCOMPARE(flickable->property("maxContentX").toReal(), 200.0); - QCOMPARE(flickable->property("maxVerticalOvershoot").toReal(), 0.0); QCOMPARE(flickable->property("maxHorizontalOvershoot").toReal(), 0.0); + QCOMPARE(flickable->property("maxVerticalOvershoot").toReal(), 0.0); + } + if ((boundsMovement == QQuickFlickable::FollowBoundsBehavior) == (boundsBehavior & QQuickFlickable::OvershootBounds)) { + QCOMPARE(flickable->property("maxContentX").toReal() - 200.0, + flickable->property("maxHorizontalOvershoot").toReal()); + QCOMPARE(flickable->property("maxContentY").toReal() - 200.0, + flickable->property("maxVerticalOvershoot").toReal()); } - QCOMPARE(flickable->property("minContentY").toReal(), 180.0); QCOMPARE(flickable->property("minContentX").toReal(), 180.0); - QCOMPARE(flickable->property("minVerticalOvershoot").toReal(), 0.0); + QCOMPARE(flickable->property("minContentY").toReal(), 180.0); QCOMPARE(flickable->property("minHorizontalOvershoot").toReal(), 0.0); + QCOMPARE(flickable->property("minVerticalOvershoot").toReal(), 0.0); } void tst_qquickflickable::overshoot_data() { QTest::addColumn<QQuickFlickable::BoundsBehavior>("boundsBehavior"); - - QTest::newRow("StopAtBounds") - << QQuickFlickable::BoundsBehavior(QQuickFlickable::StopAtBounds); - QTest::newRow("DragOverBounds") - << QQuickFlickable::BoundsBehavior(QQuickFlickable::DragOverBounds); - QTest::newRow("OvershootBounds") - << QQuickFlickable::BoundsBehavior(QQuickFlickable::OvershootBounds); - QTest::newRow("DragAndOvershootBounds") - << QQuickFlickable::BoundsBehavior(QQuickFlickable::DragAndOvershootBounds); + QTest::addColumn<int>("boundsMovement"); + + QTest::newRow("StopAtBounds,FollowBoundsBehavior") + << QQuickFlickable::BoundsBehavior(QQuickFlickable::StopAtBounds) + << int(QQuickFlickable::FollowBoundsBehavior); + QTest::newRow("DragOverBounds,FollowBoundsBehavior") + << QQuickFlickable::BoundsBehavior(QQuickFlickable::DragOverBounds) + << int(QQuickFlickable::FollowBoundsBehavior); + QTest::newRow("OvershootBounds,FollowBoundsBehavior") + << QQuickFlickable::BoundsBehavior(QQuickFlickable::OvershootBounds) + << int(QQuickFlickable::FollowBoundsBehavior); + QTest::newRow("DragAndOvershootBounds,FollowBoundsBehavior") + << QQuickFlickable::BoundsBehavior(QQuickFlickable::DragAndOvershootBounds) + << int(QQuickFlickable::FollowBoundsBehavior); + + QTest::newRow("DragOverBounds,StopAtBounds") + << QQuickFlickable::BoundsBehavior(QQuickFlickable::DragOverBounds) + << int(QQuickFlickable::StopAtBounds); + QTest::newRow("OvershootBounds,StopAtBounds") + << QQuickFlickable::BoundsBehavior(QQuickFlickable::OvershootBounds) + << int(QQuickFlickable::StopAtBounds); + QTest::newRow("DragAndOvershootBounds,StopAtBounds") + << QQuickFlickable::BoundsBehavior(QQuickFlickable::DragAndOvershootBounds) + << int(QQuickFlickable::StopAtBounds); } void tst_qquickflickable::overshoot_reentrant() diff --git a/tests/auto/quick/qquickimage/tst_qquickimage.cpp b/tests/auto/quick/qquickimage/tst_qquickimage.cpp index 2681f1a966..36d99ad48d 100644 --- a/tests/auto/quick/qquickimage/tst_qquickimage.cpp +++ b/tests/auto/quick/qquickimage/tst_qquickimage.cpp @@ -375,7 +375,7 @@ void tst_qquickimage::mirror() } QImage img = expected.toImage(); - QCOMPARE(screenshots[fillMode], img); + QCOMPARE(screenshots[fillMode].convertToFormat(img.format()), img); } } diff --git a/tests/auto/quick/qquickmultipointtoucharea/BLACKLIST b/tests/auto/quick/qquickmultipointtoucharea/BLACKLIST index 1777af9e0c..cab6e2f7bf 100644 --- a/tests/auto/quick/qquickmultipointtoucharea/BLACKLIST +++ b/tests/auto/quick/qquickmultipointtoucharea/BLACKLIST @@ -1,2 +1,4 @@ -[inFlickable] -* +[nonOverlapping] +ubuntu-16.04 +[nested] +ubuntu-16.04 diff --git a/tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp b/tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp index 2872556a94..87acd67f6a 100644 --- a/tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp +++ b/tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp @@ -800,7 +800,7 @@ void tst_QQuickMultiPointTouchArea::inFlickable2() QVERIFY(flickable->contentY() < 0); QVERIFY(flickable->isMoving()); - QCOMPARE(point11->pressed(), true); + QCOMPARE(point11->pressed(), false); QTest::touchEvent(window.data(), device).release(0, p1); QQuickTouchUtils::flush(window.data()); diff --git a/tests/auto/quick/qquickpositioners/data/implicitGridOneItem.qml b/tests/auto/quick/qquickpositioners/data/implicitGridOneItem.qml deleted file mode 100644 index 8da9fc270d..0000000000 --- a/tests/auto/quick/qquickpositioners/data/implicitGridOneItem.qml +++ /dev/null @@ -1,12 +0,0 @@ -import QtQuick 2.9 -import PositionerTest 1.0 - -ImplicitGrid { - columns: 2 - rows: 1 - - Text { - text: "Text" - width: parent.width - } -} diff --git a/tests/auto/quick/qquickpositioners/data/implicitRowOneItem.qml b/tests/auto/quick/qquickpositioners/data/implicitRowOneItem.qml deleted file mode 100644 index 25a287cf31..0000000000 --- a/tests/auto/quick/qquickpositioners/data/implicitRowOneItem.qml +++ /dev/null @@ -1,9 +0,0 @@ -import QtQuick 2.9 -import PositionerTest 1.0 - -ImplicitRow { - Text { - text: "Text" - width: parent.width - } -} diff --git a/tests/auto/quick/qquickpositioners/tst_qquickpositioners.cpp b/tests/auto/quick/qquickpositioners/tst_qquickpositioners.cpp index 4c4afb7a7b..1b3939401a 100644 --- a/tests/auto/quick/qquickpositioners/tst_qquickpositioners.cpp +++ b/tests/auto/quick/qquickpositioners/tst_qquickpositioners.cpp @@ -98,8 +98,6 @@ private slots: void test_attachedproperties(); void test_attachedproperties_data(); void test_attachedproperties_dynamic(); - void test_useImplicitSize_oneItem_data(); - void test_useImplicitSize_oneItem(); void populateTransitions_row(); void populateTransitions_row_data(); @@ -306,8 +304,6 @@ void tst_qquickpositioners::moveTransitions_flow_data() tst_qquickpositioners::tst_qquickpositioners() { - qmlRegisterType<QQuickImplicitRow>("PositionerTest", 1, 0, "ImplicitRow"); - qmlRegisterType<QQuickImplicitGrid>("PositionerTest", 1, 0, "ImplicitGrid"); } void tst_qquickpositioners::test_horizontal() @@ -4008,46 +4004,6 @@ void tst_qquickpositioners::test_attachedproperties_dynamic() } -void tst_qquickpositioners::test_useImplicitSize_oneItem_data() -{ - QTest::addColumn<QString>("positionerType"); - - QTest::newRow("Grid") << "Grid"; - QTest::newRow("Row") << "Row"; -} - -void tst_qquickpositioners::test_useImplicitSize_oneItem() -{ - QFETCH(QString, positionerType); - - QQuickView view; - view.setSource(testFileUrl(QString::fromLatin1("implicit%1OneItem.qml").arg(positionerType))); - QCOMPARE(view.status(), QQuickView::Ready); - view.show(); - QVERIFY(QTest::qWaitForWindowExposed(&view)); - - QQuickItem *positioner = view.rootObject(); - QVERIFY(positioner); - const qreal oldPositionerImplicitWidth = positioner->implicitWidth(); - - QQuickText *text = qobject_cast<QQuickText*>(positioner->childItems().first()); - QVERIFY(text); - const qreal oldTextImplicitWidth = text->implicitWidth(); - QCOMPARE(positioner->implicitWidth(), text->implicitWidth()); - - // Ensure that the implicit size of the positioner changes when the implicit size - // of one of its children changes. - text->setText(QLatin1String("Even More Text")); - const qreal textImplicitWidthIncrease = text->implicitWidth() - oldTextImplicitWidth; - QVERIFY(textImplicitWidthIncrease > 0); - QTRY_COMPARE(positioner->implicitWidth(), oldPositionerImplicitWidth + textImplicitWidthIncrease); - - // Ensure that the implicit size of the positioner does not change when the - // explicit size of one of its children changes. - text->setWidth(10); - QTRY_COMPARE(positioner->implicitWidth(), oldPositionerImplicitWidth + textImplicitWidthIncrease); -} - QQuickView *tst_qquickpositioners::createView(const QString &filename, bool wait) { QQuickView *window = new QQuickView(0); diff --git a/tests/auto/quick/qquickwindow/BLACKLIST b/tests/auto/quick/qquickwindow/BLACKLIST new file mode 100644 index 0000000000..157808fdbf --- /dev/null +++ b/tests/auto/quick/qquickwindow/BLACKLIST @@ -0,0 +1,4 @@ +[requestActivate] +osx-10.11 +[attachedProperty] +osx-10.11 diff --git a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp index 578f737c4d..4fea13eb49 100644 --- a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp +++ b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp @@ -28,6 +28,7 @@ #include <qtest.h> #include <QDebug> +#include <QMimeData> #include <QTouchEvent> #include <QtQuick/QQuickItem> #include <QtQuick/QQuickView> @@ -385,6 +386,8 @@ private slots: void grabContentItemToImage(); + void testDragEventPropertyPropagation(); + private: QTouchDevice *touchDevice; QTouchDevice *touchDeviceWithVelocity; @@ -2617,6 +2620,261 @@ void tst_qquickwindow::grabContentItemToImage() QTRY_COMPARE(created->property("success").toInt(), 1); } +class TestDropTarget : public QQuickItem +{ + Q_OBJECT +public: + TestDropTarget(QQuickItem *parent = 0) + : QQuickItem(parent) + , enterDropAction(Qt::CopyAction) + , moveDropAction(Qt::CopyAction) + , dropDropAction(Qt::CopyAction) + , enterAccept(true) + , moveAccept(true) + , dropAccept(true) + { + setFlags(ItemAcceptsDrops); + } + + void reset() + { + enterDropAction = Qt::CopyAction; + moveDropAction = Qt::CopyAction; + dropDropAction = Qt::CopyAction; + enterAccept = true; + moveAccept = true; + dropAccept = true; + } + + void dragEnterEvent(QDragEnterEvent *event) + { + event->setAccepted(enterAccept); + event->setDropAction(enterDropAction); + } + + void dragMoveEvent(QDragMoveEvent *event) + { + event->setAccepted(moveAccept); + event->setDropAction(moveDropAction); + } + + void dropEvent(QDropEvent *event) + { + event->setAccepted(dropAccept); + event->setDropAction(dropDropAction); + } + + Qt::DropAction enterDropAction; + Qt::DropAction moveDropAction; + Qt::DropAction dropDropAction; + bool enterAccept; + bool moveAccept; + bool dropAccept; +}; + +class DragEventTester { +public: + DragEventTester() + : pos(60, 60) + , actions(Qt::CopyAction | Qt::MoveAction | Qt::LinkAction) + , buttons(Qt::LeftButton) + , modifiers(Qt::NoModifier) + { + } + + ~DragEventTester() { + qDeleteAll(events); + events.clear(); + enterEvent = 0; + moveEvent = 0; + dropEvent = 0; + leaveEvent = 0; + } + + void addEnterEvent() + { + enterEvent = new QDragEnterEvent(pos, actions, &data, buttons, modifiers); + events.append(enterEvent); + } + + void addMoveEvent() + { + moveEvent = new QDragMoveEvent(pos, actions, &data, buttons, modifiers, QEvent::DragMove); + events.append(moveEvent); + } + + void addDropEvent() + { + dropEvent = new QDropEvent(pos, actions, &data, buttons, modifiers, QEvent::Drop); + events.append(dropEvent); + } + + void addLeaveEvent() + { + leaveEvent = new QDragLeaveEvent(); + events.append(leaveEvent); + } + + void sendDragEventSequence(QQuickWindow *window) const { + for (int i = 0; i < events.size(); ++i) { + QCoreApplication::sendEvent(window, events[i]); + } + } + + // Used for building events. + QMimeData data; + QPoint pos; + Qt::DropActions actions; + Qt::MouseButtons buttons; + Qt::KeyboardModifiers modifiers; + + // Owns events. + QList<QEvent *> events; + + // Non-owner pointers for easy acccess. + QDragEnterEvent *enterEvent; + QDragMoveEvent *moveEvent; + QDropEvent *dropEvent; + QDragLeaveEvent *leaveEvent; +}; + +void tst_qquickwindow::testDragEventPropertyPropagation() +{ + QQuickWindow window; + TestDropTarget dropTarget(window.contentItem()); + + // Setting the size is important because the QQuickWindow checks if the drag happened inside + // the drop target. + dropTarget.setSize(QSizeF(100, 100)); + + // Test enter events property propagation. + // For enter events, only isAccepted gets propagated. + { + DragEventTester builder; + dropTarget.enterAccept = false; + dropTarget.enterDropAction = Qt::IgnoreAction; + builder.addEnterEvent(); builder.addMoveEvent(); builder.addLeaveEvent(); + builder.sendDragEventSequence(&window); + QDragEnterEvent* enterEvent = builder.enterEvent; + QCOMPARE(enterEvent->isAccepted(), dropTarget.enterAccept); + } + { + DragEventTester builder; + dropTarget.enterAccept = false; + dropTarget.enterDropAction = Qt::CopyAction; + builder.addEnterEvent(); builder.addMoveEvent(); builder.addLeaveEvent(); + builder.sendDragEventSequence(&window); + QDragEnterEvent* enterEvent = builder.enterEvent; + QCOMPARE(enterEvent->isAccepted(), dropTarget.enterAccept); + } + { + DragEventTester builder; + dropTarget.enterAccept = true; + dropTarget.enterDropAction = Qt::IgnoreAction; + builder.addEnterEvent(); builder.addMoveEvent(); builder.addLeaveEvent(); + builder.sendDragEventSequence(&window); + QDragEnterEvent* enterEvent = builder.enterEvent; + QCOMPARE(enterEvent->isAccepted(), dropTarget.enterAccept); + } + { + DragEventTester builder; + dropTarget.enterAccept = true; + dropTarget.enterDropAction = Qt::CopyAction; + builder.addEnterEvent(); builder.addMoveEvent(); builder.addLeaveEvent(); + builder.sendDragEventSequence(&window); + QDragEnterEvent* enterEvent = builder.enterEvent; + QCOMPARE(enterEvent->isAccepted(), dropTarget.enterAccept); + } + + // Test move events property propagation. + // For move events, both isAccepted and dropAction get propagated. + dropTarget.reset(); + { + DragEventTester builder; + dropTarget.moveAccept = false; + dropTarget.moveDropAction = Qt::IgnoreAction; + builder.addEnterEvent(); builder.addMoveEvent(); builder.addLeaveEvent(); + builder.sendDragEventSequence(&window); + QDragMoveEvent* moveEvent = builder.moveEvent; + QCOMPARE(moveEvent->isAccepted(), dropTarget.moveAccept); + QCOMPARE(moveEvent->dropAction(), dropTarget.moveDropAction); + } + { + DragEventTester builder; + dropTarget.moveAccept = false; + dropTarget.moveDropAction = Qt::CopyAction; + builder.addEnterEvent(); builder.addMoveEvent(); builder.addLeaveEvent(); + builder.sendDragEventSequence(&window); + QDragMoveEvent* moveEvent = builder.moveEvent; + QCOMPARE(moveEvent->isAccepted(), dropTarget.moveAccept); + QCOMPARE(moveEvent->dropAction(), dropTarget.moveDropAction); + } + { + DragEventTester builder; + dropTarget.moveAccept = true; + dropTarget.moveDropAction = Qt::IgnoreAction; + builder.addEnterEvent(); builder.addMoveEvent(); builder.addLeaveEvent(); + builder.sendDragEventSequence(&window); + QDragMoveEvent* moveEvent = builder.moveEvent; + QCOMPARE(moveEvent->isAccepted(), dropTarget.moveAccept); + QCOMPARE(moveEvent->dropAction(), dropTarget.moveDropAction); + } + { + DragEventTester builder; + dropTarget.moveAccept = true; + dropTarget.moveDropAction = Qt::CopyAction; + builder.addEnterEvent(); builder.addMoveEvent(); builder.addLeaveEvent(); + builder.sendDragEventSequence(&window); + QDragMoveEvent* moveEvent = builder.moveEvent; + QCOMPARE(moveEvent->isAccepted(), dropTarget.moveAccept); + QCOMPARE(moveEvent->dropAction(), dropTarget.moveDropAction); + } + + // Test drop events property propagation. + // For drop events, both isAccepted and dropAction get propagated. + dropTarget.reset(); + { + DragEventTester builder; + dropTarget.dropAccept = false; + dropTarget.dropDropAction = Qt::IgnoreAction; + builder.addEnterEvent(); builder.addMoveEvent(); builder.addDropEvent(); + builder.sendDragEventSequence(&window); + QDropEvent* dropEvent = builder.dropEvent; + QCOMPARE(dropEvent->isAccepted(), dropTarget.dropAccept); + QCOMPARE(dropEvent->dropAction(), dropTarget.dropDropAction); + } + { + DragEventTester builder; + dropTarget.dropAccept = false; + dropTarget.dropDropAction = Qt::CopyAction; + builder.addEnterEvent(); builder.addMoveEvent(); builder.addDropEvent(); + builder.sendDragEventSequence(&window); + QDropEvent* dropEvent = builder.dropEvent; + QCOMPARE(dropEvent->isAccepted(), dropTarget.dropAccept); + QCOMPARE(dropEvent->dropAction(), dropTarget.dropDropAction); + } + { + DragEventTester builder; + dropTarget.dropAccept = true; + dropTarget.dropDropAction = Qt::IgnoreAction; + builder.addEnterEvent(); builder.addMoveEvent(); builder.addDropEvent(); + builder.sendDragEventSequence(&window); + QDropEvent* dropEvent = builder.dropEvent; + QCOMPARE(dropEvent->isAccepted(), dropTarget.dropAccept); + QCOMPARE(dropEvent->dropAction(), dropTarget.dropDropAction); + } + { + DragEventTester builder; + dropTarget.dropAccept = true; + dropTarget.dropDropAction = Qt::CopyAction; + builder.addEnterEvent(); builder.addMoveEvent(); builder.addDropEvent(); + builder.sendDragEventSequence(&window); + QDropEvent* dropEvent = builder.dropEvent; + QCOMPARE(dropEvent->isAccepted(), dropTarget.dropAccept); + QCOMPARE(dropEvent->dropAction(), dropTarget.dropDropAction); + } +} + QTEST_MAIN(tst_qquickwindow) #include "tst_qquickwindow.moc" diff --git a/tests/auto/quick/touchmouse/tst_touchmouse.cpp b/tests/auto/quick/touchmouse/tst_touchmouse.cpp index b02d60d0c5..6e7fce6189 100644 --- a/tests/auto/quick/touchmouse/tst_touchmouse.cpp +++ b/tests/auto/quick/touchmouse/tst_touchmouse.cpp @@ -71,7 +71,7 @@ Q_SIGNALS: public: EventItem(QQuickItem *parent = 0) - : QQuickItem(parent), acceptMouse(false), acceptTouch(false), filterTouch(false), point0(-1) + : QQuickItem(parent), touchUngrabCount(0), acceptMouse(false), acceptTouch(false), filterTouch(false), point0(-1) { setAcceptedMouseButtons(Qt::LeftButton); } @@ -111,11 +111,17 @@ public: eventList.append(Event(QEvent::UngrabMouse, QPoint(0,0), QPoint(0,0))); } + void touchUngrabEvent() + { + ++touchUngrabCount; + } + bool event(QEvent *event) { return QQuickItem::event(event); } QList<Event> eventList; + int touchUngrabCount; bool acceptMouse; bool acceptTouch; bool filterTouch; // when used as event filter @@ -158,6 +164,7 @@ private slots: void mouseOverTouch(); void buttonOnFlickable(); + void touchButtonOnFlickable(); void buttonOnDelayedPressFlickable_data(); void buttonOnDelayedPressFlickable(); void buttonOnTouch(); @@ -568,9 +575,10 @@ void tst_TouchMouse::buttonOnFlickable() QCOMPARE(pointerEvent->point(0)->exclusiveGrabber(), eventItem1); QCOMPARE(window->mouseGrabberItem(), eventItem1); - p1 += QPoint(0, -10); - QPoint p2 = p1 + QPoint(0, -10); - QPoint p3 = p2 + QPoint(0, -10); + int dragDelta = -qApp->styleHints()->startDragDistance(); + p1 += QPoint(0, dragDelta); + QPoint p2 = p1 + QPoint(0, dragDelta); + QPoint p3 = p2 + QPoint(0, dragDelta); QQuickTouchUtils::flush(window.data()); QTest::touchEvent(window.data(), device).move(0, p1, window.data()); QQuickTouchUtils::flush(window.data()); @@ -593,6 +601,66 @@ void tst_TouchMouse::buttonOnFlickable() QQuickTouchUtils::flush(window.data()); } +void tst_TouchMouse::touchButtonOnFlickable() +{ + // flickable - height 500 / 1000 + // - eventItem1 y: 100, height 100 + // - eventItem2 y: 300, height 100 + + QScopedPointer<QQuickView> window(createView()); + window->setSource(testFileUrl("buttononflickable.qml")); + window->show(); + QQuickViewTestUtil::centerOnScreen(window.data()); + QVERIFY(QTest::qWaitForWindowActive(window.data())); + QVERIFY(window->rootObject() != 0); + + QQuickFlickable *flickable = window->rootObject()->findChild<QQuickFlickable*>("flickable"); + QVERIFY(flickable); + + EventItem *eventItem2 = window->rootObject()->findChild<EventItem*>("eventItem2"); + QVERIFY(eventItem2); + QCOMPARE(eventItem2->eventList.size(), 0); + eventItem2->acceptTouch = true; + + // press via touch, then drag: check that flickable moves and that the button gets ungrabbed + QCOMPARE(eventItem2->eventList.size(), 0); + QPoint p1 = QPoint(10, 310); + QTest::touchEvent(window.data(), device).press(0, p1, window.data()); + QQuickTouchUtils::flush(window.data()); + QCOMPARE(eventItem2->eventList.size(), 1); + QCOMPARE(eventItem2->eventList.at(0).type, QEvent::TouchBegin); + + QQuickWindowPrivate *windowPriv = QQuickWindowPrivate::get(window.data()); + QVERIFY(windowPriv->touchMouseId == -1); + auto pointerEvent = QQuickPointerDevice::touchDevices().at(0)->pointerEvent(); + QCOMPARE(pointerEvent->point(0)->grabberItem(), eventItem2); + QCOMPARE(window->mouseGrabberItem(), nullptr); + + int dragDelta = qApp->styleHints()->startDragDistance() * -0.7; + p1 += QPoint(0, dragDelta); + QPoint p2 = p1 + QPoint(0, dragDelta); + QPoint p3 = p2 + QPoint(0, dragDelta); + + QQuickTouchUtils::flush(window.data()); + QTest::touchEvent(window.data(), device).move(0, p1, window.data()); + QQuickTouchUtils::flush(window.data()); + QTest::touchEvent(window.data(), device).move(0, p2, window.data()); + QQuickTouchUtils::flush(window.data()); + QTest::touchEvent(window.data(), device).move(0, p3, window.data()); + QQuickTouchUtils::flush(window.data()); + + QVERIFY(eventItem2->eventList.size() > 2); + QCOMPARE(eventItem2->eventList.at(1).type, QEvent::TouchUpdate); + QCOMPARE(eventItem2->touchUngrabCount, 1); + QCOMPARE(window->mouseGrabberItem(), flickable); + QVERIFY(windowPriv->touchMouseId != -1); + QCOMPARE(pointerEvent->point(0)->grabberItem(), flickable); + QVERIFY(flickable->isMovingVertically()); + + QTest::touchEvent(window.data(), device).release(0, p3, window.data()); + QQuickTouchUtils::flush(window.data()); +} + void tst_TouchMouse::buttonOnDelayedPressFlickable_data() { QTest::addColumn<bool>("scrollBeforeDelayIsOver"); diff --git a/tests/auto/quickwidgets/qquickwidget/tst_qquickwidget.cpp b/tests/auto/quickwidgets/qquickwidget/tst_qquickwidget.cpp index 5e8f762e23..bd051ec990 100644 --- a/tests/auto/quickwidgets/qquickwidget/tst_qquickwidget.cpp +++ b/tests/auto/quickwidgets/qquickwidget/tst_qquickwidget.cpp @@ -58,6 +58,7 @@ private slots: void grabBeforeShow(); void reparentToNewWindow(); void nullEngine(); + void keyEvents(); }; @@ -337,6 +338,33 @@ void tst_qquickwidget::nullEngine() QVERIFY(widget.engine()); } +class KeyHandlingWidget : public QQuickWidget +{ +public: + void keyPressEvent(QKeyEvent *e) override { + if (e->key() == Qt::Key_A) + ok = true; + } + + bool ok = false; +}; + +void tst_qquickwidget::keyEvents() +{ + // A QQuickWidget should behave like a normal widget when it comes to event handling. + // Verify that key events actually reach the widget. (QTBUG-45757) + KeyHandlingWidget widget; + widget.setSource(testFileUrl("rectangle.qml")); + widget.show(); + QVERIFY(QTest::qWaitForWindowExposed(widget.window(), 5000)); + + // Note: send the event to the QWindow, not the QWidget, in order + // to simulate the full event processing chain. + QTest::keyClick(widget.window()->windowHandle(), Qt::Key_A); + + QTRY_VERIFY(widget.ok); +} + QTEST_MAIN(tst_qquickwidget) #include "tst_qquickwidget.moc" diff --git a/tests/auto/toolsupport/tst_toolsupport.cpp b/tests/auto/toolsupport/tst_toolsupport.cpp index 9a11a67e65..6ee1db805a 100644 --- a/tests/auto/toolsupport/tst_toolsupport.cpp +++ b/tests/auto/toolsupport/tst_toolsupport.cpp @@ -101,7 +101,7 @@ void tst_toolsupport::offsets_data() = QTest::newRow("CompiledData::CompilationUnit::data") << pmm_to_offsetof(&QV4::CompiledData::CompilationUnit::data); - data << 8 << 16; + data << 12 << 24; } { @@ -109,7 +109,7 @@ void tst_toolsupport::offsets_data() = QTest::newRow("CompiledData::CompilationUnit::runtimeStrings") << pmm_to_offsetof(&QV4::CompiledData::CompilationUnit::runtimeStrings); - data << 16 << 32; + data << 0 << 0; } { diff --git a/tests/benchmarks/qml/holistic/testtypes.h b/tests/benchmarks/qml/holistic/testtypes.h index 0736982373..a752a8585b 100644 --- a/tests/benchmarks/qml/holistic/testtypes.h +++ b/tests/benchmarks/qml/holistic/testtypes.h @@ -43,6 +43,7 @@ #include <QtQml/qjsvalue.h> #include <QtQml/qqmlscriptstring.h> #include <QtQml/qqmlcomponent.h> +#include <QtCore/qregexp.h> class MyQmlAttachedObject : public QObject { diff --git a/tests/manual/scenegraph_lancelot/scenegrabber/main.cpp b/tests/manual/scenegraph_lancelot/scenegrabber/main.cpp index 886cfc6599..6da0799bbc 100644 --- a/tests/manual/scenegraph_lancelot/scenegrabber/main.cpp +++ b/tests/manual/scenegraph_lancelot/scenegrabber/main.cpp @@ -29,6 +29,7 @@ #include <QtCore/QTimer> #include <QtCore/QDebug> #include <QtCore/QFileInfo> +#include <QtCore/QHashFunctions> #include <QtGui/QGuiApplication> #include <QtGui/QImage> @@ -134,11 +135,9 @@ private: }; -Q_CORE_EXPORT extern QBasicAtomicInt qt_qhash_seed; - int main(int argc, char *argv[]) { - qt_qhash_seed = 0; + qSetGlobalQHashSeed(0); QGuiApplication a(argc, argv); diff --git a/tests/manual/v4/test262 b/tests/manual/v4/test262 deleted file mode 160000 -Subproject 9741ac4655808ac46c127e3d1d8ba3d27ada618 diff --git a/tests/manual/v4/tests.pro b/tests/manual/v4/tests.pro deleted file mode 100644 index ce4a34f7a0..0000000000 --- a/tests/manual/v4/tests.pro +++ /dev/null @@ -1,15 +0,0 @@ -TEMPLATE = aux - -TESTSCRIPT=$$PWD/test262.py -isEmpty(V4CMD): V4CMD = qmljs - -checktarget.target = check -checktarget.commands = python $$TESTSCRIPT --command=$$V4CMD --parallel --with-test-expectations --update-expectations -checktarget.depends = all -QMAKE_EXTRA_TARGETS += checktarget - -checkmothtarget.target = check-interpreter -checkmothtarget.commands = python $$TESTSCRIPT --command=\"$$V4CMD --interpret\" --parallel --with-test-expectations -checkmothtarget.depends = all -QMAKE_EXTRA_TARGETS += checkmothtarget - |