diff options
Diffstat (limited to 'tests/auto/qml/debugger')
43 files changed, 882 insertions, 125 deletions
diff --git a/tests/auto/qml/debugger/debugger.pro b/tests/auto/qml/debugger/debugger.pro index 63721cc575..5c328fbfcc 100644 --- a/tests/auto/qml/debugger/debugger.pro +++ b/tests/auto/qml/debugger/debugger.pro @@ -1,5 +1,7 @@ TEMPLATE = subdirs +SUBDIRS += qqmldebugjsserver + PUBLICTESTS += \ qdebugmessageservice \ qqmlenginedebugservice \ @@ -11,7 +13,8 @@ PUBLICTESTS += \ qqmlenginecontrol \ qqmldebuggingenabler \ qqmlnativeconnector \ - qqmldebugprocess + qqmldebugprocess \ + qqmlpreview PRIVATETESTS += \ qqmldebugclient \ @@ -21,6 +24,9 @@ PRIVATETESTS += \ SUBDIRS += $$PUBLICTESTS +qqmldebugjs.depends = qqmldebugjsserver +qqmlprofilerservice.depends = qqmldebugjsserver + qtConfig(private_tests): \ SUBDIRS += $$PRIVATETESTS diff --git a/tests/auto/qml/debugger/qdebugmessageservice/tst_qdebugmessageservice.cpp b/tests/auto/qml/debugger/qdebugmessageservice/tst_qdebugmessageservice.cpp index f851688b5e..d2cfd3897a 100644 --- a/tests/auto/qml/debugger/qdebugmessageservice/tst_qdebugmessageservice.cpp +++ b/tests/auto/qml/debugger/qdebugmessageservice/tst_qdebugmessageservice.cpp @@ -89,21 +89,12 @@ public: protected: //inherited from QQmlDebugClient - void stateChanged(State state); void messageReceived(const QByteArray &data); signals: - void enabled(); void debugOutput(); }; -void QQmlDebugMsgClient::stateChanged(State state) -{ - if (state == Enabled) { - emit enabled(); - } -} - void QQmlDebugMsgClient::messageReceived(const QByteArray &data) { QPacket ds(connection()->currentDataStreamVersion(), data); diff --git a/tests/auto/qml/debugger/qqmldebugclient/tst_qqmldebugclient.cpp b/tests/auto/qml/debugger/qqmldebugclient/tst_qqmldebugclient.cpp index 452520cf11..ffdbf72ded 100644 --- a/tests/auto/qml/debugger/qqmldebugclient/tst_qqmldebugclient.cpp +++ b/tests/auto/qml/debugger/qqmldebugclient/tst_qqmldebugclient.cpp @@ -66,8 +66,6 @@ void tst_QQmlDebugClient::initTestCase() QQmlDebugConnector::setPluginKey(QLatin1String("QQmlDebugServer")); QQmlDebugConnector::setServices(QStringList() << QStringLiteral("tst_QQmlDebugClient::handshake()")); - QTest::ignoreMessage(QtWarningMsg, - "QML debugger: Cannot set plugin key after loading the plugin."); m_service = new QQmlDebugTestService("tst_QQmlDebugClient::handshake()"); diff --git a/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenabler/tst_qqmldebuggingenabler.cpp b/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenabler/tst_qqmldebuggingenabler.cpp index 52e7f85e52..37118f4bd0 100644 --- a/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenabler/tst_qqmldebuggingenabler.cpp +++ b/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenabler/tst_qqmldebuggingenabler.cpp @@ -125,7 +125,7 @@ void tst_QQmlDebuggingEnabler::qmlscene() QQmlDebugClient::Enabled : QQmlDebugClient::Unavailable); } - QCOMPARE(m_process->state(), QLatin1String("running")); + QCOMPARE(m_process->state(), QProcess::Running); if (!blockMode) { QTRY_VERIFY_WITH_TIMEOUT(m_process->output().contains( QLatin1String("Component.onCompleted")), 15000); @@ -172,7 +172,7 @@ void tst_QQmlDebuggingEnabler::custom() QQmlDebugClient::Enabled : QQmlDebugClient::Unavailable); } - QCOMPARE(m_process->state(), QLatin1String("running")); + QCOMPARE(m_process->state(), QProcess::Running); if (!blockMode) { QTRY_VERIFY_WITH_TIMEOUT(m_process->output().contains(QLatin1String("QQmlEngine created")), 15000); diff --git a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/breakpointRelocation.qml b/tests/auto/qml/debugger/qqmldebugjs/data/breakpointRelocation.qml index 06aabc94f9..06aabc94f9 100644 --- a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/breakpointRelocation.qml +++ b/tests/auto/qml/debugger/qqmldebugjs/data/breakpointRelocation.qml diff --git a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/changeBreakpoint.qml b/tests/auto/qml/debugger/qqmldebugjs/data/changeBreakpoint.qml index 00a85e56ac..00a85e56ac 100644 --- a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/changeBreakpoint.qml +++ b/tests/auto/qml/debugger/qqmldebugjs/data/changeBreakpoint.qml diff --git a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/condition.qml b/tests/auto/qml/debugger/qqmldebugjs/data/condition.qml index 3a50ba2eb7..3a50ba2eb7 100644 --- a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/condition.qml +++ b/tests/auto/qml/debugger/qqmldebugjs/data/condition.qml diff --git a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/createComponent.qml b/tests/auto/qml/debugger/qqmldebugjs/data/createComponent.qml index 089cc03733..089cc03733 100644 --- a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/createComponent.qml +++ b/tests/auto/qml/debugger/qqmldebugjs/data/createComponent.qml diff --git a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/encodeQmlScope.qml b/tests/auto/qml/debugger/qqmldebugjs/data/encodeQmlScope.qml index 7ea048044f..7ea048044f 100644 --- a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/encodeQmlScope.qml +++ b/tests/auto/qml/debugger/qqmldebugjs/data/encodeQmlScope.qml diff --git a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/exception.qml b/tests/auto/qml/debugger/qqmldebugjs/data/exception.qml index 06f11fa016..06f11fa016 100644 --- a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/exception.qml +++ b/tests/auto/qml/debugger/qqmldebugjs/data/exception.qml diff --git a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/loadjsfile.qml b/tests/auto/qml/debugger/qqmldebugjs/data/loadjsfile.qml index 088c1b19fd..088c1b19fd 100644 --- a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/loadjsfile.qml +++ b/tests/auto/qml/debugger/qqmldebugjs/data/loadjsfile.qml diff --git a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/oncompleted.qml b/tests/auto/qml/debugger/qqmldebugjs/data/oncompleted.qml index deba24cf91..deba24cf91 100644 --- a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/oncompleted.qml +++ b/tests/auto/qml/debugger/qqmldebugjs/data/oncompleted.qml diff --git a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/quit.qml b/tests/auto/qml/debugger/qqmldebugjs/data/quit.qml index bc8c2b90ae..bc8c2b90ae 100644 --- a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/quit.qml +++ b/tests/auto/qml/debugger/qqmldebugjs/data/quit.qml diff --git a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/stepAction.qml b/tests/auto/qml/debugger/qqmldebugjs/data/stepAction.qml index fb0b6c401c..fb0b6c401c 100644 --- a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/stepAction.qml +++ b/tests/auto/qml/debugger/qqmldebugjs/data/stepAction.qml diff --git a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/test.js b/tests/auto/qml/debugger/qqmldebugjs/data/test.js index 92e61d103c..92e61d103c 100644 --- a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/test.js +++ b/tests/auto/qml/debugger/qqmldebugjs/data/test.js diff --git a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/test.qml b/tests/auto/qml/debugger/qqmldebugjs/data/test.qml index a36d0cae91..a36d0cae91 100644 --- a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/test.qml +++ b/tests/auto/qml/debugger/qqmldebugjs/data/test.qml diff --git a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/timer.qml b/tests/auto/qml/debugger/qqmldebugjs/data/timer.qml index 66e6b96e18..66e6b96e18 100644 --- a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/timer.qml +++ b/tests/auto/qml/debugger/qqmldebugjs/data/timer.qml diff --git a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs.pro b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs.pro index bd6debcea1..b9d5f116dc 100644 --- a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs.pro +++ b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs.pro @@ -1,4 +1,24 @@ -TEMPLATE = subdirs -SUBDIRS = qqmldebugjs qqmldebugjsserver +CONFIG += testcase +TARGET = tst_qqmldebugjs +QT += qml testlib gui-private core-private +macos:CONFIG -= app_bundle -qqmldebugjs.depends = qqmldebugjsserver +SOURCES += tst_qqmldebugjs.cpp + +INCLUDEPATH += ../shared +include(../shared/debugutil.pri) +include(../shared/qqmlenginedebugclient.pri) + +TESTDATA = data/* + +OTHER_FILES += data/test.qml data/test.js \ + data/timer.qml \ + data/exception.qml \ + data/oncompleted.qml \ + data/loadjsfile.qml \ + data/condition.qml \ + data/changeBreakpoint.qml \ + data/stepAction.qml \ + data/breakpointRelocation.qml \ + data/createComponent.qml \ + data/encodeQmlScope.qml diff --git a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/qqmldebugjs.pro b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/qqmldebugjs.pro deleted file mode 100644 index 52d70bd1b1..0000000000 --- a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/qqmldebugjs.pro +++ /dev/null @@ -1,24 +0,0 @@ -CONFIG += testcase -TARGET = tst_qqmldebugjs -QT += qml testlib gui-private core-private -CONFIG -= debug_and_release_target -osx:CONFIG -= app_bundle - -SOURCES += tst_qqmldebugjs.cpp - -include(../../shared/debugutil.pri) -include(../../shared/qqmlenginedebugclient.pri) - -TESTDATA = data/* - -OTHER_FILES += data/test.qml data/test.js \ - data/timer.qml \ - data/exception.qml \ - data/oncompleted.qml \ - data/loadjsfile.qml \ - data/condition.qml \ - data/changeBreakpoint.qml \ - data/stepAction.qml \ - data/breakpointRelocation.qml \ - data/createComponent.qml \ - data/encodeQmlScope.qml diff --git a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjsserver/qqmldebugjsserver.pro b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjsserver/qqmldebugjsserver.pro deleted file mode 100644 index 837eaed9f1..0000000000 --- a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjsserver/qqmldebugjsserver.pro +++ /dev/null @@ -1,12 +0,0 @@ -QT += qml testlib -osx:CONFIG -= app_bundle -CONFIG -= debug_and_release_target -INCLUDEPATH += ../../shared -SOURCES += qqmldebugjsserver.cpp -DEFINES += QT_QML_DEBUG_NO_WARNING - -DESTDIR = ../qqmldebugjs - -target.path = $$[QT_INSTALL_TESTS]/tst_qqmldebugjs -INSTALLS += target - diff --git a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/tst_qqmldebugjs.cpp b/tests/auto/qml/debugger/qqmldebugjs/tst_qqmldebugjs.cpp index a28dbcd9de..e3996e0c18 100644 --- a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/tst_qqmldebugjs.cpp +++ b/tests/auto/qml/debugger/qqmldebugjs/tst_qqmldebugjs.cpp @@ -28,8 +28,8 @@ #include "debugutil_p.h" #include "qqmldebugprocess_p.h" -#include "../../shared/qqmlenginedebugclient.h" -#include "../../../../shared/util.h" +#include "../shared/qqmlenginedebugclient.h" +#include "../../../shared/util.h" #include <private/qqmldebugclient_p.h> #include <private/qqmldebugconnection_p.h> @@ -256,6 +256,8 @@ public: { parser = jsEngine.evaluate(QLatin1String("JSON.parse")); stringify = jsEngine.evaluate(QLatin1String("JSON.stringify")); + QObject::connect(this, &QQmlDebugClient::stateChanged, + this, &QJSDebugClient::onStateChanged); } void connect(bool redundantRefs = false, bool namesAsObjects = false); @@ -277,7 +279,7 @@ public: protected: //inherited from QQmlDebugClient - void stateChanged(State state); + void onStateChanged(State state); void messageReceived(const QByteArray &data); signals: @@ -665,7 +667,7 @@ void QJSDebugClient::disconnect() sendMessage(packMessage(DISCONNECT, json.toString().toUtf8())); } -void QJSDebugClient::stateChanged(State state) +void QJSDebugClient::onStateChanged(State state) { if (state == Enabled) flushSendBuffer(); @@ -770,7 +772,7 @@ QQmlDebugTest::ConnectResult tst_QQmlDebugJS::init(bool qmlscene, const QString { const QString executable = qmlscene ? QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene" - : QCoreApplication::applicationDirPath() + QLatin1String("/qqmldebugjsserver"); + : debugJsServerPath("qqmldebugjs"); return QQmlDebugTest::connect( executable, restrictServices ? QStringLiteral("V8Debugger") : QString(), testFile(qmlFile), blockMode); diff --git a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjsserver/qqmldebugjsserver.cpp b/tests/auto/qml/debugger/qqmldebugjsserver/qqmldebugjsserver.cpp index 6a4ec5cc75..6a4ec5cc75 100644 --- a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjsserver/qqmldebugjsserver.cpp +++ b/tests/auto/qml/debugger/qqmldebugjsserver/qqmldebugjsserver.cpp diff --git a/tests/auto/qml/debugger/qqmldebugjsserver/qqmldebugjsserver.pro b/tests/auto/qml/debugger/qqmldebugjsserver/qqmldebugjsserver.pro new file mode 100644 index 0000000000..a31da57054 --- /dev/null +++ b/tests/auto/qml/debugger/qqmldebugjsserver/qqmldebugjsserver.pro @@ -0,0 +1,9 @@ +QT += qml testlib +macos:CONFIG -= app_bundle +INCLUDEPATH += ../shared +SOURCES += qqmldebugjsserver.cpp +DEFINES += QT_QML_DEBUG_NO_WARNING + +target.path = $$[QT_INSTALL_TESTS]/qqmldebugjsserver +INSTALLS += target + diff --git a/tests/auto/qml/debugger/qqmldebuglocal/tst_qqmldebuglocal.cpp b/tests/auto/qml/debugger/qqmldebuglocal/tst_qqmldebuglocal.cpp index 5b3c0c5240..4e47c92c2a 100644 --- a/tests/auto/qml/debugger/qqmldebuglocal/tst_qqmldebuglocal.cpp +++ b/tests/auto/qml/debugger/qqmldebuglocal/tst_qqmldebuglocal.cpp @@ -65,8 +65,6 @@ void tst_QQmlDebugLocal::initTestCase() { fileName = QString::fromLatin1("tst_QQmlDebugLocal%1").arg(std::time(nullptr)); QQmlDebugConnector::setPluginKey("QQmlDebugServer"); - QTest::ignoreMessage(QtWarningMsg, - "QML debugger: Cannot set plugin key after loading the plugin."); m_service = new QQmlDebugTestService("tst_QQmlDebugLocal::handshake()"); const QString waitingMsg = QString("QML Debugger: Connecting to socket %1...").arg(fileName); diff --git a/tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocess/tst_qqmldebugprocess.cpp b/tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocess/tst_qqmldebugprocess.cpp index 993a1d5f63..35bd912d9b 100644 --- a/tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocess/tst_qqmldebugprocess.cpp +++ b/tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocess/tst_qqmldebugprocess.cpp @@ -118,7 +118,7 @@ void tst_QQmlDebugProcess::sessionStart() QTimer::singleShot(delay, process.data(), wait); QTRY_VERIFY(done); - QVERIFY(process->state().startsWith("not running")); + QCOMPARE(process->state(), QProcess::NotRunning); } QTEST_MAIN(tst_QQmlDebugProcess) diff --git a/tests/auto/qml/debugger/qqmldebugservice/tst_qqmldebugservice.cpp b/tests/auto/qml/debugger/qqmldebugservice/tst_qqmldebugservice.cpp index 1daf6b581e..3557940386 100644 --- a/tests/auto/qml/debugger/qqmldebugservice/tst_qqmldebugservice.cpp +++ b/tests/auto/qml/debugger/qqmldebugservice/tst_qqmldebugservice.cpp @@ -75,8 +75,6 @@ void tst_QQmlDebugService::initTestCase() QQmlDebugConnector::setPluginKey(QLatin1String("QQmlDebugServer")); QQmlDebugConnector::setServices(QStringList() << QStringLiteral("tst_QQmlDebugService")); - QTest::ignoreMessage(QtWarningMsg, - "QML debugger: Cannot set plugin key after loading the plugin."); m_service = new QQmlDebugTestService("tst_QQmlDebugService", 2); foreach (const QString &service, QQmlDebuggingEnabler::debuggerServices()) diff --git a/tests/auto/qml/debugger/qqmlpreview/data/broken.qml b/tests/auto/qml/debugger/qqmlpreview/data/broken.qml new file mode 100644 index 0000000000..4ebbf7576a --- /dev/null +++ b/tests/auto/qml/debugger/qqmlpreview/data/broken.qml @@ -0,0 +1,31 @@ +/**************************************************************************** +** +** Copyright (C) 2018 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$ +** +****************************************************************************/ + +import QtQuick 2.0 + +Item { diff --git a/tests/auto/qml/debugger/qqmlpreview/data/qtquick2.qml b/tests/auto/qml/debugger/qqmlpreview/data/qtquick2.qml new file mode 100644 index 0000000000..b525ab4fa0 --- /dev/null +++ b/tests/auto/qml/debugger/qqmlpreview/data/qtquick2.qml @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2018 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$ +** +****************************************************************************/ + +import QtQuick 2.0 + +Rectangle { + width: 100 + height: 100 + color: "blue" + + RotationAnimation on rotation { + duration: 3600 + loops: Animation.Infinite + from: 0 + to: 360 + } + + Timer { + interval: 300 + repeat: true + running: true + property int prevHit: -1 + property int prevRotation: -1 + onTriggered: { + var date = new Date; + var millis = date.getMilliseconds() + + if (prevHit < 0) { + prevHit = millis; + prevRotation = parent.rotation + return; + } + + var milliDelta = millis - prevHit; + if (milliDelta <= 0) + milliDelta += 1000; + prevHit = millis; + + var delta = parent.rotation - prevRotation; + if (delta < 0) + delta += 360 + prevRotation = parent.rotation + console.log(milliDelta, delta, "ms/degrees "); + } + } +} diff --git a/tests/auto/qml/debugger/qqmlpreview/data/window.qml b/tests/auto/qml/debugger/qqmlpreview/data/window.qml new file mode 100644 index 0000000000..f9f8d5aeb1 --- /dev/null +++ b/tests/auto/qml/debugger/qqmlpreview/data/window.qml @@ -0,0 +1,44 @@ +/**************************************************************************** +** +** Copyright (C) 2018 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$ +** +****************************************************************************/ + +import QtQuick 2.0 +import QtQuick.Window 2.0 + +Window { + visible: true + + height: 100 + width: 100 + + Timer { + repeat: false + interval: 1000 + running: true + onTriggered: console.log("window.qml"); + } +} diff --git a/tests/auto/qml/debugger/qqmlpreview/data/window1.qml b/tests/auto/qml/debugger/qqmlpreview/data/window1.qml new file mode 100644 index 0000000000..e8e9ad706d --- /dev/null +++ b/tests/auto/qml/debugger/qqmlpreview/data/window1.qml @@ -0,0 +1,43 @@ +/**************************************************************************** +** +** Copyright (C) 2018 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$ +** +****************************************************************************/ + +import QtQuick 2.0 +import QtQuick.Window 2.3 + +Window { + visible: true + + height: 200 + width: 100 + + Timer { + interval: 1000 + running: true + onTriggered: console.log("window1.qml"); + } +} diff --git a/tests/auto/qml/debugger/qqmlpreview/data/window2.qml b/tests/auto/qml/debugger/qqmlpreview/data/window2.qml new file mode 100644 index 0000000000..9ad42d2ee2 --- /dev/null +++ b/tests/auto/qml/debugger/qqmlpreview/data/window2.qml @@ -0,0 +1,43 @@ +/**************************************************************************** +** +** Copyright (C) 2018 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$ +** +****************************************************************************/ + +import QtQuick 2.0 +import QtQuick.Window 2.3 + +Window { + visible: true + + height: 100 + width: 200 + + Timer { + interval: 1000 + running: true + onTriggered: console.log("window2.qml"); + } +} diff --git a/tests/auto/qml/debugger/qqmlpreview/data/zoom.qml b/tests/auto/qml/debugger/qqmlpreview/data/zoom.qml new file mode 100644 index 0000000000..0aca235de1 --- /dev/null +++ b/tests/auto/qml/debugger/qqmlpreview/data/zoom.qml @@ -0,0 +1,51 @@ +/**************************************************************************** +** +** Copyright (C) 2018 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$ +** +****************************************************************************/ + +import QtQuick 2.0 +import QtQuick.Window 2.2 + +Window { + id: w + height: 100 + width: 100 + visible: true + + Rectangle { + width: 50 + height: 50 + color: "blue" + anchors.centerIn: parent + } + + Timer { + interval: 100 + running: true + repeat: true + onTriggered: console.log("zoom", w.screen.devicePixelRatio) + } +} diff --git a/tests/auto/qml/debugger/qqmlpreview/qqmlpreview.pro b/tests/auto/qml/debugger/qqmlpreview/qqmlpreview.pro new file mode 100644 index 0000000000..4a0d385e1a --- /dev/null +++ b/tests/auto/qml/debugger/qqmlpreview/qqmlpreview.pro @@ -0,0 +1,24 @@ +CONFIG += testcase +TARGET = tst_qqmlpreview + +QT += qml testlib core qmldebug-private +macos:CONFIG -= app_bundle + +INCLUDEPATH += ../../../../../src/plugins/qmltooling/qmldbg_preview/ + +SOURCES += \ + tst_qqmlpreview.cpp \ + ../../../../../src/plugins/qmltooling/qmldbg_preview/qqmlpreviewblacklist.cpp + +HEADERS += \ + ../../../../../src/plugins/qmltooling/qmldbg_preview/qqmlpreviewblacklist.h + +include(../shared/debugutil.pri) + +TESTDATA = \ + data/window.qml \ + data/qtquick2.qml \ + data/window2.qml \ + data/window1.qml \ + data/broken.qml \ + data/zoom.qml diff --git a/tests/auto/qml/debugger/qqmlpreview/tst_qqmlpreview.cpp b/tests/auto/qml/debugger/qqmlpreview/tst_qqmlpreview.cpp new file mode 100644 index 0000000000..fa416900d0 --- /dev/null +++ b/tests/auto/qml/debugger/qqmlpreview/tst_qqmlpreview.cpp @@ -0,0 +1,317 @@ +/**************************************************************************** +** +** Copyright (C) 2018 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 "qqmldebugprocess_p.h" +#include "debugutil_p.h" +#include "qqmlpreviewblacklist.h" + +#include <QtTest/qtest.h> +#include <QtTest/qsignalspy.h> +#include <QtCore/qtimer.h> +#include <QtCore/qdebug.h> +#include <QtCore/qthread.h> +#include <QtCore/qlibraryinfo.h> +#include <QtNetwork/qhostaddress.h> + +#include <private/qqmldebugconnection_p.h> +#include <private/qqmlpreviewclient_p.h> + +class tst_QQmlPreview : public QQmlDebugTest +{ + Q_OBJECT + +private: + ConnectResult startQmlProcess(const QString &qmlFile); + void serveRequest(const QString &path); + QList<QQmlDebugClient *> createClients() override; + + QPointer<QQmlPreviewClient> m_client; + + QStringList m_files; + QStringList m_filesNotFound; + QStringList m_directories; + QStringList m_serviceErrors; + +private slots: + void cleanup() final; + + void connect(); + void load(); + void rerun(); + void blacklist(); + void error(); + void zoom(); +}; + +QQmlDebugTest::ConnectResult tst_QQmlPreview::startQmlProcess(const QString &qmlFile) +{ + return QQmlDebugTest::connect(QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qml", + QStringLiteral("QmlPreview"), testFile(qmlFile), true); +} + +void tst_QQmlPreview::serveRequest(const QString &path) +{ + QFileInfo info(path); + + if (info.isDir()) { + m_directories.append(path); + m_client->sendDirectory(path, QDir(path).entryList()); + } else { + QFile file(path); + if (file.open(QIODevice::ReadOnly)) { + m_files.append(path); + m_client->sendFile(path, file.readAll()); + } else { + m_filesNotFound.append(path); + m_client->sendError(path); + } + } +} + +QList<QQmlDebugClient *> tst_QQmlPreview::createClients() +{ + m_client = new QQmlPreviewClient(m_connection); + + QObject::connect(m_client, &QQmlPreviewClient::request, this, &tst_QQmlPreview::serveRequest); + QObject::connect(m_client, &QQmlPreviewClient::error, this, [this](const QString &error) { + m_serviceErrors.append(error); + }); + + return QList<QQmlDebugClient *>({m_client}); +} + +void checkFiles(const QStringList &files) +{ + QVERIFY(!files.contains("/etc/localtime")); + QVERIFY(!files.contains("/etc/timezome")); + QVERIFY(!files.contains(":/qgradient/webgradients.binaryjson")); +} + +void tst_QQmlPreview::cleanup() +{ + // Use a separate function so that we don't return early from cleanup() on failure. + checkFiles(m_files); + + QQmlDebugTest::cleanup(); + if (QTest::currentTestFailed()) { + qDebug() << "Files loaded:" << m_files; + qDebug() << "Files not loaded:" << m_filesNotFound; + qDebug() << "Directories loaded:" << m_directories; + qDebug() << "Errors reported:" << m_serviceErrors; + } + + m_directories.clear(); + m_files.clear(); + m_filesNotFound.clear(); + m_serviceErrors.clear(); +} + +void tst_QQmlPreview::connect() +{ + const QString file("window.qml"); + QCOMPARE(startQmlProcess(file), ConnectSuccess); + QVERIFY(m_client); + QTRY_COMPARE(m_client->state(), QQmlDebugClient::Enabled); + m_client->triggerLoad(testFileUrl(file)); + QTRY_VERIFY(m_files.contains(testFile(file))); + QTRY_VERIFY_WITH_TIMEOUT(m_process->output().contains("qml: window.qml"), 10000); + m_process->stop(); + QTRY_COMPARE(m_client->state(), QQmlDebugClient::NotConnected); + QVERIFY(m_serviceErrors.isEmpty()); +} + +void tst_QQmlPreview::load() +{ + const QString file("qtquick2.qml"); + QCOMPARE(startQmlProcess(file), ConnectSuccess); + QVERIFY(m_client); + QTRY_COMPARE(m_client->state(), QQmlDebugClient::Enabled); + m_client->triggerLoad(testFileUrl(file)); + QTRY_VERIFY(m_files.contains(testFile(file))); + QTRY_VERIFY(m_process->output().contains("ms/degrees")); + + const QStringList files({"window2.qml", "window1.qml", "window.qml"}); + for (const QString &newFile : files) { + m_client->triggerLoad(testFileUrl(newFile)); + QTRY_VERIFY(m_files.contains(testFile(newFile))); + QTRY_VERIFY(m_process->output().contains(QString::fromLatin1("qml: %1").arg(newFile))); + } + + m_process->stop(); + QTRY_COMPARE(m_client->state(), QQmlDebugClient::NotConnected); + QVERIFY(m_serviceErrors.isEmpty()); +} + +void tst_QQmlPreview::rerun() +{ + const QString file("window.qml"); + QCOMPARE(startQmlProcess(file), ConnectSuccess); + QVERIFY(m_client); + m_client->triggerLoad(testFileUrl(file)); + const QLatin1String message("qml: window.qml"); + QTRY_VERIFY(m_process->output().contains(message)); + const int pos = m_process->output().lastIndexOf(message) + message.size(); + QVERIFY(pos >= 0); + + m_client->triggerRerun(); + QTRY_VERIFY(m_process->output().indexOf(message, pos) >= pos); + + m_process->stop(); + QVERIFY(m_serviceErrors.isEmpty()); +} + +void tst_QQmlPreview::blacklist() +{ + QQmlPreviewBlacklist blacklist; + + QStringList strings({ + "lalala", "lulul", "trakdkd", "suppe", "zack" + }); + + for (const QString &string : strings) + QVERIFY(!blacklist.isBlacklisted(string)); + + for (const QString &string : strings) + blacklist.blacklist(string); + + for (const QString &string : strings) { + QVERIFY(blacklist.isBlacklisted(string)); + QVERIFY(!blacklist.isBlacklisted(string.left(string.size() / 2))); + QVERIFY(!blacklist.isBlacklisted(string + "45")); + QVERIFY(!blacklist.isBlacklisted(" " + string)); + QVERIFY(blacklist.isBlacklisted(string + "/45")); + } + + for (auto begin = strings.begin(), it = begin, end = strings.end(); it != end; ++it) { + std::rotate(begin, it, end); + QString path = "/" + strings.join('/'); + blacklist.blacklist(path); + QVERIFY(blacklist.isBlacklisted(path)); + QVERIFY(blacklist.isBlacklisted(path + "/file")); + QVERIFY(!blacklist.isBlacklisted(path + "more")); + path.chop(1); + QVERIFY(!blacklist.isBlacklisted(path)); + std::reverse(begin, end); + } + + blacklist.clear(); + for (const QString &string : strings) + QVERIFY(!blacklist.isBlacklisted(string)); + + blacklist.blacklist(":/qt-project.org"); + QVERIFY(blacklist.isBlacklisted(":/qt-project.org/QmlRuntime/conf/configuration.qml")); + QVERIFY(!blacklist.isBlacklisted(":/qt-project.orgQmlRuntime/conf/configuration.qml")); + + QQmlPreviewBlacklist blacklist2; + + blacklist2.blacklist(":/qt-project.org"); + blacklist2.blacklist(":/QtQuick/Controls/Styles"); + blacklist2.blacklist(":/ExtrasImports/QtQuick/Controls/Styles"); + blacklist2.blacklist(QLibraryInfo::location(QLibraryInfo::Qml2ImportsPath)); + blacklist2.blacklist("/home/ulf/.local/share/QtProject/Qml Runtime/configuration.qml"); + blacklist2.blacklist("/usr/share"); + blacklist2.blacklist("/usr/share/QtProject/Qml Runtime/configuration.qml"); + QVERIFY(blacklist2.isBlacklisted(QLibraryInfo::location(QLibraryInfo::Qml2ImportsPath))); + blacklist2.blacklist("/usr/local/share/QtProject/Qml Runtime/configuration.qml"); + blacklist2.blacklist("qml"); + blacklist2.blacklist(""); // This should not remove all other paths. + + QVERIFY(blacklist2.isBlacklisted(QLibraryInfo::location(QLibraryInfo::Qml2ImportsPath) + + "/QtQuick/Window.2.0")); + QVERIFY(blacklist2.isBlacklisted(QLibraryInfo::location(QLibraryInfo::Qml2ImportsPath))); + QVERIFY(blacklist2.isBlacklisted("/usr/share/QtProject/Qml Runtime/configuration.qml")); + QVERIFY(blacklist2.isBlacklisted("/usr/share/stuff")); + QVERIFY(blacklist2.isBlacklisted("")); + + QQmlPreviewBlacklist blacklist3; + blacklist3.blacklist("/usr/share"); + blacklist3.blacklist("/usr"); + blacklist3.blacklist("/usrdings"); + QVERIFY(blacklist3.isBlacklisted("/usrdings")); + QVERIFY(blacklist3.isBlacklisted("/usr/src")); + QVERIFY(!blacklist3.isBlacklisted("/opt/share")); + QVERIFY(!blacklist3.isBlacklisted("/opt")); + + blacklist3.whitelist("/usr/share"); + QVERIFY(blacklist3.isBlacklisted("/usrdings")); + QVERIFY(!blacklist3.isBlacklisted("/usr")); + QVERIFY(!blacklist3.isBlacklisted("/usr/share")); + QVERIFY(!blacklist3.isBlacklisted("/usr/src")); + QVERIFY(!blacklist3.isBlacklisted("/opt/share")); + QVERIFY(!blacklist3.isBlacklisted("/opt")); +} + +void tst_QQmlPreview::error() +{ + QCOMPARE(startQmlProcess("window.qml"), ConnectSuccess); + QVERIFY(m_client); + m_client->triggerLoad(testFileUrl("broken.qml")); + QTRY_COMPARE_WITH_TIMEOUT(m_serviceErrors.count(), 1, 10000); + QVERIFY(m_serviceErrors.first().contains("broken.qml:32 Expected token `}'")); +} + +static float parseZoomFactor(const QString &output) +{ + const QString prefix("zoom "); + const int start = output.lastIndexOf(prefix) + prefix.length(); + if (start < 0) + return -1; + const int end = output.indexOf('\n', start); + if (end < 0) + return -1; + bool ok = false; + const float zoomFactor = output.mid(start, end - start).toFloat(&ok); + if (!ok) + return -1; + return zoomFactor; +} + +void tst_QQmlPreview::zoom() +{ + const QString file("zoom.qml"); + QCOMPARE(startQmlProcess(file), ConnectSuccess); + QVERIFY(m_client); + m_client->triggerLoad(testFileUrl(file)); + QTRY_VERIFY(m_files.contains(testFile(file))); + float baseZoomFactor = -1; + QTRY_VERIFY((baseZoomFactor = parseZoomFactor(m_process->output())) > 0); + m_client->triggerZoom(2.0f); + QTRY_VERIFY(qFuzzyCompare(parseZoomFactor(m_process->output()), baseZoomFactor * 2.0f)); + m_client->triggerZoom(1.5f); + QTRY_VERIFY(qFuzzyCompare(parseZoomFactor(m_process->output()), baseZoomFactor * 1.5f)); + m_client->triggerZoom(0.5f); + QTRY_VERIFY(qFuzzyCompare(parseZoomFactor(m_process->output()), baseZoomFactor * 0.5f)); + m_client->triggerZoom(-1.0f); + QTRY_VERIFY(qFuzzyCompare(parseZoomFactor(m_process->output()), baseZoomFactor)); + m_process->stop(); + QVERIFY(m_serviceErrors.isEmpty()); +} + +QTEST_MAIN(tst_QQmlPreview) + +#include "tst_qqmlpreview.moc" diff --git a/tests/auto/qml/debugger/qqmlprofilerservice/data/quit.qml b/tests/auto/qml/debugger/qqmlprofilerservice/data/quit.qml new file mode 100644 index 0000000000..bc8c2b90ae --- /dev/null +++ b/tests/auto/qml/debugger/qqmlprofilerservice/data/quit.qml @@ -0,0 +1,40 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +import QtQuick 2.0 + +//DO NOT CHANGE + +Item { + Timer { + running: true + triggeredOnStart: true + onTriggered: Qt.quit(); + } +} + diff --git a/tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp b/tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp index 3cb315b355..eb0b0c2fe2 100644 --- a/tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp +++ b/tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp @@ -34,6 +34,7 @@ #include <private/qqmldebugconnection_p.h> #include <QtTest/qtest.h> +#include <QtTest/qsignalspy.h> #include <QtCore/qlibraryinfo.h> #include <QtGui/private/qguiapplication_p.h> @@ -195,7 +196,9 @@ private: }; ConnectResult connect(bool block, const QString &testFile, bool recordFromStart = true, - uint flushInterval = 0, bool restrictServices = true); + uint flushInterval = 0, bool restrictServices = true, + const QString &executable + = QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene"); void checkProcessTerminated(); void checkTraceReceived(); void checkJsHeap(); @@ -221,6 +224,7 @@ private slots: void translationBinding(); void memory(); void compile(); + void multiEngine(); private: bool m_recordFromStart = true; @@ -237,7 +241,7 @@ private: QQmlDebugTest::ConnectResult tst_QQmlProfilerService::connect( bool block, const QString &file, bool recordFromStart, uint flushInterval, - bool restrictServices) + bool restrictServices, const QString &executable) { m_recordFromStart = recordFromStart; m_flushInterval = flushInterval; @@ -245,7 +249,7 @@ QQmlDebugTest::ConnectResult tst_QQmlProfilerService::connect( // ### Still using qmlscene due to QTBUG-33377 return QQmlDebugTest::connect( - QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene", + executable, restrictServices ? "CanvasFrameRate,EngineControl,DebugMessages" : QString(), testFile(file), block); } @@ -261,11 +265,13 @@ void tst_QQmlProfilerService::checkProcessTerminated() QVERIFY(m_client->client); QTRY_COMPARE(m_client->client->state(), QQmlDebugClient::NotConnected); QVERIFY(m_process); + QVERIFY(m_process->exitStatus() != QProcess::CrashExit); QTRY_COMPARE(m_process->exitStatus(), QProcess::NormalExit); } void tst_QQmlProfilerService::checkTraceReceived() { + QVERIFY(m_process->exitStatus() != QProcess::CrashExit); QTRY_VERIFY2(m_isComplete, "No trace received in time."); QVector<qint64> numbers; @@ -282,6 +288,7 @@ void tst_QQmlProfilerService::checkTraceReceived() void tst_QQmlProfilerService::checkJsHeap() { + QVERIFY(m_client); QVERIFY2(m_client->jsHeapMessages.count() > 0, "no JavaScript heap messages received"); bool seen_alloc = false; @@ -340,6 +347,11 @@ bool tst_QQmlProfilerService::verify(tst_QQmlProfilerService::MessageListType ty int expectedPosition, const QQmlProfilerEventType &expected, quint32 checks, const QVector<qint64> &expectedNumbers) { + if (!m_client) { + qWarning() << "No debug client available"; + return false; + } + const QVector<QQmlProfilerEvent> *target = nullptr; switch (type) { case MessageListQML: target = &(m_client->qmlMessages); break; @@ -349,6 +361,11 @@ bool tst_QQmlProfilerService::verify(tst_QQmlProfilerService::MessageListType ty case MessageListPixmap: target = &(m_client->pixmapMessages); break; } + if (!target) { + qWarning() << "Invalid MessageListType" << type; + return false; + } + if (target->length() <= expectedPosition) { qWarning() << "Not enough events. expected position:" << expectedPosition << "length:" << target->length(); @@ -629,7 +646,7 @@ void tst_QQmlProfilerService::scenegraphData() void tst_QQmlProfilerService::profileOnExit() { - connect(true, "exit.qml"); + QCOMPARE(connect(true, "exit.qml"), ConnectSuccess); checkProcessTerminated(); checkTraceReceived(); @@ -711,7 +728,7 @@ void tst_QQmlProfilerService::flushInterval() void tst_QQmlProfilerService::translationBinding() { - connect(true, "qstr.qml"); + QCOMPARE(connect(true, "qstr.qml"), ConnectSuccess); checkProcessTerminated(); checkTraceReceived(); @@ -727,12 +744,13 @@ void tst_QQmlProfilerService::translationBinding() void tst_QQmlProfilerService::memory() { - connect(true, "memory.qml"); + QCOMPARE(connect(true, "memory.qml"), ConnectSuccess); checkProcessTerminated(); checkTraceReceived(); checkJsHeap(); + QVERIFY(m_client); int smallItems = 0; for (auto message : m_client->jsHeapMessages) { const QQmlProfilerEventType &type = m_client->types[message.typeIndex()]; @@ -757,6 +775,8 @@ void tst_QQmlProfilerService::compile() // Flush interval so that we actually get the events before we stop recording. connect(true, "test.qml", true, 100); + QVERIFY(m_client); + // We need to check specifically for compile events as we can otherwise stop recording after the // StartTrace has arrived, but before it compiles anything. QTRY_VERIFY(hasCompileEvents(m_client->types)); @@ -790,6 +810,22 @@ void tst_QQmlProfilerService::compile() QCOMPARE(rangeStage, RangeEnd); } +void tst_QQmlProfilerService::multiEngine() +{ + QCOMPARE(connect(true, "quit.qml", true, 0, false, debugJsServerPath("qqmlprofilerservice")), + ConnectSuccess); + + QSignalSpy spy(m_client->client, SIGNAL(complete(qint64))); + + checkTraceReceived(); + checkJsHeap(); + + QTRY_COMPARE(m_process->state(), QProcess::NotRunning); + QCOMPARE(m_process->exitStatus(), QProcess::NormalExit); + + QCOMPARE(spy.count(), 1); +} + QTEST_MAIN(tst_QQmlProfilerService) #include "tst_qqmlprofilerservice.moc" diff --git a/tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp b/tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp index c65c592f10..a176f674e6 100644 --- a/tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp +++ b/tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp @@ -86,8 +86,7 @@ public: QV4::Scope scope(v4); QV4::ScopedString name(scope, v4->newString(functionName)); - QV4::ScopedContext ctx(scope, v4->rootContext()); - QV4::ScopedValue function(scope, FunctionObject::createBuiltinFunction(ctx, name, injectedFunction)); + QV4::ScopedValue function(scope, FunctionObject::createBuiltinFunction(v4, name, injectedFunction, 0)); v4->globalObject->put(name, function); } @@ -220,7 +219,21 @@ public: { for (int i = 0, ei = m_stackTrace.size(); i != ei; ++i) { m_capturedScope.append(NamedRefs()); - ScopeJob job(&collector, i, 0); + FrameJob frameJob(&collector, i); + debugger->runInEngine(&frameJob); + QJsonObject frameObj = frameJob.returnValue(); + QJsonArray scopes = frameObj.value(QLatin1String("scopes")).toArray(); + int nscopes = scopes.size(); + int s = 0; + for (s = 0; s < nscopes; ++s) { + QJsonObject o = scopes.at(s).toObject(); + if (o.value(QLatin1String("type")).toInt(-2) == 1) // CallContext + break; + } + if (s == nscopes) + return; + + ScopeJob job(&collector, i, s); debugger->runInEngine(&job); NamedRefs &refs = m_capturedScope.last(); QJsonObject object = job.returnValue(); @@ -482,7 +495,7 @@ void tst_qv4debugger::conditionalBreakPoint() QVERIFY(m_debuggerAgent->m_capturedScope.size() > 1); const TestAgent::NamedRefs &frame0 = m_debuggerAgent->m_capturedScope.at(0); - QCOMPARE(frame0.size(), 2); + QCOMPARE(frame0.size(), 3); QVERIFY(frame0.contains("i")); QCOMPARE(frame0.value("i").toInt(), 11); } @@ -541,7 +554,7 @@ void tst_qv4debugger::readArguments() QVERIFY(m_debuggerAgent->m_wasPaused); QVERIFY(m_debuggerAgent->m_capturedScope.size() > 1); const TestAgent::NamedRefs &frame0 = m_debuggerAgent->m_capturedScope.at(0); - QCOMPARE(frame0.size(), 4); + QCOMPARE(frame0.size(), 5); QVERIFY(frame0.contains(QStringLiteral("a"))); QCOMPARE(frame0.type(QStringLiteral("a")), QStringLiteral("number")); QCOMPARE(frame0.value(QStringLiteral("a")).toDouble(), 1.0); @@ -565,7 +578,7 @@ void tst_qv4debugger::readComplicatedArguments() QVERIFY(m_debuggerAgent->m_wasPaused); QVERIFY(m_debuggerAgent->m_capturedScope.size() > 1); const TestAgent::NamedRefs &frame0 = m_debuggerAgent->m_capturedScope.at(0); - QCOMPARE(frame0.size(), 1); + QCOMPARE(frame0.size(), 2); QVERIFY(frame0.contains(QStringLiteral("a"))); QCOMPARE(frame0.type(QStringLiteral("a")), QStringLiteral("number")); QCOMPARE(frame0.value(QStringLiteral("a")).toInt(), 12); @@ -589,7 +602,7 @@ void tst_qv4debugger::readLocals() QVERIFY(m_debuggerAgent->m_wasPaused); QVERIFY(m_debuggerAgent->m_capturedScope.size() > 1); const TestAgent::NamedRefs &frame0 = m_debuggerAgent->m_capturedScope.at(0); - QCOMPARE(frame0.size(), 4); // locals and parameters + QCOMPARE(frame0.size(), 5); // locals and parameters QVERIFY(frame0.contains("c")); QCOMPARE(frame0.type("c"), QStringLiteral("number")); QCOMPARE(frame0.value("c").toDouble(), 3.0); @@ -614,7 +627,7 @@ void tst_qv4debugger::readObject() QVERIFY(m_debuggerAgent->m_wasPaused); QVERIFY(m_debuggerAgent->m_capturedScope.size() > 1); const TestAgent::NamedRefs &frame0 = m_debuggerAgent->m_capturedScope.at(0); - QCOMPARE(frame0.size(), 2); + QCOMPARE(frame0.size(), 3); QVERIFY(frame0.contains("b")); QCOMPARE(frame0.type("b"), QStringLiteral("object")); QJsonObject b = frame0.rawValue("b"); @@ -679,7 +692,7 @@ void tst_qv4debugger::readContextInAllFrames() for (int i = 0; i < 12; ++i) { const TestAgent::NamedRefs &scope = m_debuggerAgent->m_capturedScope.at(i); - QCOMPARE(scope.size(), 2); + QCOMPARE(scope.size(), 3); QVERIFY(scope.contains("n")); QCOMPARE(scope.type("n"), QStringLiteral("number")); QCOMPARE(scope.value("n").toDouble(), i + 1.0); diff --git a/tests/auto/qml/debugger/shared/debugutil.cpp b/tests/auto/qml/debugger/shared/debugutil.cpp index b118b22c64..68446b53a4 100644 --- a/tests/auto/qml/debugger/shared/debugutil.cpp +++ b/tests/auto/qml/debugger/shared/debugutil.cpp @@ -98,6 +98,9 @@ QString QQmlDebugTest::connectionStateString(const QQmlDebugConnection *connecti QQmlDebugTestClient::QQmlDebugTestClient(const QString &s, QQmlDebugConnection *c) : QQmlDebugClient(s, c) { + connect(this, &QQmlDebugClient::stateChanged, this, [this](QQmlDebugClient::State newState) { + QCOMPARE(newState, state()); + }); } QByteArray QQmlDebugTestClient::waitForResponse() @@ -111,31 +114,12 @@ QByteArray QQmlDebugTestClient::waitForResponse() return lastMsg; } -void QQmlDebugTestClient::stateChanged(State stat) -{ - QCOMPARE(stat, state()); - emit stateHasChanged(); -} - void QQmlDebugTestClient::messageReceived(const QByteArray &ba) { lastMsg = ba; emit serverMessage(ba); } -template<typename F> -struct Finalizer { - F m_lambda; - Finalizer(F &&lambda) : m_lambda(std::forward<F>(lambda)) {} - ~Finalizer() { m_lambda(); } -}; - -template<typename F> -static Finalizer<F> defer(F &&lambda) -{ - return Finalizer<F>(std::forward<F>(lambda)); -} - QQmlDebugTest::ConnectResult QQmlDebugTest::connect( const QString &executable, const QString &services, const QString &extraArgs, bool block) @@ -162,31 +146,27 @@ QQmlDebugTest::ConnectResult QQmlDebugTest::connect( if (m_clients.contains(nullptr)) return ClientsFailed; - auto allEnabled = [this]() { - for (QQmlDebugClient *client : m_clients) { - if (client->state() != QQmlDebugClient::Enabled) - return false; - } - return true; - }; + ClientStateHandler stateHandler(m_clients, createOtherClients(m_connection), services.isEmpty() + ? QQmlDebugClient::Enabled : QQmlDebugClient::Unavailable); - QList<QQmlDebugClient *> others = createOtherClients(m_connection); - auto deleter = defer([&others]() { qDeleteAll(others); }); - Q_UNUSED(deleter); const int port = m_process->debugPort(); m_connection->connectToHost(QLatin1String("127.0.0.1"), port); - for (int tries = 0; tries < 100 && !allEnabled(); ++tries) - QTest::qWait(50); - if (!allEnabled()) + + QEventLoop loop; + QTimer timer; + QObject::connect(&stateHandler, &ClientStateHandler::allOk, &loop, &QEventLoop::quit); + QObject::connect(m_connection, &QQmlDebugConnection::disconnected, &loop, &QEventLoop::quit); + QObject::connect(&timer, &QTimer::timeout, &loop, &QEventLoop::quit); + + timer.start(5000); + loop.exec(); + + if (!stateHandler.allEnabled()) return EnableFailed; - const QQmlDebugClient::State expectedState = services.isEmpty() ? QQmlDebugClient::Enabled - : QQmlDebugClient::Unavailable; - for (QQmlDebugClient *other : others) { - if (other->state() != expectedState) - return RestrictFailed; - } + if (!stateHandler.othersAsExpected()) + return RestrictFailed; return ConnectSuccess; } @@ -211,7 +191,7 @@ void QQmlDebugTest::cleanup() if (QTest::currentTestFailed()) { const QString null = QStringLiteral("null"); - qDebug() << "Process State:" << (m_process ? m_process->state() : null); + qDebug() << "Process State:" << (m_process ? m_process->stateString() : null); qDebug() << "Application Output:" << (m_process ? m_process->output() : null); qDebug() << "Connection State:" << QQmlDebugTest::connectionStateString(m_connection); for (QQmlDebugClient *client : m_clients) { @@ -234,3 +214,50 @@ void QQmlDebugTest::cleanup() m_process = nullptr; } } + +ClientStateHandler::ClientStateHandler(const QList<QQmlDebugClient *> &clients, + const QList<QQmlDebugClient *> &others, + QQmlDebugClient::State expectedOthers) : + m_clients(clients), m_others(others), m_expectedOthers(expectedOthers) +{ + for (QQmlDebugClient *client : m_clients) { + QObject::connect(client, &QQmlDebugClient::stateChanged, + this, &ClientStateHandler::checkStates); + } + for (QQmlDebugClient *client : m_others) { + QObject::connect(client, &QQmlDebugClient::stateChanged, + this, &ClientStateHandler::checkStates); + } +} + +ClientStateHandler::~ClientStateHandler() +{ + qDeleteAll(m_others); +} + +void ClientStateHandler::checkStates() +{ + for (QQmlDebugClient *client : m_clients) { + if (client->state() != QQmlDebugClient::Enabled) + return; + } + + m_allEnabled = true; + + for (QQmlDebugClient *other : m_others) { + if (other->state() != m_expectedOthers) + return; + } + + m_othersAsExpected = true; + emit allOk(); +} + +QString debugJsServerPath(const QString &selfPath) +{ + static const char *debugserver = "qqmldebugjsserver"; + QString appPath = QCoreApplication::applicationDirPath(); + const int position = appPath.lastIndexOf(selfPath); + return (position == -1 ? appPath : appPath.replace(position, selfPath.length(), debugserver)) + + "/" + debugserver; +} diff --git a/tests/auto/qml/debugger/shared/debugutil_p.h b/tests/auto/qml/debugger/shared/debugutil_p.h index 94ad83bfce..1c32590305 100644 --- a/tests/auto/qml/debugger/shared/debugutil_p.h +++ b/tests/auto/qml/debugger/shared/debugutil_p.h @@ -88,11 +88,9 @@ public: QByteArray waitForResponse(); signals: - void stateHasChanged(); void serverMessage(const QByteArray &); protected: - virtual void stateChanged(State state); virtual void messageReceived(const QByteArray &ba); private: @@ -116,4 +114,33 @@ public: } }; +class ClientStateHandler : public QObject +{ + Q_OBJECT +public: + ClientStateHandler(const QList<QQmlDebugClient *> &clients, + const QList<QQmlDebugClient *> &others, + QQmlDebugClient::State expectedOthers); + + ~ClientStateHandler(); + + bool allEnabled() const { return m_allEnabled; } + bool othersAsExpected() const { return m_othersAsExpected; } + +signals: + void allOk(); + +private: + void checkStates(); + + const QList<QQmlDebugClient *> m_clients; + const QList<QQmlDebugClient *> m_others; + const QQmlDebugClient::State m_expectedOthers; + + bool m_allEnabled = false; + bool m_othersAsExpected = false; +}; + +QString debugJsServerPath(const QString &selfPath); + #endif // DEBUGUTIL_P_H diff --git a/tests/auto/qml/debugger/shared/qqmldebugprocess.cpp b/tests/auto/qml/debugger/shared/qqmldebugprocess.cpp index f2b85833c9..6f74edf863 100644 --- a/tests/auto/qml/debugger/shared/qqmldebugprocess.cpp +++ b/tests/auto/qml/debugger/shared/qqmldebugprocess.cpp @@ -50,6 +50,7 @@ QQmlDebugProcess::QQmlDebugProcess(const QString &executable, QObject *parent) this, [this]() { m_timer.stop(); m_eventLoop.quit(); + emit finished(); }); connect(&m_timer, &QTimer::timeout, this, &QQmlDebugProcess::timeout); @@ -60,7 +61,7 @@ QQmlDebugProcess::~QQmlDebugProcess() stop(); } -QString QQmlDebugProcess::state() +QString QQmlDebugProcess::stateString() const { QString stateStr; switch (m_process.state()) { @@ -155,6 +156,11 @@ bool QQmlDebugProcess::waitForFinished() return m_process.waitForFinished(); } +QProcess::ProcessState QQmlDebugProcess::state() const +{ + return m_process.state(); +} + QProcess::ExitStatus QQmlDebugProcess::exitStatus() const { return m_process.exitStatus(); diff --git a/tests/auto/qml/debugger/shared/qqmldebugprocess_p.h b/tests/auto/qml/debugger/shared/qqmldebugprocess_p.h index fd2c89bb41..945cc58c85 100644 --- a/tests/auto/qml/debugger/shared/qqmldebugprocess_p.h +++ b/tests/auto/qml/debugger/shared/qqmldebugprocess_p.h @@ -52,7 +52,7 @@ public: QQmlDebugProcess(const QString &executable, QObject *parent = 0); ~QQmlDebugProcess(); - QString state(); + QString stateString() const; void addEnvironment(const QString &environment); @@ -61,6 +61,7 @@ public: int debugPort() const; bool waitForFinished(); + QProcess::ProcessState state() const; QProcess::ExitStatus exitStatus() const; QString output() const; @@ -69,6 +70,7 @@ public: signals: void readyReadStandardOutput(); + void finished(); private slots: void timeout(); diff --git a/tests/auto/qml/debugger/shared/qqmldebugtestservice.cpp b/tests/auto/qml/debugger/shared/qqmldebugtestservice.cpp index 4dce07d824..896ed608fd 100644 --- a/tests/auto/qml/debugger/shared/qqmldebugtestservice.cpp +++ b/tests/auto/qml/debugger/shared/qqmldebugtestservice.cpp @@ -48,5 +48,4 @@ void QQmlDebugTestService::stateAboutToBeChanged(QQmlDebugService::State) void QQmlDebugTestService::stateChanged(State) { Q_ASSERT(QThread::currentThread() != thread()); - emit stateHasChanged(); } diff --git a/tests/auto/qml/debugger/shared/qqmldebugtestservice.h b/tests/auto/qml/debugger/shared/qqmldebugtestservice.h index 37b4a9f98c..9c39c0893d 100644 --- a/tests/auto/qml/debugger/shared/qqmldebugtestservice.h +++ b/tests/auto/qml/debugger/shared/qqmldebugtestservice.h @@ -38,9 +38,6 @@ class QQmlDebugTestService : public QQmlDebugService public: QQmlDebugTestService(const QString &s, float version = 1, QObject *parent = 0); -signals: - void stateHasChanged(); - protected: virtual void messageReceived(const QByteArray &ba); virtual void stateAboutToBeChanged(State state); |