aboutsummaryrefslogtreecommitdiffstats
path: root/tests/auto/qml/debugger
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/qml/debugger')
-rw-r--r--tests/auto/qml/debugger/debugger.pro9
-rw-r--r--tests/auto/qml/debugger/qdebugmessageservice/qdebugmessageservice.pro4
-rw-r--r--tests/auto/qml/debugger/qdebugmessageservice/tst_qdebugmessageservice.cpp93
-rw-r--r--tests/auto/qml/debugger/qpacketprotocol/qpacketprotocol.pro3
-rw-r--r--tests/auto/qml/debugger/qpacketprotocol/tst_qpacketprotocol.cpp2
-rw-r--r--tests/auto/qml/debugger/qqmldebugclient/qqmldebugclient.pro1
-rw-r--r--tests/auto/qml/debugger/qqmldebugclient/tst_qqmldebugclient.cpp10
-rw-r--r--tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenabler/qqmldebuggingenabler.pro2
-rw-r--r--tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenabler/tst_qqmldebuggingenabler.cpp161
-rw-r--r--tests/auto/qml/debugger/qqmldebugjs/data/breakOnAnchor.qml49
-rw-r--r--tests/auto/qml/debugger/qqmldebugjs/data/breakpointRelocation.qml (renamed from tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/breakpointRelocation.qml)0
-rw-r--r--tests/auto/qml/debugger/qqmldebugjs/data/changeBreakpoint.qml (renamed from tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/changeBreakpoint.qml)0
-rw-r--r--tests/auto/qml/debugger/qqmldebugjs/data/condition.qml (renamed from tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/condition.qml)0
-rw-r--r--tests/auto/qml/debugger/qqmldebugjs/data/createComponent.qml (renamed from tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/createComponent.qml)0
-rw-r--r--tests/auto/qml/debugger/qqmldebugjs/data/encodeQmlScope.qml19
-rw-r--r--tests/auto/qml/debugger/qqmldebugjs/data/exception.qml (renamed from tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/exception.qml)0
-rw-r--r--tests/auto/qml/debugger/qqmldebugjs/data/loadjsfile.qml (renamed from tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/loadjsfile.qml)0
-rw-r--r--tests/auto/qml/debugger/qqmldebugjs/data/oncompleted.qml (renamed from tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/oncompleted.qml)0
-rw-r--r--tests/auto/qml/debugger/qqmldebugjs/data/quit.qml (renamed from tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/quit.qml)0
-rw-r--r--tests/auto/qml/debugger/qqmldebugjs/data/stepAction.qml (renamed from tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/stepAction.qml)0
-rw-r--r--tests/auto/qml/debugger/qqmldebugjs/data/test.js (renamed from tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/test.js)0
-rw-r--r--tests/auto/qml/debugger/qqmldebugjs/data/test.qml (renamed from tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/test.qml)0
-rw-r--r--tests/auto/qml/debugger/qqmldebugjs/data/timer.qml (renamed from tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/timer.qml)0
-rw-r--r--tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs.pro26
-rw-r--r--tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/qqmldebugjs.pro25
-rw-r--r--tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/tst_qqmldebugjs.cpp1552
-rw-r--r--tests/auto/qml/debugger/qqmldebugjs/qqmldebugjsserver/qqmldebugjsserver.pro12
-rw-r--r--tests/auto/qml/debugger/qqmldebugjs/tst_qqmldebugjs.cpp1008
-rw-r--r--tests/auto/qml/debugger/qqmldebugjsserver/qqmldebugjsserver.cpp (renamed from tests/auto/qml/debugger/qqmldebugjs/qqmldebugjsserver/qqmldebugjsserver.cpp)0
-rw-r--r--tests/auto/qml/debugger/qqmldebugjsserver/qqmldebugjsserver.pro9
-rw-r--r--tests/auto/qml/debugger/qqmldebuglocal/qqmldebuglocal.pro1
-rw-r--r--tests/auto/qml/debugger/qqmldebuglocal/tst_qqmldebuglocal.cpp8
-rw-r--r--tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocess.pro4
-rw-r--r--tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocess/qqmldebugprocess.pro14
-rw-r--r--tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocess/tst_qqmldebugprocess.cpp126
-rw-r--r--tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocessprocess/qqmldebugprocessprocess.cpp39
-rw-r--r--tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocessprocess/qqmldebugprocessprocess.pro11
-rw-r--r--tests/auto/qml/debugger/qqmldebugservice/qqmldebugservice.pro2
-rw-r--r--tests/auto/qml/debugger/qqmldebugservice/tst_qqmldebugservice.cpp40
-rw-r--r--tests/auto/qml/debugger/qqmlenginecontrol/qqmlenginecontrol.pro4
-rw-r--r--tests/auto/qml/debugger/qqmlenginecontrol/tst_qqmlenginecontrol.cpp81
-rw-r--r--tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/qqmlenginedebuginspectorintegrationtest.pro6
-rw-r--r--tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/tst_qqmlenginedebuginspectorintegration.cpp130
-rw-r--r--tests/auto/qml/debugger/qqmlenginedebugservice/qqmlenginedebugservice.pro5
-rw-r--r--tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp330
-rw-r--r--tests/auto/qml/debugger/qqmlinspector/qqmlinspector.pro5
-rw-r--r--tests/auto/qml/debugger/qqmlinspector/tst_qqmlinspector.cpp85
-rw-r--r--tests/auto/qml/debugger/qqmlnativeconnector/tst_qqmlnativeconnector.cpp2
-rw-r--r--tests/auto/qml/debugger/qqmlpreview/data/broken.qml31
-rw-r--r--tests/auto/qml/debugger/qqmlpreview/data/i18n/qml_fr_FR.qm0
-rw-r--r--tests/auto/qml/debugger/qqmlpreview/data/qtquick2.qml71
-rw-r--r--tests/auto/qml/debugger/qqmlpreview/data/window.qml44
-rw-r--r--tests/auto/qml/debugger/qqmlpreview/data/window1.qml43
-rw-r--r--tests/auto/qml/debugger/qqmlpreview/data/window2.qml43
-rw-r--r--tests/auto/qml/debugger/qqmlpreview/data/zoom.qml51
-rw-r--r--tests/auto/qml/debugger/qqmlpreview/qqmlpreview.pro25
-rw-r--r--tests/auto/qml/debugger/qqmlpreview/tst_qqmlpreview.cpp365
-rw-r--r--tests/auto/qml/debugger/qqmlprofilerservice/data/batchOverflow.qml20
-rw-r--r--tests/auto/qml/debugger/qqmlprofilerservice/data/controlFromJS.qml7
-rw-r--r--tests/auto/qml/debugger/qqmlprofilerservice/data/exit.qml2
-rw-r--r--tests/auto/qml/debugger/qqmlprofilerservice/data/memory.qml17
-rw-r--r--tests/auto/qml/debugger/qqmlprofilerservice/data/qstr.qml9
-rw-r--r--tests/auto/qml/debugger/qqmlprofilerservice/data/quit.qml40
-rw-r--r--tests/auto/qml/debugger/qqmlprofilerservice/qqmlprofilerservice.pro9
-rw-r--r--tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp860
-rw-r--r--tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp168
-rw-r--r--tests/auto/qml/debugger/shared/debugutil.cpp281
-rw-r--r--tests/auto/qml/debugger/shared/debugutil.pri11
-rw-r--r--tests/auto/qml/debugger/shared/debugutil_p.h115
-rw-r--r--tests/auto/qml/debugger/shared/qqmldebugprocess.cpp249
-rw-r--r--tests/auto/qml/debugger/shared/qqmldebugprocess_p.h101
-rw-r--r--tests/auto/qml/debugger/shared/qqmldebugtestservice.cpp1
-rw-r--r--tests/auto/qml/debugger/shared/qqmldebugtestservice.h3
-rw-r--r--tests/auto/qml/debugger/shared/qqmlenginedebugclient.cpp508
-rw-r--r--tests/auto/qml/debugger/shared/qqmlenginedebugclient.h233
-rw-r--r--tests/auto/qml/debugger/shared/qqmlenginedebugclient.pri3
-rw-r--r--tests/auto/qml/debugger/shared/qqmlinspectorclient.cpp124
-rw-r--r--tests/auto/qml/debugger/shared/qqmlinspectorclient.h59
-rw-r--r--tests/auto/qml/debugger/shared/qqmlinspectorclient.pri3
79 files changed, 3607 insertions, 3767 deletions
diff --git a/tests/auto/qml/debugger/debugger.pro b/tests/auto/qml/debugger/debugger.pro
index a50411e18b..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 \
@@ -10,7 +12,9 @@ PUBLICTESTS += \
qqmlenginedebuginspectorintegrationtest \
qqmlenginecontrol \
qqmldebuggingenabler \
- qqmlnativeconnector
+ qqmlnativeconnector \
+ qqmldebugprocess \
+ qqmlpreview
PRIVATETESTS += \
qqmldebugclient \
@@ -20,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/qdebugmessageservice.pro b/tests/auto/qml/debugger/qdebugmessageservice/qdebugmessageservice.pro
index 6c729ab235..3f2c0ca390 100644
--- a/tests/auto/qml/debugger/qdebugmessageservice/qdebugmessageservice.pro
+++ b/tests/auto/qml/debugger/qdebugmessageservice/qdebugmessageservice.pro
@@ -1,12 +1,10 @@
CONFIG += testcase
TARGET = tst_qdebugmessageservice
-QT += qml network testlib gui-private core-private
+QT += network testlib gui-private core-private
osx:CONFIG -= app_bundle
SOURCES += tst_qdebugmessageservice.cpp
-INCLUDEPATH += ../shared
-include(../../../shared/util.pri)
include(../shared/debugutil.pri)
TESTDATA = data/*
diff --git a/tests/auto/qml/debugger/qdebugmessageservice/tst_qdebugmessageservice.cpp b/tests/auto/qml/debugger/qdebugmessageservice/tst_qdebugmessageservice.cpp
index f193d3928a..d2cfd3897a 100644
--- a/tests/auto/qml/debugger/qdebugmessageservice/tst_qdebugmessageservice.cpp
+++ b/tests/auto/qml/debugger/qdebugmessageservice/tst_qdebugmessageservice.cpp
@@ -28,7 +28,6 @@
//QQmlDebugTest
#include "debugutil_p.h"
-#include "../../../shared/util.h"
#include <private/qqmldebugclient_p.h>
#include <private/qqmldebugconnection_p.h>
@@ -38,31 +37,19 @@
#include <QtCore/qlibraryinfo.h>
#include <QtTest/qtest.h>
-const char *NORMALMODE = "-qmljsdebugger=port:3777,3787,block";
const char *QMLFILE = "test.qml";
class QQmlDebugMsgClient;
-class tst_QDebugMessageService : public QQmlDataTest
+class tst_QDebugMessageService : public QQmlDebugTest
{
Q_OBJECT
-public:
- tst_QDebugMessageService();
-
- void init();
-
private slots:
- void initTestCase();
- void cleanupTestCase();
-
- void cleanup();
-
void retrieveDebugOutput();
private:
- QQmlDebugProcess *m_process;
- QQmlDebugMsgClient *m_client;
- QQmlDebugConnection *m_connection;
+ QList<QQmlDebugClient *> createClients() override;
+ QPointer<QQmlDebugMsgClient> m_client;
};
struct LogEntry {
@@ -102,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);
@@ -150,73 +128,16 @@ void QQmlDebugMsgClient::messageReceived(const QByteArray &data)
}
}
-tst_QDebugMessageService::tst_QDebugMessageService()
-{
-}
-
-void tst_QDebugMessageService::initTestCase()
+QList<QQmlDebugClient *> tst_QDebugMessageService::createClients()
{
- QQmlDataTest::initTestCase();
- m_process = 0;
- m_client = 0;
- m_connection = 0;
-}
-
-void tst_QDebugMessageService::cleanupTestCase()
-{
- if (m_process)
- delete m_process;
-
- if (m_client)
- delete m_client;
-
- if (m_connection)
- delete m_connection;
-}
-
-void tst_QDebugMessageService::init()
-{
- m_connection = new QQmlDebugConnection();
- m_process = new QQmlDebugProcess(QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qml", this);
m_client = new QQmlDebugMsgClient(m_connection);
-
- m_process->start(QStringList() << QLatin1String(NORMALMODE) << QQmlDataTest::instance()->testFile(QMLFILE));
- QVERIFY2(m_process->waitForSessionStart(),
- "Could not launch application, or did not get 'Waiting for connection'.");
-
- const int port = m_process->debugPort();
- m_connection->connectToHost("127.0.0.1", port);
- QVERIFY(m_connection->waitForConnected());
-
- if (m_client->state() != QQmlDebugClient::Enabled)
- QQmlDebugTest::waitForSignal(m_client, SIGNAL(enabled()));
-
- QCOMPARE(m_client->state(), QQmlDebugClient::Enabled);
-}
-
-void tst_QDebugMessageService::cleanup()
-{
- if (QTest::currentTestFailed()) {
- qDebug() << "Process State:" << m_process->state();
- qDebug() << "Application Output:" << m_process->output();
- }
- if (m_process)
- delete m_process;
-
- if (m_client)
- delete m_client;
-
- if (m_connection)
- delete m_connection;
-
- m_process = 0;
- m_client = 0;
- m_connection = 0;
+ return QList<QQmlDebugClient *>({m_client});
}
void tst_QDebugMessageService::retrieveDebugOutput()
{
- init();
+ QCOMPARE(QQmlDebugTest::connect(QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qml",
+ QString(), testFile(QMLFILE), true), ConnectSuccess);
QTRY_VERIFY(m_client->logBuffer.size() >= 2);
diff --git a/tests/auto/qml/debugger/qpacketprotocol/qpacketprotocol.pro b/tests/auto/qml/debugger/qpacketprotocol/qpacketprotocol.pro
index a7c0fa7f8e..dc0120cd87 100644
--- a/tests/auto/qml/debugger/qpacketprotocol/qpacketprotocol.pro
+++ b/tests/auto/qml/debugger/qpacketprotocol/qpacketprotocol.pro
@@ -4,7 +4,6 @@ osx:CONFIG -= app_bundle
SOURCES += tst_qpacketprotocol.cpp
-INCLUDEPATH += ../shared
include(../shared/debugutil.pri)
-QT += qml network testlib gui-private core-private
+QT += network testlib gui-private core-private
diff --git a/tests/auto/qml/debugger/qpacketprotocol/tst_qpacketprotocol.cpp b/tests/auto/qml/debugger/qpacketprotocol/tst_qpacketprotocol.cpp
index cadc2a7cc4..21ca921304 100644
--- a/tests/auto/qml/debugger/qpacketprotocol/tst_qpacketprotocol.cpp
+++ b/tests/auto/qml/debugger/qpacketprotocol/tst_qpacketprotocol.cpp
@@ -60,7 +60,7 @@ private slots:
void tst_QPacketProtocol::init()
{
m_server = new QTcpServer(this);
- m_serverConn = 0;
+ m_serverConn = nullptr;
QVERIFY(m_server->listen(QHostAddress("127.0.0.1")));
m_client = new QTcpSocket(this);
diff --git a/tests/auto/qml/debugger/qqmldebugclient/qqmldebugclient.pro b/tests/auto/qml/debugger/qqmldebugclient/qqmldebugclient.pro
index 622b373692..673330a3cf 100644
--- a/tests/auto/qml/debugger/qqmldebugclient/qqmldebugclient.pro
+++ b/tests/auto/qml/debugger/qqmldebugclient/qqmldebugclient.pro
@@ -7,7 +7,6 @@ HEADERS += ../shared/qqmldebugtestservice.h
SOURCES += tst_qqmldebugclient.cpp \
../shared/qqmldebugtestservice.cpp
-INCLUDEPATH += ../shared
include(../shared/debugutil.pri)
DEFINES += QT_QML_DEBUG_NO_WARNING
diff --git a/tests/auto/qml/debugger/qqmldebugclient/tst_qqmldebugclient.cpp b/tests/auto/qml/debugger/qqmldebugclient/tst_qqmldebugclient.cpp
index 04bc5c3c1a..ffdbf72ded 100644
--- a/tests/auto/qml/debugger/qqmldebugclient/tst_qqmldebugclient.cpp
+++ b/tests/auto/qml/debugger/qqmldebugclient/tst_qqmldebugclient.cpp
@@ -66,17 +66,15 @@ 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()");
foreach (const QString &service, QQmlDebuggingEnabler::debuggerServices())
- QCOMPARE(QQmlDebugConnector::instance()->service(service), (QQmlDebugService *)0);
+ QCOMPARE(QQmlDebugConnector::instance()->service(service), (QQmlDebugService *)nullptr);
foreach (const QString &service, QQmlDebuggingEnabler::inspectorServices())
- QCOMPARE(QQmlDebugConnector::instance()->service(service), (QQmlDebugService *)0);
+ QCOMPARE(QQmlDebugConnector::instance()->service(service), (QQmlDebugService *)nullptr);
foreach (const QString &service, QQmlDebuggingEnabler::profilerServices())
- QCOMPARE(QQmlDebugConnector::instance()->service(service), (QQmlDebugService *)0);
+ QCOMPARE(QQmlDebugConnector::instance()->service(service), (QQmlDebugService *)nullptr);
const QString waitingMsg = QString("QML Debugger: Waiting for connection on port %1...").arg(PORT);
QTest::ignoreMessage(QtDebugMsg, waitingMsg.toLatin1().constData());
@@ -126,7 +124,7 @@ void tst_QQmlDebugClient::state()
QQmlDebugClient client2("tst_QQmlDebugClient::state()", m_conn);
QCOMPARE(client2.state(), QQmlDebugClient::NotConnected);
- QQmlDebugClient client3("tst_QQmlDebugClient::state3()", 0);
+ QQmlDebugClient client3("tst_QQmlDebugClient::state3()", nullptr);
QCOMPARE(client3.state(), QQmlDebugClient::NotConnected);
}
diff --git a/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenabler/qqmldebuggingenabler.pro b/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenabler/qqmldebuggingenabler.pro
index f8014f04f4..bd382ebaab 100644
--- a/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenabler/qqmldebuggingenabler.pro
+++ b/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenabler/qqmldebuggingenabler.pro
@@ -6,8 +6,6 @@ osx:CONFIG -= app_bundle
SOURCES += tst_qqmldebuggingenabler.cpp
-INCLUDEPATH += ../../shared
-include(../../../../shared/util.pri)
include(../../shared/debugutil.pri)
OTHER_FILES += data/test.qml
diff --git a/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenabler/tst_qqmldebuggingenabler.cpp b/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenabler/tst_qqmldebuggingenabler.cpp
index 3aa3a5c87e..37118f4bd0 100644
--- a/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenabler/tst_qqmldebuggingenabler.cpp
+++ b/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenabler/tst_qqmldebuggingenabler.cpp
@@ -27,11 +27,14 @@
****************************************************************************/
#include "debugutil_p.h"
+#include "qqmldebugprocess_p.h"
#include "../../../shared/util.h"
#include <private/qqmldebugclient_p.h>
#include <private/qqmldebugconnection_p.h>
+#include <QtQml/qqmldebug.h>
+
#include <QtTest/qtest.h>
#include <QtCore/qprocess.h>
#include <QtCore/qtimer.h>
@@ -40,17 +43,11 @@
#include <QtCore/qmutex.h>
#include <QtCore/qlibraryinfo.h>
-class tst_QQmlDebuggingEnabler : public QQmlDataTest
+class tst_QQmlDebuggingEnabler : public QQmlDebugTest
{
Q_OBJECT
- bool init(bool blockMode, bool qmlscene, int portFrom, int portTo);
-
private slots:
- void initTestCase();
- void cleanupTestCase();
- void cleanup();
-
void qmlscene_data();
void qmlscene();
void custom_data();
@@ -58,88 +55,8 @@ private slots:
private:
void data();
- QQmlDebugProcess *process;
- QQmlDebugConnection *connection;
- QTime t;
};
-void tst_QQmlDebuggingEnabler::initTestCase()
-{
- QQmlDataTest::initTestCase();
- t.start();
- process = 0;
- connection = 0;
-}
-
-void tst_QQmlDebuggingEnabler::cleanupTestCase()
-{
- if (process) {
- process->stop();
- delete process;
- }
-
- if (connection)
- delete connection;
-}
-
-bool tst_QQmlDebuggingEnabler::init(bool blockMode, bool qmlscene, int portFrom, int portTo)
-{
- connection = new QQmlDebugConnection();
-
- if (qmlscene) {
- process = new QQmlDebugProcess(QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene", this);
- process->setMaximumBindErrors(1);
- } else {
- process = new QQmlDebugProcess(QCoreApplication::applicationDirPath() + QLatin1String("/qqmldebuggingenablerserver"), this);
- process->setMaximumBindErrors(portTo - portFrom);
- }
-
- if (qmlscene) {
- process->start(QStringList() << QLatin1String("-qmljsdebugger=port:") +
- QString::number(portFrom) + QLatin1Char(',') + QString::number(portTo) +
- QLatin1String(blockMode ? ",block": "") <<
- testFile(QLatin1String("test.qml")));
- } else {
- QStringList args;
- if (blockMode)
- args << QLatin1String("-block");
- args << QString::number(portFrom) << QString::number(portTo);
- process->start(args);
- }
-
- if (!process->waitForSessionStart()) {
- return false;
- }
-
- const int port = process->debugPort();
- connection->connectToHost("127.0.0.1", port);
- if (!connection->waitForConnected()) {
- qDebug() << "could not connect to host!";
- return false;
- }
- return true;
-}
-
-void tst_QQmlDebuggingEnabler::cleanup()
-{
- if (QTest::currentTestFailed()) {
- qDebug() << "Process State:" << process->state();
- qDebug() << "Application Output:" << process->output();
- }
-
- if (process) {
- process->stop();
- delete process;
- }
-
-
- if (connection)
- delete connection;
-
- process = 0;
- connection = 0;
-}
-
void tst_QQmlDebuggingEnabler::data()
{
QTest::addColumn<QString>("connector");
@@ -185,32 +102,34 @@ void tst_QQmlDebuggingEnabler::qmlscene()
QFETCH(bool, blockMode);
QFETCH(QStringList, services);
- process = new QQmlDebugProcess(QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene",
- this);
- process->setMaximumBindErrors(1);
- process->start(QStringList()
- << QString::fromLatin1("-qmljsdebugger=connector:%1%2%3%4")
- .arg(connector + (connector == QLatin1String("QQmlDebugServer") ?
- QLatin1String(",port:5555,5565") : QString()))
- .arg(blockMode ? QLatin1String(",block") : QString())
- .arg(services.isEmpty() ? QString() : QString::fromLatin1(",services:"))
- .arg(services.isEmpty() ? QString() : services.join(","))
- << testFile(QLatin1String("test.qml")));
+ m_process = new QQmlDebugProcess(
+ QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene", this);
+ m_process->setMaximumBindErrors(1);
+ m_process->start(QStringList()
+ << QString::fromLatin1("-qmljsdebugger=connector:%1%2%3%4")
+ .arg(connector + (connector == QLatin1String("QQmlDebugServer")
+ ? QLatin1String(",port:5555,5565") : QString()))
+ .arg(blockMode ? QLatin1String(",block") : QString())
+ .arg(services.isEmpty() ? QString() : QString::fromLatin1(",services:"))
+ .arg(services.isEmpty() ? QString() : services.join(","))
+ << testFile(QLatin1String("test.qml")));
if (connector == QLatin1String("QQmlDebugServer")) {
- QVERIFY(process->waitForSessionStart());
- connection = new QQmlDebugConnection();
- QList<QQmlDebugClient *> clients = QQmlDebugTest::createOtherClients(connection);
- connection->connectToHost("127.0.0.1", process->debugPort());
- QVERIFY(connection->waitForConnected());
- foreach (QQmlDebugClient *client, clients)
+ QVERIFY(m_process->waitForSessionStart());
+ m_connection = new QQmlDebugConnection();
+ m_clients = QQmlDebugTest::createOtherClients(m_connection);
+ m_connection->connectToHost("127.0.0.1", m_process->debugPort());
+ QVERIFY(m_connection->waitForConnected());
+ foreach (QQmlDebugClient *client, m_clients)
QCOMPARE(client->state(), (services.isEmpty() || services.contains(client->name())) ?
QQmlDebugClient::Enabled : QQmlDebugClient::Unavailable);
}
- QCOMPARE(process->state(), QLatin1String("running"));
- if (!blockMode)
- QTRY_VERIFY(process->output().contains(QLatin1String("qml: Component.onCompleted")));
+ QCOMPARE(m_process->state(), QProcess::Running);
+ if (!blockMode) {
+ QTRY_VERIFY_WITH_TIMEOUT(m_process->output().contains(
+ QLatin1String("Component.onCompleted")), 15000);
+ }
}
void tst_QQmlDebuggingEnabler::custom_data()
@@ -226,9 +145,9 @@ void tst_QQmlDebuggingEnabler::custom()
const int portFrom = 5555;
const int portTo = 5565;
- process = new QQmlDebugProcess(QCoreApplication::applicationDirPath() +
- QLatin1String("/qqmldebuggingenablerserver"), this);
- process->setMaximumBindErrors(portTo - portFrom);
+ m_process = new QQmlDebugProcess(QCoreApplication::applicationDirPath() +
+ QLatin1String("/qqmldebuggingenablerserver"), this);
+ m_process->setMaximumBindErrors(portTo - portFrom);
QStringList args;
if (blockMode)
@@ -240,22 +159,24 @@ void tst_QQmlDebuggingEnabler::custom()
if (!services.isEmpty())
args << QLatin1String("-services") << services;
- process->start(args);
+ m_process->start(args);
if (connector == QLatin1String("QQmlDebugServer")) {
- QVERIFY(process->waitForSessionStart());
- connection = new QQmlDebugConnection();
- QList<QQmlDebugClient *> clients = QQmlDebugTest::createOtherClients(connection);
- connection->connectToHost("127.0.0.1", process->debugPort());
- QVERIFY(connection->waitForConnected());
- foreach (QQmlDebugClient *client, clients)
+ QVERIFY(m_process->waitForSessionStart());
+ m_connection = new QQmlDebugConnection();
+ m_clients = QQmlDebugTest::createOtherClients(m_connection);
+ m_connection->connectToHost("127.0.0.1", m_process->debugPort());
+ QVERIFY(m_connection->waitForConnected());
+ for (QQmlDebugClient *client : qAsConst(m_clients))
QCOMPARE(client->state(), (services.isEmpty() || services.contains(client->name())) ?
QQmlDebugClient::Enabled : QQmlDebugClient::Unavailable);
}
- QCOMPARE(process->state(), QLatin1String("running"));
- if (!blockMode)
- QTRY_VERIFY(process->output().contains(QLatin1String("QQmlEngine created")));
+ QCOMPARE(m_process->state(), QProcess::Running);
+ if (!blockMode) {
+ QTRY_VERIFY_WITH_TIMEOUT(m_process->output().contains(QLatin1String("QQmlEngine created")),
+ 15000);
+ }
}
QTEST_MAIN(tst_QQmlDebuggingEnabler)
diff --git a/tests/auto/qml/debugger/qqmldebugjs/data/breakOnAnchor.qml b/tests/auto/qml/debugger/qqmldebugjs/data/breakOnAnchor.qml
new file mode 100644
index 0000000000..72a8c9559c
--- /dev/null
+++ b/tests/auto/qml/debugger/qqmldebugjs/data/breakOnAnchor.qml
@@ -0,0 +1,49 @@
+/****************************************************************************
+**
+** 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.11
+
+
+Item {
+ visible: true
+ Text {
+ anchors.centerIn: parent
+ text: "bla"
+ MouseArea {
+ anchors.fill: parent
+ }
+ }
+
+ Timer {
+ interval: 100;
+ running: true;
+ onTriggered: {
+ Qt.quit();
+ }
+ }
+}
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/data/encodeQmlScope.qml b/tests/auto/qml/debugger/qqmldebugjs/data/encodeQmlScope.qml
new file mode 100644
index 0000000000..7ea048044f
--- /dev/null
+++ b/tests/auto/qml/debugger/qqmldebugjs/data/encodeQmlScope.qml
@@ -0,0 +1,19 @@
+import QtQuick 2.0
+
+Item {
+ property int a: 0
+ property int b: 0
+ onAChanged: console.log("inline")
+ onBChanged: {
+ console.log("extra braces");
+ }
+
+ Timer {
+ interval: 10
+ running: true
+ onTriggered: {
+ parent.a += 10;
+ parent.b -= 10;
+ }
+ }
+}
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..acd5546a02 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 += testlib gui-private core-private
+macos:CONFIG -= app_bundle
-qqmldebugjs.depends = qqmldebugjsserver
+SOURCES += tst_qqmldebugjs.cpp
+
+INCLUDEPATH += ../shared
+include(../shared/debugutil.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 \
+ data/breakOnAnchor.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 cbaf3b5309..0000000000
--- a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/qqmldebugjs.pro
+++ /dev/null
@@ -1,25 +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
-
-INCLUDEPATH += ../../shared
-include(../../../../shared/util.pri)
-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
diff --git a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/tst_qqmldebugjs.cpp b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/tst_qqmldebugjs.cpp
deleted file mode 100644
index d248cf9708..0000000000
--- a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/tst_qqmldebugjs.cpp
+++ /dev/null
@@ -1,1552 +0,0 @@
-/****************************************************************************
-**
-** 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 "debugutil_p.h"
-#include "../../shared/qqmlenginedebugclient.h"
-#include "../../../../shared/util.h"
-
-#include <private/qqmldebugclient_p.h>
-#include <private/qqmldebugconnection_p.h>
-#include <private/qpacket_p.h>
-
-#include <QtTest/qtest.h>
-#include <QtCore/qprocess.h>
-#include <QtCore/qtimer.h>
-#include <QtCore/qfileinfo.h>
-#include <QtCore/qdir.h>
-#include <QtCore/qmutex.h>
-#include <QtCore/qlibraryinfo.h>
-#include <QtQml/qjsengine.h>
-
-const char *V8REQUEST = "v8request";
-const char *V8MESSAGE = "v8message";
-const char *SEQ = "seq";
-const char *TYPE = "type";
-const char *COMMAND = "command";
-const char *ARGUMENTS = "arguments";
-const char *STEPACTION = "stepaction";
-const char *STEPCOUNT = "stepcount";
-const char *EXPRESSION = "expression";
-const char *FRAME = "frame";
-const char *CONTEXT = "context";
-const char *GLOBAL = "global";
-const char *DISABLEBREAK = "disable_break";
-const char *HANDLES = "handles";
-const char *INCLUDESOURCE = "includeSource";
-const char *FROMFRAME = "fromFrame";
-const char *TOFRAME = "toFrame";
-const char *BOTTOM = "bottom";
-const char *NUMBER = "number";
-const char *FRAMENUMBER = "frameNumber";
-const char *TYPES = "types";
-const char *IDS = "ids";
-const char *FILTER = "filter";
-const char *FROMLINE = "fromLine";
-const char *TOLINE = "toLine";
-const char *TARGET = "target";
-const char *LINE = "line";
-const char *COLUMN = "column";
-const char *ENABLED = "enabled";
-const char *CONDITION = "condition";
-const char *IGNORECOUNT = "ignoreCount";
-const char *BREAKPOINT = "breakpoint";
-const char *FLAGS = "flags";
-
-const char *CONTINEDEBUGGING = "continue";
-const char *EVALUATE = "evaluate";
-const char *LOOKUP = "lookup";
-const char *BACKTRACE = "backtrace";
-const char *SCOPE = "scope";
-const char *SCOPES = "scopes";
-const char *SCRIPTS = "scripts";
-const char *SOURCE = "source";
-const char *SETBREAKPOINT = "setbreakpoint";
-const char *CLEARBREAKPOINT = "clearbreakpoint";
-const char *SETEXCEPTIONBREAK = "setexceptionbreak";
-const char *VERSION = "version";
-const char *DISCONNECT = "disconnect";
-const char *GARBAGECOLLECTOR = "gc";
-
-const char *CONNECT = "connect";
-const char *INTERRUPT = "interrupt";
-
-const char *REQUEST = "request";
-const char *IN = "in";
-const char *NEXT = "next";
-const char *OUT = "out";
-
-const char *SCRIPT = "script";
-const char *SCRIPTREGEXP = "scriptRegExp";
-const char *EVENT = "event";
-
-const char *ALL = "all";
-const char *UNCAUGHT = "uncaught";
-
-const char *BLOCKMODE = "-qmljsdebugger=port:3771,3800,block";
-const char *NORMALMODE = "-qmljsdebugger=port:3771,3800";
-const char *BLOCKRESTRICTEDMODE = "-qmljsdebugger=port:3771,3800,block,services:V8Debugger";
-const char *NORMALRESTRICTEDMODE = "-qmljsdebugger=port:3771,3800,services:V8Debugger";
-const char *TEST_QMLFILE = "test.qml";
-const char *TEST_JSFILE = "test.js";
-const char *TIMER_QMLFILE = "timer.qml";
-const char *LOADJSFILE_QMLFILE = "loadjsfile.qml";
-const char *EXCEPTION_QMLFILE = "exception.qml";
-const char *ONCOMPLETED_QMLFILE = "oncompleted.qml";
-const char *CREATECOMPONENT_QMLFILE = "createComponent.qml";
-const char *CONDITION_QMLFILE = "condition.qml";
-const char *QUIT_QMLFILE = "quit.qml";
-const char *CHANGEBREAKPOINT_QMLFILE = "changeBreakpoint.qml";
-const char *STEPACTION_QMLFILE = "stepAction.qml";
-const char *BREAKPOINTRELOCATION_QMLFILE = "breakpointRelocation.qml";
-
-#define VARIANTMAPINIT \
- QString obj("{}"); \
- QJSValue jsonVal = parser.call(QJSValueList() << obj); \
- jsonVal.setProperty(SEQ,QJSValue(seq++)); \
- jsonVal.setProperty(TYPE,REQUEST);
-
-
-#undef QVERIFY
-#define QVERIFY(statement) \
-do {\
- if (!QTest::qVerify((statement), #statement, "", __FILE__, __LINE__)) {\
- if (QTest::currentTestFailed()) \
- qDebug().nospace() << "\nDEBUGGEE OUTPUT:\n" << process->output();\
- return;\
- }\
-} while (0)
-
-
-class QJSDebugClient;
-
-class tst_QQmlDebugJS : public QQmlDataTest
-{
- Q_OBJECT
-
- void init(bool qmlscene, const QString &qmlFile = QString(TEST_QMLFILE), bool blockMode = true,
- bool restrictServices = false);
-
-private slots:
- void initTestCase();
- void cleanupTestCase();
-
- void cleanup();
-
- void connect_data();
- void connect();
- void interrupt_data() { targetData(); }
- void interrupt();
- void getVersion_data() { targetData(); }
- void getVersion();
- void getVersionWhenAttaching_data() { targetData(); }
- void getVersionWhenAttaching();
-
- void disconnect_data() { targetData(); }
- void disconnect();
-
- void setBreakpointInScriptOnCompleted_data() { targetData(); }
- void setBreakpointInScriptOnCompleted();
- void setBreakpointInScriptOnComponentCreated_data() { targetData(); }
- void setBreakpointInScriptOnComponentCreated();
- void setBreakpointInScriptOnTimerCallback_data() { targetData(); }
- void setBreakpointInScriptOnTimerCallback();
- void setBreakpointInScriptInDifferentFile_data() { targetData(); }
- void setBreakpointInScriptInDifferentFile();
- void setBreakpointInScriptOnComment_data() { targetData(); }
- void setBreakpointInScriptOnComment();
- void setBreakpointInScriptOnEmptyLine_data() { targetData(); }
- void setBreakpointInScriptOnEmptyLine();
- void setBreakpointInScriptOnOptimizedBinding_data() { targetData(); }
- void setBreakpointInScriptOnOptimizedBinding();
- void setBreakpointInScriptWithCondition_data() { targetData(); }
- void setBreakpointInScriptWithCondition();
- void setBreakpointInScriptThatQuits_data() { targetData(); }
- void setBreakpointInScriptThatQuits();
- void setBreakpointWhenAttaching();
-
- void clearBreakpoint_data() { targetData(); }
- void clearBreakpoint();
-
- void setExceptionBreak_data() { targetData(); }
- void setExceptionBreak();
-
- void stepNext_data() { targetData(); }
- void stepNext();
- void stepIn_data() { targetData(); }
- void stepIn();
- void stepOut_data() { targetData(); }
- void stepOut();
- void continueDebugging_data() { targetData(); }
- void continueDebugging();
-
- void backtrace_data() { targetData(); }
- void backtrace();
-
- void getFrameDetails_data() { targetData(); }
- void getFrameDetails();
-
- void getScopeDetails_data() { targetData(); }
- void getScopeDetails();
-
- void evaluateInGlobalScope();
- void evaluateInLocalScope_data() { targetData(); }
- void evaluateInLocalScope();
-
- void evaluateInContext();
-
- void getScripts_data() { targetData(); }
- void getScripts();
-
-private:
- void targetData();
-
- QQmlDebugProcess *process;
- QJSDebugClient *client;
- QQmlDebugConnection *connection;
- QTime t;
-};
-
-class QJSDebugClient : public QQmlDebugClient
-{
- Q_OBJECT
-public:
- enum StepAction
- {
- Continue,
- In,
- Out,
- Next
- };
-
- enum Exception
- {
- All,
- Uncaught
- };
-
- QJSDebugClient(QQmlDebugConnection *connection)
- : QQmlDebugClient(QLatin1String("V8Debugger"), connection),
- seq(0)
- {
- parser = jsEngine.evaluate(QLatin1String("JSON.parse"));
- stringify = jsEngine.evaluate(QLatin1String("JSON.stringify"));
- }
-
- void connect(bool redundantRefs = false, bool namesAsObjects = false);
- void interrupt();
-
- void continueDebugging(StepAction stepAction);
- void evaluate(QString expr, int frame = -1, int context = -1);
- void lookup(QList<int> handles, bool includeSource = false);
- void backtrace(int fromFrame = -1, int toFrame = -1, bool bottom = false);
- void frame(int number = -1);
- void scope(int number = -1, int frameNumber = -1);
- void scripts(int types = 4, QList<int> ids = QList<int>(), bool includeSource = false, QVariant filter = QVariant());
- void setBreakpoint(QString target, int line = -1, int column = -1, bool enabled = true,
- QString condition = QString(), int ignoreCount = -1);
- void clearBreakpoint(int breakpoint);
- void setExceptionBreak(Exception type, bool enabled = false);
- void version();
- void disconnect();
-
-protected:
- //inherited from QQmlDebugClient
- void stateChanged(State state);
- void messageReceived(const QByteArray &data);
-
-signals:
- void enabled();
- void connected();
- void interruptRequested();
- void result();
- void failure();
- void stopped();
-
-private:
- void sendMessage(const QByteArray &);
- void flushSendBuffer();
- QByteArray packMessage(const QByteArray &type, const QByteArray &message = QByteArray());
-
-private:
- QJSEngine jsEngine;
- int seq;
-
- QList<QByteArray> sendBuffer;
-public:
- QJSValue parser;
- QJSValue stringify;
- QByteArray response;
-
-};
-
-void QJSDebugClient::connect(bool redundantRefs, bool namesAsObjects)
-{
- 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()
-{
- sendMessage(packMessage(INTERRUPT));
-}
-
-void QJSDebugClient::continueDebugging(StepAction action)
-{
- // { "seq" : <number>,
- // "type" : "request",
- // "command" : "continue",
- // "arguments" : { "stepaction" : <"in", "next" or "out">,
- // "stepcount" : <number of steps (default 1)>
- // }
- // }
- VARIANTMAPINIT;
- jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(CONTINEDEBUGGING)));
-
- if (action != Continue) {
- QJSValue args = parser.call(QJSValueList() << obj);
- switch (action) {
- case In: args.setProperty(QLatin1String(STEPACTION),QJSValue(QLatin1String(IN)));
- break;
- case Out: args.setProperty(QLatin1String(STEPACTION),QJSValue(QLatin1String(OUT)));
- break;
- case Next: args.setProperty(QLatin1String(STEPACTION),QJSValue(QLatin1String(NEXT)));
- break;
- default:break;
- }
- if (!args.isUndefined()) {
- jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
- }
- }
- QJSValue json = stringify.call(QJSValueList() << jsonVal);
- sendMessage(packMessage(V8REQUEST, json.toString().toUtf8()));
-}
-
-void QJSDebugClient::evaluate(QString expr, int frame, int context)
-{
- // { "seq" : <number>,
- // "type" : "request",
- // "command" : "evaluate",
- // "arguments" : { "expression" : <expression to evaluate>,
- // "frame" : <number>,
- // "context" : <object ID>
- // }
- // }
- VARIANTMAPINIT;
- jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(EVALUATE)));
-
- QJSValue args = parser.call(QJSValueList() << obj);
- args.setProperty(QLatin1String(EXPRESSION),QJSValue(expr));
-
- if (frame != -1)
- args.setProperty(QLatin1String(FRAME),QJSValue(frame));
-
- if (context != -1)
- args.setProperty(QLatin1String(CONTEXT), QJSValue(context));
-
- if (!args.isUndefined()) {
- jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
- }
-
- QJSValue json = stringify.call(QJSValueList() << jsonVal);
- sendMessage(packMessage(V8REQUEST, json.toString().toUtf8()));
-}
-
-void QJSDebugClient::lookup(QList<int> handles, bool includeSource)
-{
- // { "seq" : <number>,
- // "type" : "request",
- // "command" : "lookup",
- // "arguments" : { "handles" : <array of handles>,
- // "includeSource" : <boolean indicating whether the source will be included when script objects are returned>,
- // }
- // }
- VARIANTMAPINIT;
- jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(LOOKUP)));
-
- QJSValue args = parser.call(QJSValueList() << obj);
-
- QString arr("[]");
- QJSValue array = parser.call(QJSValueList() << arr);
- int index = 0;
- foreach (int handle, handles) {
- array.setProperty(index++,QJSValue(handle));
- }
- args.setProperty(QLatin1String(HANDLES),array);
-
- if (includeSource)
- args.setProperty(QLatin1String(INCLUDESOURCE),QJSValue(includeSource));
-
- if (!args.isUndefined()) {
- jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
- }
-
- QJSValue json = stringify.call(QJSValueList() << jsonVal);
- sendMessage(packMessage(V8REQUEST, json.toString().toUtf8()));
-}
-
-void QJSDebugClient::backtrace(int fromFrame, int toFrame, bool bottom)
-{
- // { "seq" : <number>,
- // "type" : "request",
- // "command" : "backtrace",
- // "arguments" : { "fromFrame" : <number>
- // "toFrame" : <number>
- // "bottom" : <boolean, set to true if the bottom of the stack is requested>
- // }
- // }
- VARIANTMAPINIT;
- jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(BACKTRACE)));
-
- QJSValue args = parser.call(QJSValueList() << obj);
-
- if (fromFrame != -1)
- args.setProperty(QLatin1String(FROMFRAME),QJSValue(fromFrame));
-
- if (toFrame != -1)
- args.setProperty(QLatin1String(TOFRAME),QJSValue(toFrame));
-
- if (bottom)
- args.setProperty(QLatin1String(BOTTOM),QJSValue(bottom));
-
- if (!args.isUndefined()) {
- jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
- }
-
- QJSValue json = stringify.call(QJSValueList() << jsonVal);
- sendMessage(packMessage(V8REQUEST, json.toString().toUtf8()));
-}
-
-void QJSDebugClient::frame(int number)
-{
- // { "seq" : <number>,
- // "type" : "request",
- // "command" : "frame",
- // "arguments" : { "number" : <frame number>
- // }
- // }
- VARIANTMAPINIT;
- jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(FRAME)));
-
- if (number != -1) {
- QJSValue args = parser.call(QJSValueList() << obj);
- args.setProperty(QLatin1String(NUMBER),QJSValue(number));
-
- if (!args.isUndefined()) {
- jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
- }
- }
-
- QJSValue json = stringify.call(QJSValueList() << jsonVal);
- sendMessage(packMessage(V8REQUEST, json.toString().toUtf8()));
-}
-
-void QJSDebugClient::scope(int number, int frameNumber)
-{
- // { "seq" : <number>,
- // "type" : "request",
- // "command" : "scope",
- // "arguments" : { "number" : <scope number>
- // "frameNumber" : <frame number, optional uses selected frame if missing>
- // }
- // }
- VARIANTMAPINIT;
- jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(SCOPE)));
-
- if (number != -1) {
- QJSValue args = parser.call(QJSValueList() << obj);
- args.setProperty(QLatin1String(NUMBER),QJSValue(number));
-
- if (frameNumber != -1)
- args.setProperty(QLatin1String(FRAMENUMBER),QJSValue(frameNumber));
-
- if (!args.isUndefined()) {
- jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
- }
- }
-
- QJSValue json = stringify.call(QJSValueList() << jsonVal);
- sendMessage(packMessage(V8REQUEST, json.toString().toUtf8()));
-}
-
-void QJSDebugClient::scripts(int types, QList<int> ids, bool includeSource, QVariant /*filter*/)
-{
- // { "seq" : <number>,
- // "type" : "request",
- // "command" : "scripts",
- // "arguments" : { "types" : <types of scripts to retrieve
- // set bit 0 for native scripts
- // set bit 1 for extension scripts
- // set bit 2 for normal scripts
- // (default is 4 for normal scripts)>
- // "ids" : <array of id's of scripts to return. If this is not specified all scripts are requrned>
- // "includeSource" : <boolean indicating whether the source code should be included for the scripts returned>
- // "filter" : <string or number: filter string or script id.
- // If a number is specified, then only the script with the same number as its script id will be retrieved.
- // If a string is specified, then only scripts whose names contain the filter string will be retrieved.>
- // }
- // }
- VARIANTMAPINIT;
- jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(SCRIPTS)));
-
- QJSValue args = parser.call(QJSValueList() << obj);
- args.setProperty(QLatin1String(TYPES),QJSValue(types));
-
- if (ids.count()) {
- QString arr("[]");
- QJSValue array = parser.call(QJSValueList() << arr);
- int index = 0;
- foreach (int id, ids) {
- array.setProperty(index++,QJSValue(id));
- }
- args.setProperty(QLatin1String(IDS),array);
- }
-
- if (includeSource)
- args.setProperty(QLatin1String(INCLUDESOURCE),QJSValue(includeSource));
-
- if (!args.isUndefined()) {
- jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
- }
-
- QJSValue json = stringify.call(QJSValueList() << jsonVal);
- sendMessage(packMessage(V8REQUEST, json.toString().toUtf8()));
-}
-
-void QJSDebugClient::setBreakpoint(QString target, int line, int column, bool enabled,
- QString condition, int ignoreCount)
-{
- // { "seq" : <number>,
- // "type" : "request",
- // "command" : "setbreakpoint",
- // "arguments" : { "type" : "scriptRegExp"
- // "target" : <function expression or script identification>
- // "line" : <line in script or function>
- // "column" : <character position within the line>
- // "enabled" : <initial enabled state. True or false, default is true>
- // "condition" : <string with break point condition>
- // "ignoreCount" : <number specifying the number of break point hits to ignore, default value is 0>
- // }
- // }
-
- VARIANTMAPINIT;
- jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(SETBREAKPOINT)));
-
- QJSValue args = parser.call(QJSValueList() << obj);
-
- args.setProperty(QLatin1String(TYPE),QJSValue(QLatin1String(SCRIPTREGEXP)));
- args.setProperty(QLatin1String(TARGET),QJSValue(target));
-
- if (line != -1)
- args.setProperty(QLatin1String(LINE),QJSValue(line));
-
- if (column != -1)
- args.setProperty(QLatin1String(COLUMN),QJSValue(column));
-
- args.setProperty(QLatin1String(ENABLED),QJSValue(enabled));
-
- if (!condition.isEmpty())
- args.setProperty(QLatin1String(CONDITION),QJSValue(condition));
-
- if (ignoreCount != -1)
- args.setProperty(QLatin1String(IGNORECOUNT),QJSValue(ignoreCount));
-
- if (!args.isUndefined()) {
- jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
- }
-
- QJSValue json = stringify.call(QJSValueList() << jsonVal);
- sendMessage(packMessage(V8REQUEST, json.toString().toUtf8()));
-}
-
-void QJSDebugClient::clearBreakpoint(int breakpoint)
-{
- // { "seq" : <number>,
- // "type" : "request",
- // "command" : "clearbreakpoint",
- // "arguments" : { "breakpoint" : <number of the break point to clear>
- // }
- // }
- VARIANTMAPINIT;
- jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(CLEARBREAKPOINT)));
-
- QJSValue args = parser.call(QJSValueList() << obj);
-
- args.setProperty(QLatin1String(BREAKPOINT),QJSValue(breakpoint));
-
- if (!args.isUndefined()) {
- jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
- }
-
- QJSValue json = stringify.call(QJSValueList() << jsonVal);
- sendMessage(packMessage(V8REQUEST, json.toString().toUtf8()));
-}
-
-void QJSDebugClient::setExceptionBreak(Exception type, bool enabled)
-{
- // { "seq" : <number>,
- // "type" : "request",
- // "command" : "setexceptionbreak",
- // "arguments" : { "type" : <string: "all", or "uncaught">,
- // "enabled" : <optional bool: enables the break type if true>
- // }
- // }
- VARIANTMAPINIT;
- jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(SETEXCEPTIONBREAK)));
-
- QJSValue args = parser.call(QJSValueList() << obj);
-
- if (type == All)
- args.setProperty(QLatin1String(TYPE),QJSValue(QLatin1String(ALL)));
- else if (type == Uncaught)
- args.setProperty(QLatin1String(TYPE),QJSValue(QLatin1String(UNCAUGHT)));
-
- if (enabled)
- args.setProperty(QLatin1String(ENABLED),QJSValue(enabled));
-
- if (!args.isUndefined()) {
- jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
- }
-
- QJSValue json = stringify.call(QJSValueList() << jsonVal);
- sendMessage(packMessage(V8REQUEST, json.toString().toUtf8()));
-}
-
-void QJSDebugClient::version()
-{
- // { "seq" : <number>,
- // "type" : "request",
- // "command" : "version",
- // }
- VARIANTMAPINIT;
- jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(VERSION)));
-
- QJSValue json = stringify.call(QJSValueList() << jsonVal);
- sendMessage(packMessage(V8REQUEST, json.toString().toUtf8()));
-}
-
-void QJSDebugClient::disconnect()
-{
- // { "seq" : <number>,
- // "type" : "request",
- // "command" : "disconnect",
- // }
- VARIANTMAPINIT;
- jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(DISCONNECT)));
-
- QJSValue json = stringify.call(QJSValueList() << jsonVal);
- sendMessage(packMessage(DISCONNECT, json.toString().toUtf8()));
-}
-
-void QJSDebugClient::stateChanged(State state)
-{
- if (state == Enabled) {
- flushSendBuffer();
- emit enabled();
- }
-}
-
-void QJSDebugClient::messageReceived(const QByteArray &data)
-{
- QPacket ds(connection()->currentDataStreamVersion(), data);
- QByteArray command;
- ds >> command;
-
- if (command == "V8DEBUG") {
- QByteArray type;
- ds >> type >> response;
-
- if (type == CONNECT) {
- emit connected();
-
- } else if (type == INTERRUPT) {
- emit interruptRequested();
-
- } else if (type == V8MESSAGE) {
- QString jsonString(response);
- QVariantMap value = parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
- QString type = value.value("type").toString();
-
- if (type == "response") {
-
- if (!value.value("success").toBool()) {
- emit failure();
- qDebug() << "Received success == false response from application";
- return;
- }
-
- QString debugCommand(value.value("command").toString());
- if (debugCommand == "backtrace" ||
- debugCommand == "lookup" ||
- debugCommand == "setbreakpoint" ||
- debugCommand == "evaluate" ||
- debugCommand == "version" ||
- debugCommand == "disconnect" ||
- debugCommand == "gc" ||
- debugCommand == "changebreakpoint" ||
- debugCommand == "clearbreakpoint" ||
- debugCommand == "frame" ||
- debugCommand == "scope" ||
- debugCommand == "scopes" ||
- debugCommand == "scripts" ||
- debugCommand == "source" ||
- debugCommand == "setexceptionbreak" /*||
- debugCommand == "profile"*/) {
- emit result();
-
- } else {
- // DO NOTHING
- }
-
- } else if (type == QLatin1String(EVENT)) {
- QString event(value.value(QLatin1String(EVENT)).toString());
-
- if (event == "break" ||
- event == "exception")
- emit stopped();
- }
-
- }
- }
-}
-
-void QJSDebugClient::sendMessage(const QByteArray &msg)
-{
- if (state() == Enabled) {
- QQmlDebugClient::sendMessage(msg);
- } else {
- sendBuffer.append(msg);
- }
-}
-
-void QJSDebugClient::flushSendBuffer()
-{
- foreach (const QByteArray &msg, sendBuffer)
- QQmlDebugClient::sendMessage(msg);
- sendBuffer.clear();
-}
-
-QByteArray QJSDebugClient::packMessage(const QByteArray &type, const QByteArray &message)
-{
- QPacket rs(connection()->currentDataStreamVersion());
- QByteArray cmd = "V8DEBUG";
- rs << cmd << type << message;
- return rs.data();
-}
-
-void tst_QQmlDebugJS::initTestCase()
-{
- QQmlDataTest::initTestCase();
- t.start();
- process = 0;
- client = 0;
- connection = 0;
-}
-
-void tst_QQmlDebugJS::cleanupTestCase()
-{
- if (process) {
- process->stop();
- delete process;
- }
-
- if (client)
- delete client;
-
- if (connection)
- delete connection;
-}
-
-void tst_QQmlDebugJS::init(bool qmlscene, const QString &qmlFile, bool blockMode,
- bool restrictServices)
-{
- connection = new QQmlDebugConnection();
- if (qmlscene)
- process = new QQmlDebugProcess(QLibraryInfo::location(QLibraryInfo::BinariesPath) +
- "/qmlscene", this);
- else
- process = new QQmlDebugProcess(QCoreApplication::applicationDirPath() +
- QLatin1String("/qqmldebugjsserver"), this);
- client = new QJSDebugClient(connection);
- QList<QQmlDebugClient *> others = QQmlDebugTest::createOtherClients(connection);
-
- const char *args = 0;
- if (blockMode)
- args = restrictServices ? BLOCKRESTRICTEDMODE : BLOCKMODE;
- else
- args = restrictServices ? NORMALRESTRICTEDMODE : NORMALMODE;
-
- process->start(QStringList() << QLatin1String(args) << testFile(qmlFile));
-
- QVERIFY(process->waitForSessionStart());
-
- const int port = process->debugPort();
- connection->connectToHost("127.0.0.1", port);
- QVERIFY(connection->waitForConnected());
-
-
- if (client->state() != QQmlDebugClient::Enabled)
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(enabled())));
-
- foreach (QQmlDebugClient *otherClient, others)
- QCOMPARE(otherClient->state(), restrictServices ? QQmlDebugClient::Unavailable :
- QQmlDebugClient::Enabled);
- qDeleteAll(others);
-}
-
-void tst_QQmlDebugJS::cleanup()
-{
- if (QTest::currentTestFailed()) {
- qDebug() << "Process State:" << process->state();
- qDebug() << "Application Output:" << process->output();
- }
-
- if (process) {
- process->stop();
- delete process;
- }
-
- if (client)
- delete client;
-
- if (connection)
- delete connection;
-
- process = 0;
- client = 0;
- connection = 0;
-}
-
-void tst_QQmlDebugJS::connect_data()
-{
- QTest::addColumn<bool>("blockMode");
- QTest::addColumn<bool>("restrictMode");
- QTest::addColumn<bool>("qmlscene");
- QTest::newRow("normal / unrestricted / custom") << false << false << false;
- QTest::newRow("block / unrestricted / custom") << true << false << false;
- QTest::newRow("normal / restricted / custom") << false << true << false;
- QTest::newRow("block / restricted / custom") << true << true << false;
- QTest::newRow("normal / unrestricted / qmlscene") << false << false << true;
- QTest::newRow("block / unrestricted / qmlscene") << true << false << true;
- QTest::newRow("normal / restricted / qmlscene") << false << true << true;
- QTest::newRow("block / restricted / qmlscene") << true << true << true;
-}
-
-void tst_QQmlDebugJS::connect()
-{
- QFETCH(bool, blockMode);
- QFETCH(bool, restrictMode);
- QFETCH(bool, qmlscene);
- init(qmlscene, QString(TEST_QMLFILE), blockMode, restrictMode);
- client->connect();
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(connected())));
-}
-
-void tst_QQmlDebugJS::interrupt()
-{
- //void connect()
-
- QFETCH(bool, qmlscene);
- QFETCH(bool, redundantRefs);
- QFETCH(bool, namesAsObjects);
- init(qmlscene);
- client->connect(redundantRefs, namesAsObjects);
-
- client->interrupt();
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(interruptRequested())));
-}
-
-void tst_QQmlDebugJS::getVersion()
-{
- //void version()
-
- QFETCH(bool, qmlscene);
- QFETCH(bool, redundantRefs);
- QFETCH(bool, namesAsObjects);
- init(qmlscene);
- client->connect(redundantRefs, namesAsObjects);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(connected())));
-
- client->version();
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result())));
-}
-
-void tst_QQmlDebugJS::getVersionWhenAttaching()
-{
- //void version()
- QFETCH(bool, qmlscene);
- QFETCH(bool, redundantRefs);
- QFETCH(bool, namesAsObjects);
-
- init(qmlscene, QLatin1String(TIMER_QMLFILE), false);
- client->connect(redundantRefs, namesAsObjects);
-
- client->version();
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result())));
-}
-
-void tst_QQmlDebugJS::disconnect()
-{
- //void disconnect()
-
- QFETCH(bool, qmlscene);
- QFETCH(bool, redundantRefs);
- QFETCH(bool, namesAsObjects);
- init(qmlscene);
- client->connect(redundantRefs, namesAsObjects);
-
- client->disconnect();
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result())));
-}
-
-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(redundantRefs, namesAsObjects);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
-
- QString jsonString(client->response);
- QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
-
- QVariantMap body = value.value("body").toMap();
-
- QCOMPARE(body.value("sourceLine").toInt(), sourceLine);
- QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(ONCOMPLETED_QMLFILE));
-}
-
-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(redundantRefs, namesAsObjects);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
-
- QString jsonString(client->response);
- QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
-
- QVariantMap body = value.value("body").toMap();
-
- QCOMPARE(body.value("sourceLine").toInt(), sourceLine);
- QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(ONCOMPLETED_QMLFILE));
-}
-
-void tst_QQmlDebugJS::setBreakpointInScriptOnTimerCallback()
-{
- QFETCH(bool, qmlscene);
- QFETCH(bool, redundantRefs);
- QFETCH(bool, namesAsObjects);
- int sourceLine = 35;
- init(qmlscene, TIMER_QMLFILE);
-
- 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);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
-
- QString jsonString(client->response);
- QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
-
- QVariantMap body = value.value("body").toMap();
-
- QCOMPARE(body.value("sourceLine").toInt(), sourceLine);
- QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(TIMER_QMLFILE));
-}
-
-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(redundantRefs, namesAsObjects);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
-
- QString jsonString(client->response);
- QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
-
- QVariantMap body = value.value("body").toMap();
-
- QCOMPARE(body.value("sourceLine").toInt(), sourceLine);
- QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(TEST_JSFILE));
-}
-
-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(redundantRefs, namesAsObjects);
- QEXPECT_FAIL("", "Relocation of breakpoints is disabled right now", Abort);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()), 1));
-
- QString jsonString(client->response);
- QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
-
- QVariantMap body = value.value("body").toMap();
-
- QCOMPARE(body.value("sourceLine").toInt(), actualLine);
- QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(BREAKPOINTRELOCATION_QMLFILE));
-}
-
-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(redundantRefs, namesAsObjects);
- QEXPECT_FAIL("", "Relocation of breakpoints is disabled right now", Abort);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()), 1));
-
- QString jsonString(client->response);
- QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
-
- QVariantMap body = value.value("body").toMap();
-
- QCOMPARE(body.value("sourceLine").toInt(), actualLine);
- QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(BREAKPOINTRELOCATION_QMLFILE));
-}
-
-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(redundantRefs, namesAsObjects);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
-
- QString jsonString(client->response);
- QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
-
- QVariantMap body = value.value("body").toMap();
-
- QCOMPARE(body.value("sourceLine").toInt(), sourceLine);
- QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(BREAKPOINTRELOCATION_QMLFILE));
-}
-
-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(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())));
-
- //Get the frame index
- QString jsonString = client->response;
- QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
-
- {
- QVariantMap body = value.value("body").toMap();
- int frameIndex = body.value("index").toInt();
-
- //Verify the value of 'result'
- client->evaluate(QLatin1String("a"),frameIndex);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result())));
- }
-
- jsonString = client->response;
- QJSValue val = client->parser.call(QJSValueList() << QJSValue(jsonString));
- QVERIFY(val.isObject());
- QJSValue body = val.property(QStringLiteral("body"));
- QVERIFY(body.isObject());
- val = body.property("value");
- QVERIFY(val.isNumber());
-
- const int a = val.toInt();
- QVERIFY(a > out);
-}
-
-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(redundantRefs, namesAsObjects);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
-
- QString jsonString(client->response);
- QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
-
- QVariantMap body = value.value("body").toMap();
-
- QCOMPARE(body.value("sourceLine").toInt(), sourceLine);
- QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(QUIT_QMLFILE));
-
- client->continueDebugging(QJSDebugClient::Continue);
- QVERIFY(process->waitForFinished());
- QCOMPARE(process->exitStatus(), QProcess::NormalExit);
-}
-
-void tst_QQmlDebugJS::setBreakpointWhenAttaching()
-{
- int sourceLine = 35;
- init(true, QLatin1String(TIMER_QMLFILE), false);
-
- client->connect();
-
- QSKIP("\nThe breakpoint may not hit because the engine may run in JIT mode or not have debug\n"
- "instructions, as we've connected in non-blocking mode above. That means we may have\n"
- "connected after the engine was already running, with all the QML already compiled.");
-
- //The breakpoint is in a timer loop so we can set it after connect().
- client->setBreakpoint(QLatin1String(TIMER_QMLFILE), sourceLine);
-
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
-}
-
-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(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)
- client->setBreakpoint(QLatin1String(CHANGEBREAKPOINT_QMLFILE), sourceLine1, -1, true);
- client->setBreakpoint(QLatin1String(CHANGEBREAKPOINT_QMLFILE), sourceLine2, -1, true);
-
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
-
- //Will hit 1st brakpoint, change this breakpoint enable = false
- QString jsonString(client->response);
- QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
-
- QVariantMap body = value.value("body").toMap();
- QList<QVariant> breakpointsHit = body.value("breakpoints").toList();
-
- int breakpoint = breakpointsHit.at(0).toInt();
- client->clearBreakpoint(breakpoint);
-
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result())));
-
- //Continue with debugging
- client->continueDebugging(QJSDebugClient::Continue);
- //Hit 2nd breakpoint
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
-
- //Continue with debugging
- client->continueDebugging(QJSDebugClient::Continue);
- //Should stop at 2nd breakpoint
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
-
- jsonString = client->response;
- value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
-
- body = value.value("body").toMap();
-
- QCOMPARE(body.value("sourceLine").toInt(), sourceLine2);
-}
-
-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(redundantRefs, namesAsObjects);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
-}
-
-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(redundantRefs, namesAsObjects);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
-
- client->continueDebugging(QJSDebugClient::Next);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
-
- QString jsonString(client->response);
- QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
-
- QVariantMap body = value.value("body").toMap();
-
- QCOMPARE(body.value("sourceLine").toInt(), sourceLine + 1);
- QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(STEPACTION_QMLFILE));
-}
-
-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(redundantRefs, namesAsObjects);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
-
- client->continueDebugging(QJSDebugClient::In);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
-
- QString jsonString(client->response);
- QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
-
- QVariantMap body = value.value("body").toMap();
-
- QCOMPARE(body.value("sourceLine").toInt(), actualLine);
- QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(STEPACTION_QMLFILE));
-}
-
-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(redundantRefs, namesAsObjects);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
-
- client->continueDebugging(QJSDebugClient::Out);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
-
- QString jsonString(client->response);
- QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
-
- QVariantMap body = value.value("body").toMap();
-
- QCOMPARE(body.value("sourceLine").toInt(), actualLine);
- QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(STEPACTION_QMLFILE));
-}
-
-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;
- init(qmlscene, STEPACTION_QMLFILE);
-
- client->setBreakpoint(QLatin1String(STEPACTION_QMLFILE), sourceLine1, -1, true);
- client->setBreakpoint(QLatin1String(STEPACTION_QMLFILE), sourceLine2, -1, true);
- client->connect(redundantRefs, namesAsObjects);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
-
- client->continueDebugging(QJSDebugClient::Continue);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
-
- QString jsonString(client->response);
- QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
-
- QVariantMap body = value.value("body").toMap();
-
- QCOMPARE(body.value("sourceLine").toInt(), sourceLine2);
- QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(STEPACTION_QMLFILE));
-}
-
-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(redundantRefs, namesAsObjects);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
-
- client->backtrace();
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result())));
-}
-
-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(redundantRefs, namesAsObjects);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
-
- client->frame();
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result())));
-}
-
-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(redundantRefs, namesAsObjects);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
-
- client->scope();
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result())));
-}
-
-void tst_QQmlDebugJS::evaluateInGlobalScope()
-{
- //void evaluate(QString expr, int frame = -1);
- init(true);
-
- client->connect();
-
- do {
- // The engine might not be initialized, yet. We just try until it shows up.
- client->evaluate(QLatin1String("console.log('Hello World')"));
- } while (!QQmlDebugTest::waitForSignal(client, SIGNAL(result()), 500));
-
- //Verify the return value of 'console.log()', which is "undefined"
- QString jsonString(client->response);
- QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
- QVariantMap body = value.value("body").toMap();
- QCOMPARE(body.value("type").toString(),QLatin1String("undefined"));
-}
-
-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(redundantRefs, namesAsObjects);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
-
- client->frame();
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result())));
-
- //Get the frame index
- QString jsonString(client->response);
- QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
-
- QVariantMap body = value.value("body").toMap();
-
- int frameIndex = body.value("index").toInt();
-
- client->evaluate(QLatin1String("root.a"), frameIndex);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result())));
-
- //Verify the value of 'timer.interval'
- jsonString = client->response;
- value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
-
- body = value.value("body").toMap();
-
- QCOMPARE(body.value("value").toInt(),10);
-}
-
-void tst_QQmlDebugJS::evaluateInContext()
-{
- connection = new QQmlDebugConnection();
- process = new QQmlDebugProcess(QLibraryInfo::location(QLibraryInfo::BinariesPath)
- + "/qmlscene", this);
- client = new QJSDebugClient(connection);
- QScopedPointer<QQmlEngineDebugClient> engineClient(new QQmlEngineDebugClient(connection));
- process->start(QStringList() << QLatin1String(BLOCKMODE) << testFile(ONCOMPLETED_QMLFILE));
-
- QVERIFY(process->waitForSessionStart());
-
- connection->connectToHost("127.0.0.1", process->debugPort());
- QVERIFY(connection->waitForConnected());
-
- QTRY_COMPARE(client->state(), QQmlEngineDebugClient::Enabled);
- QTRY_COMPARE(engineClient->state(), QQmlEngineDebugClient::Enabled);
- client->connect();
-
- // "a" not accessible without extra context
- client->evaluate(QLatin1String("a + 10"), -1, -1);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(failure())));
-
- bool success = false;
- engineClient->queryAvailableEngines(&success);
- QVERIFY(success);
- QVERIFY(QQmlDebugTest::waitForSignal(engineClient.data(), SIGNAL(result())));
-
- QVERIFY(engineClient->engines().count());
- engineClient->queryRootContexts(engineClient->engines()[0].debugId, &success);
- QVERIFY(success);
- QVERIFY(QQmlDebugTest::waitForSignal(engineClient.data(), SIGNAL(result())));
-
- auto contexts = engineClient->rootContext().contexts;
- QCOMPARE(contexts.count(), 1);
- auto objects = contexts[0].objects;
- QCOMPARE(objects.count(), 1);
- engineClient->queryObjectRecursive(objects[0], &success);
- QVERIFY(success);
- QVERIFY(QQmlDebugTest::waitForSignal(engineClient.data(), SIGNAL(result())));
- auto object = engineClient->object();
-
- // "a" accessible in context of surrounding object
- client->evaluate(QLatin1String("a + 10"), -1, object.debugId);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result())));
-
- QString jsonString = client->response;
- QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
-
- QVariantMap body = value.value("body").toMap();
- QTRY_COMPARE(body.value("value").toInt(), 20);
-}
-
-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(redundantRefs, namesAsObjects);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
-
- client->scripts();
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result())));
- QString jsonString(client->response);
- QVariantMap value = client->parser.call(QJSValueList()
- << QJSValue(jsonString)).toVariant().toMap();
-
- QList<QVariant> scripts = value.value("body").toList();
-
- QCOMPARE(scripts.count(), 1);
- QVERIFY(scripts.first().toMap()[QStringLiteral("name")].toString().endsWith(QStringLiteral("data/test.qml")));
-}
-
-void tst_QQmlDebugJS::targetData()
-{
- QTest::addColumn<bool>("qmlscene");
- 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)
-
-#include "tst_qqmldebugjs.moc"
-
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/tst_qqmldebugjs.cpp b/tests/auto/qml/debugger/qqmldebugjs/tst_qqmldebugjs.cpp
new file mode 100644
index 0000000000..1ac28c473b
--- /dev/null
+++ b/tests/auto/qml/debugger/qqmldebugjs/tst_qqmldebugjs.cpp
@@ -0,0 +1,1008 @@
+/****************************************************************************
+**
+** 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 "debugutil_p.h"
+#include "qqmldebugprocess_p.h"
+#include "../../../shared/util.h"
+
+#include <private/qqmlenginedebugclient_p.h>
+#include <private/qv4debugclient_p.h>
+#include <private/qqmldebugconnection_p.h>
+#include <private/qpacket_p.h>
+
+#include <QtTest/qtest.h>
+#include <QtTest/qtestsystem.h>
+#include <QtCore/qprocess.h>
+#include <QtCore/qtimer.h>
+#include <QtCore/qfileinfo.h>
+#include <QtCore/qdir.h>
+#include <QtCore/qmutex.h>
+#include <QtCore/qlibraryinfo.h>
+#include <QtCore/qjsonobject.h>
+#include <QtCore/qjsonarray.h>
+
+const char *BLOCKMODE = "-qmljsdebugger=port:3771,3800,block";
+const char *NORMALMODE = "-qmljsdebugger=port:3771,3800";
+const char *BLOCKRESTRICTEDMODE = "-qmljsdebugger=port:3771,3800,block,services:V8Debugger";
+const char *NORMALRESTRICTEDMODE = "-qmljsdebugger=port:3771,3800,services:V8Debugger";
+const char *TEST_QMLFILE = "test.qml";
+const char *TEST_JSFILE = "test.js";
+const char *TIMER_QMLFILE = "timer.qml";
+const char *LOADJSFILE_QMLFILE = "loadjsfile.qml";
+const char *EXCEPTION_QMLFILE = "exception.qml";
+const char *ONCOMPLETED_QMLFILE = "oncompleted.qml";
+const char *CREATECOMPONENT_QMLFILE = "createComponent.qml";
+const char *CONDITION_QMLFILE = "condition.qml";
+const char *QUIT_QMLFILE = "quit.qml";
+const char *CHANGEBREAKPOINT_QMLFILE = "changeBreakpoint.qml";
+const char *STEPACTION_QMLFILE = "stepAction.qml";
+const char *BREAKPOINTRELOCATION_QMLFILE = "breakpointRelocation.qml";
+const char *ENCODEQMLSCOPE_QMLFILE = "encodeQmlScope.qml";
+const char *BREAKONANCHOR_QMLFILE = "breakOnAnchor.qml";
+
+#undef QVERIFY
+#define QVERIFY(statement) \
+do {\
+ if (!QTest::qVerify((statement), #statement, "", __FILE__, __LINE__)) {\
+ if (QTest::currentTestFailed()) \
+ qDebug().nospace() << "\nDEBUGGEE OUTPUT:\n" << m_process->output();\
+ return;\
+ }\
+} while (0)
+
+class tst_QQmlDebugJS : public QQmlDebugTest
+{
+ Q_OBJECT
+
+private slots:
+ void initTestCase() override;
+
+ void connect_data();
+ void connect();
+ void interrupt_data() { targetData(); }
+ void interrupt();
+ void getVersion_data() { targetData(); }
+ void getVersion();
+ void getVersionWhenAttaching_data() { targetData(); }
+ void getVersionWhenAttaching();
+
+ void disconnect_data() { targetData(); }
+ void disconnect();
+
+ void setBreakpointInScriptOnCompleted_data() { targetData(); }
+ void setBreakpointInScriptOnCompleted();
+ void setBreakpointInScriptOnComponentCreated_data() { targetData(); }
+ void setBreakpointInScriptOnComponentCreated();
+ void setBreakpointInScriptOnTimerCallback_data() { targetData(); }
+ void setBreakpointInScriptOnTimerCallback();
+ void setBreakpointInScriptInDifferentFile_data() { targetData(); }
+ void setBreakpointInScriptInDifferentFile();
+ void setBreakpointInScriptOnComment_data() { targetData(); }
+ void setBreakpointInScriptOnComment();
+ void setBreakpointInScriptOnEmptyLine_data() { targetData(); }
+ void setBreakpointInScriptOnEmptyLine();
+ void setBreakpointInScriptOnOptimizedBinding_data() { targetData(); }
+ void setBreakpointInScriptOnOptimizedBinding();
+ void setBreakpointInScriptWithCondition_data() { targetData(); }
+ void setBreakpointInScriptWithCondition();
+ void setBreakpointInScriptThatQuits_data() { targetData(); }
+ void setBreakpointInScriptThatQuits();
+ void setBreakpointWhenAttaching();
+
+ void clearBreakpoint_data() { targetData(); }
+ void clearBreakpoint();
+
+ void changeBreakpoint_data() { targetData(); }
+ void changeBreakpoint();
+
+ void setExceptionBreak_data() { targetData(); }
+ void setExceptionBreak();
+
+ void stepNext_data() { targetData(); }
+ void stepNext();
+ void stepIn_data() { targetData(); }
+ void stepIn();
+ void stepOut_data() { targetData(); }
+ void stepOut();
+ void continueDebugging_data() { targetData(); }
+ void continueDebugging();
+
+ void backtrace_data() { targetData(); }
+ void backtrace();
+
+ void getFrameDetails_data() { targetData(); }
+ void getFrameDetails();
+
+ void getScopeDetails_data() { targetData(); }
+ void getScopeDetails();
+
+ void evaluateInGlobalScope();
+ void evaluateInLocalScope_data() { targetData(); }
+ void evaluateInLocalScope();
+
+ void evaluateInContext();
+
+ void getScripts_data() { targetData(); }
+ void getScripts();
+
+ void encodeQmlScope();
+ void breakOnAnchor();
+
+private:
+ ConnectResult init(bool qmlscene, const QString &qmlFile = QString(TEST_QMLFILE),
+ bool blockMode = true, bool restrictServices = false);
+ QList<QQmlDebugClient *> createClients() override;
+ QPointer<QV4DebugClient> m_client;
+
+ void targetData();
+ bool waitForClientSignal(const char *signal, int timeout = 30000);
+ void checkVersionParameters();
+
+ QTime t;
+};
+
+
+
+void tst_QQmlDebugJS::initTestCase()
+{
+ QQmlDebugTest::initTestCase();
+ t.start();
+}
+
+QQmlDebugTest::ConnectResult tst_QQmlDebugJS::init(bool qmlscene, const QString &qmlFile,
+ bool blockMode, bool restrictServices)
+{
+ const QString executable = qmlscene
+ ? QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene"
+ : debugJsServerPath("qqmldebugjs");
+ return QQmlDebugTest::connect(
+ executable, restrictServices ? QStringLiteral("V8Debugger") : QString(),
+ testFile(qmlFile), blockMode);
+}
+
+void tst_QQmlDebugJS::connect_data()
+{
+ QTest::addColumn<bool>("blockMode");
+ QTest::addColumn<bool>("restrictMode");
+ QTest::addColumn<bool>("qmlscene");
+ QTest::newRow("normal / unrestricted / custom") << false << false << false;
+ QTest::newRow("block / unrestricted / custom") << true << false << false;
+ QTest::newRow("normal / restricted / custom") << false << true << false;
+ QTest::newRow("block / restricted / custom") << true << true << false;
+ QTest::newRow("normal / unrestricted / qmlscene") << false << false << true;
+ QTest::newRow("block / unrestricted / qmlscene") << true << false << true;
+ QTest::newRow("normal / restricted / qmlscene") << false << true << true;
+ QTest::newRow("block / restricted / qmlscene") << true << true << true;
+}
+
+void tst_QQmlDebugJS::connect()
+{
+ QFETCH(bool, blockMode);
+ QFETCH(bool, restrictMode);
+ QFETCH(bool, qmlscene);
+
+ QCOMPARE(init(qmlscene, QString(TEST_QMLFILE), blockMode, restrictMode), ConnectSuccess);
+ m_client->connect();
+ QVERIFY(waitForClientSignal(SIGNAL(connected())));
+}
+
+void tst_QQmlDebugJS::interrupt()
+{
+ //void connect()
+ QFETCH(bool, qmlscene);
+
+ QCOMPARE(init(qmlscene), ConnectSuccess);
+ m_client->connect();
+
+ m_client->interrupt();
+ QVERIFY(waitForClientSignal(SIGNAL(interrupted())));
+}
+
+void tst_QQmlDebugJS::getVersion()
+{
+ //void version()
+ QFETCH(bool, qmlscene);
+
+ QCOMPARE(init(qmlscene), ConnectSuccess);
+ m_client->connect();
+ QVERIFY(waitForClientSignal(SIGNAL(connected())));
+
+ m_client->version();
+ QVERIFY(waitForClientSignal(SIGNAL(result())));
+ checkVersionParameters();
+}
+
+void tst_QQmlDebugJS::getVersionWhenAttaching()
+{
+ //void version()
+ QFETCH(bool, qmlscene);
+
+ QCOMPARE(init(qmlscene, QLatin1String(TIMER_QMLFILE), false), ConnectSuccess);
+ m_client->connect();
+
+ m_client->version();
+ QVERIFY(waitForClientSignal(SIGNAL(result())));
+ checkVersionParameters();
+}
+
+void tst_QQmlDebugJS::disconnect()
+{
+ //void disconnect()
+ QFETCH(bool, qmlscene);
+
+ QCOMPARE(init(qmlscene), ConnectSuccess);
+ m_client->connect();
+
+ m_client->disconnect();
+ QVERIFY(waitForClientSignal(SIGNAL(result())));
+}
+
+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);
+
+ int sourceLine = 34;
+ QCOMPARE(init(qmlscene, ONCOMPLETED_QMLFILE), ConnectSuccess);
+
+ m_client->setBreakpoint(QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true);
+ m_client->connect();
+ QVERIFY(waitForClientSignal(SIGNAL(stopped())));
+
+ const QJsonObject body = m_client->response().body.toObject();
+
+ QCOMPARE(body.value("sourceLine").toInt(), sourceLine);
+ QCOMPARE(QFileInfo(body.value("script").toObject().value("name").toString()).fileName(),
+ QLatin1String(ONCOMPLETED_QMLFILE));
+}
+
+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);
+
+ int sourceLine = 34;
+ QCOMPARE(init(qmlscene, CREATECOMPONENT_QMLFILE), ConnectSuccess);
+
+ m_client->setBreakpoint(QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true);
+ m_client->connect();
+ QVERIFY(waitForClientSignal(SIGNAL(stopped())));
+
+ const QJsonObject body = m_client->response().body.toObject();
+
+ QCOMPARE(body.value("sourceLine").toInt(), sourceLine);
+ QCOMPARE(QFileInfo(body.value("script").toObject().value("name").toString()).fileName(),
+ QLatin1String(ONCOMPLETED_QMLFILE));
+}
+
+void tst_QQmlDebugJS::setBreakpointInScriptOnTimerCallback()
+{
+ QFETCH(bool, qmlscene);
+
+ int sourceLine = 35;
+ QCOMPARE(init(qmlscene, TIMER_QMLFILE), ConnectSuccess);
+
+ m_client->connect();
+ //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.
+ m_client->setBreakpoint(QLatin1String(TIMER_QMLFILE), sourceLine, -1, true);
+ QVERIFY(waitForClientSignal(SIGNAL(stopped())));
+
+ const QJsonObject body = m_client->response().body.toObject();
+
+ QCOMPARE(body.value("sourceLine").toInt(), sourceLine);
+ QCOMPARE(QFileInfo(body.value("script").toObject().value("name").toString()).fileName(),
+ QLatin1String(TIMER_QMLFILE));
+}
+
+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);
+
+ int sourceLine = 31;
+ QCOMPARE(init(qmlscene, LOADJSFILE_QMLFILE), ConnectSuccess);
+
+ m_client->setBreakpoint(QLatin1String(TEST_JSFILE), sourceLine, -1, true);
+ m_client->connect();
+ QVERIFY(waitForClientSignal(SIGNAL(stopped())));
+
+ const QJsonObject body = m_client->response().body.toObject();
+
+ QCOMPARE(body.value("sourceLine").toInt(), sourceLine);
+ QCOMPARE(QFileInfo(body.value("script").toObject().value("name").toString()).fileName(),
+ QLatin1String(TEST_JSFILE));
+}
+
+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);
+
+ int sourceLine = 34;
+ int actualLine = 36;
+ QCOMPARE(init(qmlscene, BREAKPOINTRELOCATION_QMLFILE), ConnectSuccess);
+
+ m_client->setBreakpoint(QLatin1String(BREAKPOINTRELOCATION_QMLFILE), sourceLine, -1, true);
+ m_client->connect();
+ QEXPECT_FAIL("", "Relocation of breakpoints is disabled right now", Abort);
+ QVERIFY(waitForClientSignal(SIGNAL(stopped()), 1));
+
+ const QJsonObject body = m_client->response().body.toObject();
+
+ QCOMPARE(body.value("sourceLine").toInt(), actualLine);
+ QCOMPARE(QFileInfo(body.value("script").toObject().value("name").toString()).fileName(),
+ QLatin1String(BREAKPOINTRELOCATION_QMLFILE));
+}
+
+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);
+
+ int sourceLine = 35;
+ int actualLine = 36;
+ QCOMPARE(init(qmlscene, BREAKPOINTRELOCATION_QMLFILE), ConnectSuccess);
+
+ m_client->setBreakpoint(QLatin1String(BREAKPOINTRELOCATION_QMLFILE), sourceLine, -1, true);
+ m_client->connect();
+ QEXPECT_FAIL("", "Relocation of breakpoints is disabled right now", Abort);
+ QVERIFY(waitForClientSignal(SIGNAL(stopped()), 1));
+
+ const QJsonObject body = m_client->response().body.toObject();
+
+ QCOMPARE(body.value("sourceLine").toInt(), actualLine);
+ QCOMPARE(QFileInfo(body.value("script").toObject().value("name").toString()).fileName(),
+ QLatin1String(BREAKPOINTRELOCATION_QMLFILE));
+}
+
+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);
+
+ int sourceLine = 39;
+ QCOMPARE(init(qmlscene, BREAKPOINTRELOCATION_QMLFILE), ConnectSuccess);
+
+ m_client->setBreakpoint(QLatin1String(BREAKPOINTRELOCATION_QMLFILE), sourceLine, -1, true);
+ m_client->connect();
+ QVERIFY(waitForClientSignal(SIGNAL(stopped())));
+
+ const QJsonObject body = m_client->response().body.toObject();
+
+ QCOMPARE(body.value("sourceLine").toInt(), sourceLine);
+ QCOMPARE(QFileInfo(body.value("script").toObject().value("name").toString()).fileName(),
+ QLatin1String(BREAKPOINTRELOCATION_QMLFILE));
+}
+
+void tst_QQmlDebugJS::setBreakpointInScriptWithCondition()
+{
+ QFETCH(bool, qmlscene);
+
+ int out = 10;
+ int sourceLine = 37;
+ QCOMPARE(init(qmlscene, CONDITION_QMLFILE), ConnectSuccess);
+
+ m_client->connect();
+ //The breakpoint is in a timer loop so we can set it after connect().
+ m_client->setBreakpoint(QLatin1String(CONDITION_QMLFILE), sourceLine, 1, true, QLatin1String("a > 10"));
+ QVERIFY(waitForClientSignal(SIGNAL(stopped())));
+
+ //Get the frame index
+ {
+ const QJsonObject body = m_client->response().body.toObject();
+ int frameIndex = body.value("index").toInt();
+
+ //Verify the value of 'result'
+ m_client->evaluate(QLatin1String("a"),frameIndex);
+ QVERIFY(waitForClientSignal(SIGNAL(result())));
+ }
+
+ const QJsonObject body = m_client->response().body.toObject();
+ QVERIFY(!body.isEmpty());
+ QJsonValue val = body.value("value");
+ QVERIFY(val.isDouble());
+
+ const int a = val.toInt();
+ QVERIFY(a > out);
+}
+
+void tst_QQmlDebugJS::setBreakpointInScriptThatQuits()
+{
+ QFETCH(bool, qmlscene);
+
+ QCOMPARE(init(qmlscene, QUIT_QMLFILE), ConnectSuccess);
+
+ int sourceLine = 36;
+
+ m_client->setBreakpoint(QLatin1String(QUIT_QMLFILE), sourceLine, -1, true);
+ m_client->connect();
+ QVERIFY(waitForClientSignal(SIGNAL(stopped())));
+
+ const QJsonObject body = m_client->response().body.toObject();
+
+ QCOMPARE(body.value("sourceLine").toInt(), sourceLine);
+ QCOMPARE(QFileInfo(body.value("script").toObject().value("name").toString()).fileName(), QLatin1String(QUIT_QMLFILE));
+
+ m_client->continueDebugging(QV4DebugClient::Continue);
+ QVERIFY(m_process->waitForFinished());
+ QCOMPARE(m_process->exitStatus(), QProcess::NormalExit);
+}
+
+void tst_QQmlDebugJS::setBreakpointWhenAttaching()
+{
+ int sourceLine = 35;
+ QCOMPARE(init(true, QLatin1String(TIMER_QMLFILE), false), ConnectSuccess);
+
+ m_client->connect();
+
+ QSKIP("\nThe breakpoint may not hit because the engine may run in JIT mode or not have debug\n"
+ "instructions, as we've connected in non-blocking mode above. That means we may have\n"
+ "connected after the engine was already running, with all the QML already compiled.");
+
+ //The breakpoint is in a timer loop so we can set it after connect().
+ m_client->setBreakpoint(QLatin1String(TIMER_QMLFILE), sourceLine);
+
+ QVERIFY(waitForClientSignal(SIGNAL(stopped())));
+}
+
+void tst_QQmlDebugJS::clearBreakpoint()
+{
+ //void clearBreakpoint(int breakpoint);
+ QFETCH(bool, qmlscene);
+
+ int sourceLine1 = 37;
+ int sourceLine2 = 38;
+ QCOMPARE(init(qmlscene, CHANGEBREAKPOINT_QMLFILE), ConnectSuccess);
+
+ m_client->connect();
+ //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)
+ m_client->setBreakpoint(QLatin1String(CHANGEBREAKPOINT_QMLFILE), sourceLine1, -1, true);
+ m_client->setBreakpoint(QLatin1String(CHANGEBREAKPOINT_QMLFILE), sourceLine2, -1, true);
+
+ QVERIFY(waitForClientSignal(SIGNAL(stopped())));
+
+ {
+ //Will hit 1st brakpoint, change this breakpoint enable = false
+ const QJsonObject body = m_client->response().body.toObject();
+ const QJsonArray breakpointsHit = body.value("breakpoints").toArray();
+
+ int breakpoint = breakpointsHit.at(0).toInt();
+ m_client->clearBreakpoint(breakpoint);
+
+ QVERIFY(waitForClientSignal(SIGNAL(result())));
+
+ //Continue with debugging
+ m_client->continueDebugging(QV4DebugClient::Continue);
+ //Hit 2nd breakpoint
+ QVERIFY(waitForClientSignal(SIGNAL(stopped())));
+
+ //Continue with debugging
+ m_client->continueDebugging(QV4DebugClient::Continue);
+ }
+
+ //Should stop at 2nd breakpoint
+ QVERIFY(waitForClientSignal(SIGNAL(stopped())));
+
+ {
+ const QJsonObject body = m_client->response().body.toObject();
+ QCOMPARE(body.value("sourceLine").toInt(), sourceLine2);
+ }
+}
+
+void tst_QQmlDebugJS::changeBreakpoint()
+{
+ //void clearBreakpoint(int breakpoint);
+ QFETCH(bool, qmlscene);
+
+ int sourceLine2 = 37;
+ int sourceLine1 = 38;
+ QCOMPARE(init(qmlscene, CHANGEBREAKPOINT_QMLFILE), ConnectSuccess);
+
+ bool isStopped = false;
+ QObject::connect(m_client.data(), &QV4DebugClient::stopped, this, [&]() { isStopped = true; });
+
+ auto continueDebugging = [&]() {
+ m_client->continueDebugging(QV4DebugClient::Continue);
+ isStopped = false;
+ };
+
+ m_client->connect();
+
+ auto extractBody = [&]() {
+ return m_client->response().body.toObject();
+ };
+
+ auto extractBreakPointId = [&](const QJsonObject &body) {
+ const QJsonArray breakpointsHit = body.value("breakpoints").toArray();
+ if (breakpointsHit.size() != 1)
+ return -1;
+ return breakpointsHit[0].toInt();
+ };
+
+ auto setBreakPoint = [&](int sourceLine, bool enabled) {
+ int id = -1;
+ auto connection = QObject::connect(m_client.data(), &QV4DebugClient::result, [&]() {
+ id = extractBody().value("breakpoint").toInt();
+ });
+
+ m_client->setBreakpoint(QLatin1String(CHANGEBREAKPOINT_QMLFILE), sourceLine, -1, enabled);
+ bool success = QTest::qWaitFor([&]() { return id >= 0; });
+ Q_UNUSED(success);
+
+ QObject::disconnect(connection);
+ return id;
+ };
+
+ //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)
+ const int breakpoint1 = setBreakPoint(sourceLine1, false);
+ QVERIFY(breakpoint1 >= 0);
+
+ const int breakpoint2 = setBreakPoint(sourceLine2, true);
+ QVERIFY(breakpoint2 >= 0);
+
+ auto verifyBreakpoint = [&](int sourceLine, int breakpointId) {
+ QTRY_VERIFY_WITH_TIMEOUT(isStopped, 30000);
+ const QJsonObject body = extractBody();
+ QCOMPARE(body.value("sourceLine").toInt(), sourceLine);
+ QCOMPARE(extractBreakPointId(body), breakpointId);
+ };
+
+ verifyBreakpoint(sourceLine2, breakpoint2);
+
+ continueDebugging();
+ verifyBreakpoint(sourceLine2, breakpoint2);
+
+ m_client->changeBreakpoint(breakpoint2, false);
+ QVERIFY(waitForClientSignal(SIGNAL(result())));
+
+ m_client->changeBreakpoint(breakpoint1, true);
+ QVERIFY(waitForClientSignal(SIGNAL(result())));
+
+ continueDebugging();
+ verifyBreakpoint(sourceLine1, breakpoint1);
+
+ continueDebugging();
+ verifyBreakpoint(sourceLine1, breakpoint1);
+
+ m_client->changeBreakpoint(breakpoint2, true);
+ QVERIFY(waitForClientSignal(SIGNAL(result())));
+
+ m_client->changeBreakpoint(breakpoint1, false);
+ QVERIFY(waitForClientSignal(SIGNAL(result())));
+
+ for (int i = 0; i < 3; ++i) {
+ continueDebugging();
+ verifyBreakpoint(sourceLine2, breakpoint2);
+ }
+}
+
+void tst_QQmlDebugJS::setExceptionBreak()
+{
+ //void setExceptionBreak(QString type, bool enabled = false);
+ QFETCH(bool, qmlscene);
+
+ QCOMPARE(init(qmlscene, EXCEPTION_QMLFILE), ConnectSuccess);
+ m_client->setExceptionBreak(QV4DebugClient::All,true);
+ m_client->connect();
+ QVERIFY(waitForClientSignal(SIGNAL(stopped())));
+}
+
+void tst_QQmlDebugJS::stepNext()
+{
+ //void continueDebugging(StepAction stepAction, int stepCount = 1);
+ QFETCH(bool, qmlscene);
+
+ int sourceLine = 37;
+ QCOMPARE(init(qmlscene, STEPACTION_QMLFILE), ConnectSuccess);
+
+ m_client->setBreakpoint(QLatin1String(STEPACTION_QMLFILE), sourceLine, -1, true);
+ m_client->connect();
+ QVERIFY(waitForClientSignal(SIGNAL(stopped())));
+
+ m_client->continueDebugging(QV4DebugClient::Next);
+ QVERIFY(waitForClientSignal(SIGNAL(stopped())));
+
+ const QJsonObject body = m_client->response().body.toObject();
+
+ QCOMPARE(body.value("sourceLine").toInt(), sourceLine + 1);
+ QCOMPARE(QFileInfo(body.value("script").toObject().value("name").toString()).fileName(),
+ QLatin1String(STEPACTION_QMLFILE));
+}
+
+static QJsonObject responseBody(QV4DebugClient *client)
+{
+ return client->response().body.toObject();
+}
+
+void tst_QQmlDebugJS::stepIn()
+{
+ //void continueDebugging(StepAction stepAction, int stepCount = 1);
+ QFETCH(bool, qmlscene);
+
+ int sourceLine = 41;
+ int actualLine = 36;
+ QCOMPARE(init(qmlscene, STEPACTION_QMLFILE), ConnectSuccess);
+
+ m_client->setBreakpoint(QLatin1String(STEPACTION_QMLFILE), sourceLine, 1, true);
+ m_client->connect();
+ QVERIFY(waitForClientSignal(SIGNAL(stopped())));
+ QCOMPARE(responseBody(m_client).value("sourceLine").toInt(), sourceLine);
+
+ m_client->continueDebugging(QV4DebugClient::In);
+ QVERIFY(waitForClientSignal(SIGNAL(stopped())));
+
+ const QJsonObject body = responseBody(m_client);
+ QCOMPARE(body.value("sourceLine").toInt(), actualLine);
+ QCOMPARE(QFileInfo(body.value("script").toObject().value("name").toString()).fileName(), QLatin1String(STEPACTION_QMLFILE));
+}
+
+void tst_QQmlDebugJS::stepOut()
+{
+ //void continueDebugging(StepAction stepAction, int stepCount = 1);
+ QFETCH(bool, qmlscene);
+
+ int sourceLine = 37;
+ int actualLine = 41;
+ QCOMPARE(init(qmlscene, STEPACTION_QMLFILE), ConnectSuccess);
+
+ m_client->setBreakpoint(QLatin1String(STEPACTION_QMLFILE), sourceLine, -1, true);
+ m_client->connect();
+ QVERIFY(waitForClientSignal(SIGNAL(stopped())));
+ QCOMPARE(responseBody(m_client).value("sourceLine").toInt(), sourceLine);
+
+ m_client->continueDebugging(QV4DebugClient::Out);
+ QVERIFY(waitForClientSignal(SIGNAL(stopped())));
+
+ const QJsonObject body = responseBody(m_client);
+ QCOMPARE(body.value("sourceLine").toInt(), actualLine);
+ QCOMPARE(QFileInfo(body.value("script").toObject().value("name").toString()).fileName(), QLatin1String(STEPACTION_QMLFILE));
+}
+
+void tst_QQmlDebugJS::continueDebugging()
+{
+ //void continueDebugging(StepAction stepAction, int stepCount = 1);
+ QFETCH(bool, qmlscene);
+
+ int sourceLine1 = 41;
+ int sourceLine2 = 38;
+ QCOMPARE(init(qmlscene, STEPACTION_QMLFILE), ConnectSuccess);
+
+ m_client->setBreakpoint(QLatin1String(STEPACTION_QMLFILE), sourceLine1, -1, true);
+ m_client->setBreakpoint(QLatin1String(STEPACTION_QMLFILE), sourceLine2, -1, true);
+ m_client->connect();
+ QVERIFY(waitForClientSignal(SIGNAL(stopped())));
+
+ m_client->continueDebugging(QV4DebugClient::Continue);
+ QVERIFY(waitForClientSignal(SIGNAL(stopped())));
+
+ const QJsonObject body = responseBody(m_client);
+
+ QCOMPARE(body.value("sourceLine").toInt(), sourceLine2);
+ QCOMPARE(QFileInfo(body.value("script").toObject().value("name").toString()).fileName(),
+ QLatin1String(STEPACTION_QMLFILE));
+}
+
+void tst_QQmlDebugJS::backtrace()
+{
+ //void backtrace(int fromFrame = -1, int toFrame = -1, bool bottom = false);
+ QFETCH(bool, qmlscene);
+
+ int sourceLine = 34;
+ QCOMPARE(init(qmlscene, ONCOMPLETED_QMLFILE), ConnectSuccess);
+
+ m_client->setBreakpoint(QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true);
+ m_client->connect();
+ QVERIFY(waitForClientSignal(SIGNAL(stopped())));
+
+ m_client->backtrace();
+ QVERIFY(waitForClientSignal(SIGNAL(result())));
+}
+
+void tst_QQmlDebugJS::getFrameDetails()
+{
+ //void frame(int number = -1);
+ QFETCH(bool, qmlscene);
+
+ int sourceLine = 34;
+ QCOMPARE(init(qmlscene, ONCOMPLETED_QMLFILE), ConnectSuccess);
+
+ m_client->setBreakpoint(QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true);
+ m_client->connect();
+ QVERIFY(waitForClientSignal(SIGNAL(stopped())));
+
+ m_client->frame();
+ QVERIFY(waitForClientSignal(SIGNAL(result())));
+}
+
+void tst_QQmlDebugJS::getScopeDetails()
+{
+ //void scope(int number = -1, int frameNumber = -1);
+ QFETCH(bool, qmlscene);
+
+ int sourceLine = 34;
+ QCOMPARE(init(qmlscene, ONCOMPLETED_QMLFILE), ConnectSuccess);
+
+ m_client->setBreakpoint(QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true);
+ m_client->connect();
+ QVERIFY(waitForClientSignal(SIGNAL(stopped())));
+
+ m_client->scope();
+ QVERIFY(waitForClientSignal(SIGNAL(result())));
+}
+
+void tst_QQmlDebugJS::evaluateInGlobalScope()
+{
+ //void evaluate(QString expr, int frame = -1);
+ QCOMPARE(init(true), ConnectSuccess);
+
+ m_client->connect();
+
+ for (int i = 0; i < 10; ++i) {
+ // The engine might not be initialized, yet. We just try until it shows up.
+ m_client->evaluate(QLatin1String("console.log('Hello World')"));
+ if (waitForClientSignal(SIGNAL(result()), 500))
+ break;
+ }
+
+ //Verify the return value of 'console.log()', which is "undefined"
+ QCOMPARE(responseBody(m_client).value("type").toString(), QLatin1String("undefined"));
+}
+
+void tst_QQmlDebugJS::evaluateInLocalScope()
+{
+ //void evaluate(QString expr, bool global = false, bool disableBreak = false, int frame = -1, const QVariantMap &addContext = QVariantMap());
+ QFETCH(bool, qmlscene);
+
+ int sourceLine = 34;
+ QCOMPARE(init(qmlscene, ONCOMPLETED_QMLFILE), ConnectSuccess);
+
+ m_client->setBreakpoint(QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true);
+ m_client->connect();
+ QVERIFY(waitForClientSignal(SIGNAL(stopped())));
+
+ m_client->frame();
+ QVERIFY(waitForClientSignal(SIGNAL(result())));
+
+ {
+ //Get the frame index
+ const QJsonObject body = responseBody(m_client);
+ int frameIndex = body.value("index").toInt();
+ m_client->evaluate(QLatin1String("root.a"), frameIndex);
+ QVERIFY(waitForClientSignal(SIGNAL(result())));
+ }
+
+ {
+ //Verify the value of 'timer.interval'
+ const QJsonObject body = responseBody(m_client);
+ QCOMPARE(body.value("value").toInt(),10);
+ }
+}
+
+void tst_QQmlDebugJS::evaluateInContext()
+{
+ m_connection = new QQmlDebugConnection();
+ m_process = new QQmlDebugProcess(
+ QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene", this);
+ m_client = new QV4DebugClient(m_connection);
+ QScopedPointer<QQmlEngineDebugClient> engineClient(new QQmlEngineDebugClient(m_connection));
+ m_process->start(QStringList() << QLatin1String(BLOCKMODE) << testFile(ONCOMPLETED_QMLFILE));
+
+ QVERIFY(m_process->waitForSessionStart());
+
+ m_connection->connectToHost("127.0.0.1", m_process->debugPort());
+ QVERIFY(m_connection->waitForConnected());
+
+ QTRY_COMPARE(m_client->state(), QQmlEngineDebugClient::Enabled);
+ QTRY_COMPARE(engineClient->state(), QQmlEngineDebugClient::Enabled);
+ m_client->connect();
+
+ // "a" not accessible without extra context
+ m_client->evaluate(QLatin1String("a + 10"), -1, -1);
+ QVERIFY(waitForClientSignal(SIGNAL(failure())));
+
+ bool success = false;
+ engineClient->queryAvailableEngines(&success);
+ QVERIFY(success);
+ QVERIFY(QQmlDebugTest::waitForSignal(engineClient.data(), SIGNAL(result())));
+
+ QVERIFY(engineClient->engines().count());
+ engineClient->queryRootContexts(engineClient->engines()[0], &success);
+ QVERIFY(success);
+ QVERIFY(QQmlDebugTest::waitForSignal(engineClient.data(), SIGNAL(result())));
+
+ auto contexts = engineClient->rootContext().contexts;
+ QCOMPARE(contexts.count(), 1);
+ auto objects = contexts[0].objects;
+ QCOMPARE(objects.count(), 1);
+ engineClient->queryObjectRecursive(objects[0], &success);
+ QVERIFY(success);
+ QVERIFY(QQmlDebugTest::waitForSignal(engineClient.data(), SIGNAL(result())));
+ auto object = engineClient->object();
+
+ // "a" accessible in context of surrounding object
+ m_client->evaluate(QLatin1String("a + 10"), -1, object.debugId);
+ QVERIFY(waitForClientSignal(SIGNAL(result())));
+
+ QTRY_COMPARE(responseBody(m_client).value("value").toInt(), 20);
+}
+
+void tst_QQmlDebugJS::getScripts()
+{
+ //void scripts(int types = -1, QList<int> ids = QList<int>(), bool includeSource = false, QVariant filter = QVariant());
+ QFETCH(bool, qmlscene);
+
+ QCOMPARE(init(qmlscene), ConnectSuccess);
+
+ m_client->setBreakpoint(QString(TEST_QMLFILE), 35, -1, true);
+ m_client->connect();
+ QVERIFY(waitForClientSignal(SIGNAL(stopped())));
+
+ m_client->scripts();
+ QVERIFY(waitForClientSignal(SIGNAL(result())));
+
+ const QJsonArray scripts = m_client->response().body.toArray();
+
+ QCOMPARE(scripts.count(), 1);
+ QVERIFY(scripts.first().toObject()[QStringLiteral("name")].toString()
+ .endsWith(QStringLiteral("data/test.qml")));
+}
+
+void tst_QQmlDebugJS::encodeQmlScope()
+{
+ QString file(ENCODEQMLSCOPE_QMLFILE);
+ QCOMPARE(init(true, file), ConnectSuccess);
+
+ int numFrames = 0;
+ int numExpectedScopes = 0;
+ int numReceivedScopes = 0;
+ bool isStopped = false;
+ bool scopesFailed = false;
+
+ QObject::connect(m_client.data(), &QV4DebugClient::failure, this, [&]() {
+ qWarning() << "received failure" << m_client->response().body;
+ scopesFailed = true;
+ m_process->stop();
+ numFrames = 2;
+ isStopped = false;
+ });
+
+ QObject::connect(m_client.data(), &QV4DebugClient::stopped, this, [&]() {
+ m_client->frame();
+ isStopped = true;
+ });
+
+ QObject::connect(m_client.data(), &QV4DebugClient::result, this, [&]() {
+ const QV4DebugClient::Response value = m_client->response();
+
+ if (value.command == QString("scope")) {
+ // If the scope commands fail we get a failure() signal above.
+ if (++numReceivedScopes == numExpectedScopes) {
+ m_client->continueDebugging(QV4DebugClient::Continue);
+ isStopped = false;
+ }
+ } else if (value.command == QString("frame")) {
+
+ // We want at least a global scope and some kind of local scope here.
+ const QJsonArray scopes = value.body.toObject().value("scopes").toArray();
+ if (scopes.count() < 2)
+ scopesFailed = true;
+
+ for (const QJsonValue &scope : scopes) {
+ ++numExpectedScopes;
+ m_client->scope(scope.toObject().value("index").toInt());
+ }
+
+ ++numFrames;
+ }
+ });
+
+ m_client->setBreakpoint(file, 6);
+ m_client->setBreakpoint(file, 8);
+ m_client->connect();
+
+ QTRY_COMPARE(numFrames, 2);
+ QVERIFY(numExpectedScopes > 3);
+ QVERIFY(!scopesFailed);
+ QTRY_VERIFY(!isStopped);
+ QCOMPARE(numReceivedScopes, numExpectedScopes);
+}
+
+void tst_QQmlDebugJS::breakOnAnchor()
+{
+ QString file(BREAKONANCHOR_QMLFILE);
+ QCOMPARE(init(true, file), ConnectSuccess);
+
+ int breaks = 0;
+ bool stopped = false;
+ QObject::connect(m_client.data(), &QV4DebugClient::stopped, this, [&]() {
+ stopped = true;
+ ++breaks;
+ m_client->evaluate("this", 0, -1);
+ });
+
+ QObject::connect(m_client.data(), &QV4DebugClient::result, this, [&]() {
+ if (stopped) {
+ m_client->continueDebugging(QV4DebugClient::Continue);
+ stopped = false;
+ }
+ });
+
+ QObject::connect(m_client.data(), &QV4DebugClient::failure, this, [&]() {
+ qWarning() << "received failure" << m_client->response().body;
+ });
+
+ m_client->setBreakpoint(file, 34);
+ m_client->setBreakpoint(file, 37);
+
+ QTRY_COMPARE(m_process->state(), QProcess::Running);
+
+ m_client->connect();
+
+ QTRY_COMPARE(m_process->state(), QProcess::NotRunning);
+ QCOMPARE(m_process->exitStatus(), QProcess::NormalExit);
+
+ QCOMPARE(breaks, 2);
+}
+
+QList<QQmlDebugClient *> tst_QQmlDebugJS::createClients()
+{
+ m_client = new QV4DebugClient(m_connection);
+ return QList<QQmlDebugClient *>({m_client});
+}
+
+void tst_QQmlDebugJS::targetData()
+{
+ QTest::addColumn<bool>("qmlscene");
+ QTest::newRow("custom") << false;
+ QTest::newRow("qmlscene") << true;
+}
+
+bool tst_QQmlDebugJS::waitForClientSignal(const char *signal, int timeout)
+{
+ return QQmlDebugTest::waitForSignal(m_client.data(), signal, timeout);
+}
+
+void tst_QQmlDebugJS::checkVersionParameters()
+{
+ const QV4DebugClient::Response value = m_client->response();
+ QCOMPARE(value.command, QString("version"));
+ const QJsonObject body = value.body.toObject();
+ QCOMPARE(body.value("UnpausedEvaluate").toBool(), true);
+ QCOMPARE(body.value("ContextEvaluate").toBool(), true);
+ QCOMPARE(body.value("ChangeBreakpoint").toBool(), true);
+}
+
+QTEST_MAIN(tst_QQmlDebugJS)
+
+#include "tst_qqmldebugjs.moc"
+
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/qqmldebuglocal.pro b/tests/auto/qml/debugger/qqmldebuglocal/qqmldebuglocal.pro
index 860d39cca4..1dc9de8f34 100644
--- a/tests/auto/qml/debugger/qqmldebuglocal/qqmldebuglocal.pro
+++ b/tests/auto/qml/debugger/qqmldebuglocal/qqmldebuglocal.pro
@@ -7,7 +7,6 @@ HEADERS += ../shared/qqmldebugtestservice.h
SOURCES += tst_qqmldebuglocal.cpp \
../shared/qqmldebugtestservice.cpp
-INCLUDEPATH += ../shared
include(../shared/debugutil.pri)
QT += qml-private testlib gui-private core-private
diff --git a/tests/auto/qml/debugger/qqmldebuglocal/tst_qqmldebuglocal.cpp b/tests/auto/qml/debugger/qqmldebuglocal/tst_qqmldebuglocal.cpp
index 8d21a8a45a..4e47c92c2a 100644
--- a/tests/auto/qml/debugger/qqmldebuglocal/tst_qqmldebuglocal.cpp
+++ b/tests/auto/qml/debugger/qqmldebuglocal/tst_qqmldebuglocal.cpp
@@ -32,6 +32,8 @@
#include <private/qqmldebugconnector_p.h>
#include <private/qqmldebugconnection_p.h>
+#include <QtQml/qqmlengine.h>
+
#include <QtTest/qtest.h>
#include <QtTest/qsignalspy.h>
#include <QtNetwork/qhostaddress.h>
@@ -61,10 +63,8 @@ private slots:
void tst_QQmlDebugLocal::initTestCase()
{
- fileName = QString::fromLatin1("tst_QQmlDebugLocal%1").arg(std::time(0));
+ 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);
@@ -116,7 +116,7 @@ void tst_QQmlDebugLocal::state()
QQmlDebugClient client2("tst_QQmlDebugLocal::state()", m_conn);
QCOMPARE(client2.state(), QQmlDebugClient::NotConnected);
- QQmlDebugClient client3("tst_QQmlDebugLocal::state3()", 0);
+ QQmlDebugClient client3("tst_QQmlDebugLocal::state3()", nullptr);
QCOMPARE(client3.state(), QQmlDebugClient::NotConnected);
}
diff --git a/tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocess.pro b/tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocess.pro
new file mode 100644
index 0000000000..331d87b9f1
--- /dev/null
+++ b/tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocess.pro
@@ -0,0 +1,4 @@
+TEMPLATE = subdirs
+SUBDIRS = qqmldebugprocess qqmldebugprocessprocess
+
+qqmldebugprocess.depends = qqmldebugprocessprocess
diff --git a/tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocess/qqmldebugprocess.pro b/tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocess/qqmldebugprocess.pro
new file mode 100644
index 0000000000..9bea2d222c
--- /dev/null
+++ b/tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocess/qqmldebugprocess.pro
@@ -0,0 +1,14 @@
+CONFIG += testcase
+TARGET = tst_qqmldebugprocess
+QT = core testlib
+CONFIG -= debug_and_release_target
+macos:CONFIG -= app_bundle
+
+SOURCES += \
+ ../../shared/qqmldebugprocess.cpp \
+ tst_qqmldebugprocess.cpp
+
+HEADERS += \
+ ../../shared/qqmldebugprocess_p.h
+
+INCLUDEPATH += ../../shared
diff --git a/tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocess/tst_qqmldebugprocess.cpp b/tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocess/tst_qqmldebugprocess.cpp
new file mode 100644
index 0000000000..35bd912d9b
--- /dev/null
+++ b/tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocess/tst_qqmldebugprocess.cpp
@@ -0,0 +1,126 @@
+/****************************************************************************
+**
+** 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 <qqmldebugprocess_p.h>
+#include <QtTest>
+
+#include <QtCore/qcoreapplication.h>
+#include <QtCore/qscopedpointer.h>
+
+class tst_QQmlDebugProcess : public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void sessionStart_data();
+ void sessionStart();
+};
+
+void tst_QQmlDebugProcess::sessionStart_data()
+{
+ QTest::addColumn<int>("delay");
+ QTest::addColumn<QString>("arg");
+ QTest::addColumn<bool>("sessionExpected");
+ QTest::addColumn<bool>("outputExpected");
+
+ QTest::addRow("synchronous / waiting") << -1
+ << "QML Debugger: Waiting for connection on port 2423..."
+ << true << false;
+ QTest::addRow("synchronous / failed") << -1 << "QML Debugger: Unable to listen to port 242."
+ << false << false;
+ QTest::addRow("synchronous / unknown") << -1 << "QML Debugger: You don't know this string."
+ << false << true;
+ QTest::addRow("synchronous / appout") << -1 << "Output from app itself."
+ << false << true;
+
+ QTest::addRow("no delay / waiting") << 0
+ << "QML Debugger: Waiting for connection on port 2423..."
+ << true << false;
+ QTest::addRow("no delay / failed") << 0 << "QML Debugger: Unable to listen to port 242."
+ << false << false;
+ QTest::addRow("no delay / unknown") << 0 << "QML Debugger: You don't know this string."
+ << false << true;
+ QTest::addRow("no delay / appout") << 0 << "Output from app itself."
+ << false << true;
+
+ QTest::addRow("delay / waiting") << 1000
+ << "QML Debugger: Waiting for connection on port 2423..."
+ << true << false;
+ QTest::addRow("delay / failed") << 1000 << "QML Debugger: Unable to listen to port 242."
+ << false << false;
+ QTest::addRow("delay / unknown") << 1000 << "QML Debugger: You don't know this string."
+ << false << true;
+ QTest::addRow("delay / appout") << 1000 << "Output from app itself."
+ << false << true;
+}
+
+void tst_QQmlDebugProcess::sessionStart()
+{
+ QFETCH(int, delay);
+ QFETCH(QString, arg);
+ QFETCH(bool, sessionExpected);
+ QFETCH(bool, outputExpected);
+
+ QScopedPointer<QQmlDebugProcess> process(
+ new QQmlDebugProcess(QCoreApplication::applicationDirPath()
+ + QLatin1String("/qqmldebugprocessprocess"), this));
+ QVERIFY(process);
+
+ bool outputReceived = false;
+ connect(process.data(), &QQmlDebugProcess::readyReadStandardOutput, this, [&]() {
+ QVERIFY(outputExpected);
+ QVERIFY(!outputReceived);
+ QCOMPARE(process->output().trimmed(), arg);
+ outputReceived = true;
+ QTimer::singleShot(qMax(delay, 0), process.data(), &QQmlDebugProcess::stop);
+ });
+
+ if (!outputExpected && !sessionExpected)
+ QTest::ignoreMessage(QtWarningMsg, "App was unable to bind to port!");
+ process->start(QStringList({arg}));
+
+ bool done = false;
+ auto wait = [&](){
+ QCOMPARE(process->waitForSessionStart(), sessionExpected);
+ QCOMPARE(outputReceived, outputExpected);
+ process->stop();
+ done = true;
+ };
+
+ if (delay < 0)
+ wait();
+ else
+ QTimer::singleShot(delay, process.data(), wait);
+
+ QTRY_VERIFY(done);
+ QCOMPARE(process->state(), QProcess::NotRunning);
+}
+
+QTEST_MAIN(tst_QQmlDebugProcess)
+
+#include "tst_qqmldebugprocess.moc"
diff --git a/tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocessprocess/qqmldebugprocessprocess.cpp b/tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocessprocess/qqmldebugprocessprocess.cpp
new file mode 100644
index 0000000000..21cce53fc3
--- /dev/null
+++ b/tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocessprocess/qqmldebugprocessprocess.cpp
@@ -0,0 +1,39 @@
+/****************************************************************************
+**
+** 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 <QtCore/qdebug.h>
+#include <QtCore/qcoreapplication.h>
+
+// Process that just outputs a fake "Waiting" message.
+int main(int argc, char **argv)
+{
+ QCoreApplication app(argc, argv);
+ if (argc > 1)
+ qDebug() << argv[1];
+ return app.exec();
+}
diff --git a/tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocessprocess/qqmldebugprocessprocess.pro b/tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocessprocess/qqmldebugprocessprocess.pro
new file mode 100644
index 0000000000..a8eb4885d4
--- /dev/null
+++ b/tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocessprocess/qqmldebugprocessprocess.pro
@@ -0,0 +1,11 @@
+QT = core
+macos:CONFIG -= app_bundle
+CONFIG -= debug_and_release_target
+CONFIG += console
+SOURCES += qqmldebugprocessprocess.cpp
+
+DESTDIR = ../qqmldebugprocess
+
+target.path = $$[QT_INSTALL_TESTS]/tst_qqmldebugprocess
+INSTALLS += target
+
diff --git a/tests/auto/qml/debugger/qqmldebugservice/qqmldebugservice.pro b/tests/auto/qml/debugger/qqmldebugservice/qqmldebugservice.pro
index 79cbe52331..3101d09ea5 100644
--- a/tests/auto/qml/debugger/qqmldebugservice/qqmldebugservice.pro
+++ b/tests/auto/qml/debugger/qqmldebugservice/qqmldebugservice.pro
@@ -7,8 +7,6 @@ HEADERS += ../shared/qqmldebugtestservice.h
SOURCES += tst_qqmldebugservice.cpp \
../shared/qqmldebugtestservice.cpp
-INCLUDEPATH += ../shared
-include(../../../shared/util.pri)
include(../shared/debugutil.pri)
TESTDATA = data/*
diff --git a/tests/auto/qml/debugger/qqmldebugservice/tst_qqmldebugservice.cpp b/tests/auto/qml/debugger/qqmldebugservice/tst_qqmldebugservice.cpp
index 8092faba04..3557940386 100644
--- a/tests/auto/qml/debugger/qqmldebugservice/tst_qqmldebugservice.cpp
+++ b/tests/auto/qml/debugger/qqmldebugservice/tst_qqmldebugservice.cpp
@@ -29,6 +29,7 @@
#include "qqmldebugtestservice.h"
#include "debugutil_p.h"
+#include "qqmldebugprocess_p.h"
#include "../../../shared/util.h"
#include <private/qqmldebugclient_p.h>
@@ -74,16 +75,14 @@ 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())
- QCOMPARE(QQmlDebugConnector::instance()->service(service), (QQmlDebugService *)0);
+ QCOMPARE(QQmlDebugConnector::instance()->service(service), (QQmlDebugService *)nullptr);
foreach (const QString &service, QQmlDebuggingEnabler::inspectorServices())
- QCOMPARE(QQmlDebugConnector::instance()->service(service), (QQmlDebugService *)0);
+ QCOMPARE(QQmlDebugConnector::instance()->service(service), (QQmlDebugService *)nullptr);
foreach (const QString &service, QQmlDebuggingEnabler::profilerServices())
- QCOMPARE(QQmlDebugConnector::instance()->service(service), (QQmlDebugService *)0);
+ QCOMPARE(QQmlDebugConnector::instance()->service(service), (QQmlDebugService *)nullptr);
const QString waitingMsg = QString("QML Debugger: Waiting for connection on port %1...").arg(PORT);
QTest::ignoreMessage(QtDebugMsg, waitingMsg.toLatin1().constData());
@@ -105,10 +104,13 @@ void tst_QQmlDebugService::initTestCase()
void tst_QQmlDebugService::checkPortRange()
{
- QQmlDebugConnection *connection1 = new QQmlDebugConnection();
- QQmlDebugProcess *process1 = new QQmlDebugProcess(QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene", this);
+ QScopedPointer<QQmlDebugConnection> connection1(new QQmlDebugConnection());
+ QScopedPointer<QQmlDebugProcess> process1(
+ new QQmlDebugProcess(QLibraryInfo::location(QLibraryInfo::BinariesPath)
+ + "/qmlscene", this));
- process1->start(QStringList() << QLatin1String("-qmljsdebugger=port:3782,3792") << testFile("test.qml"));
+ process1->start(QStringList() << QLatin1String("-qmljsdebugger=port:3782,3792")
+ << testFile("test.qml"));
if (!process1->waitForSessionStart())
QFAIL("could not launch application, or did not get 'Waiting for connection'.");
@@ -119,10 +121,13 @@ void tst_QQmlDebugService::checkPortRange()
QFAIL("could not connect to host!");
// Second instance
- QQmlDebugConnection *connection2 = new QQmlDebugConnection();
- QQmlDebugProcess *process2 = new QQmlDebugProcess(QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene", this);
+ QScopedPointer<QQmlDebugConnection> connection2(new QQmlDebugConnection());
+ QScopedPointer<QQmlDebugProcess> process2(
+ new QQmlDebugProcess(QLibraryInfo::location(QLibraryInfo::BinariesPath)
+ + "/qmlscene", this));
- process2->start(QStringList() << QLatin1String("-qmljsdebugger=port:3782,3792") << testFile("test.qml"));
+ process2->start(QStringList() << QLatin1String("-qmljsdebugger=port:3782,3792")
+ << testFile("test.qml"));
if (!process2->waitForSessionStart())
QFAIL("could not launch application, or did not get 'Waiting for connection'.");
@@ -131,11 +136,6 @@ void tst_QQmlDebugService::checkPortRange()
connection2->connectToHost("127.0.0.1", port2);
if (!connection2->waitForConnected())
QFAIL("could not connect to host!");
-
- delete connection1;
- delete process1;
- delete connection2;
- delete process2;
}
void tst_QQmlDebugService::name()
@@ -207,7 +207,7 @@ void tst_QQmlDebugService::checkSupportForDataStreamVersion()
void tst_QQmlDebugService::idForObject()
{
- QCOMPARE(QQmlDebugService::idForObject(0), -1);
+ QCOMPARE(QQmlDebugService::idForObject(nullptr), -1);
QObject *objA = new QObject;
@@ -229,15 +229,15 @@ void tst_QQmlDebugService::idForObject()
void tst_QQmlDebugService::objectForId()
{
- QCOMPARE(QQmlDebugService::objectForId(-1), static_cast<QObject*>(0));
- QCOMPARE(QQmlDebugService::objectForId(1), static_cast<QObject*>(0));
+ QCOMPARE(QQmlDebugService::objectForId(-1), static_cast<QObject*>(nullptr));
+ QCOMPARE(QQmlDebugService::objectForId(1), static_cast<QObject*>(nullptr));
QObject *obj = new QObject;
int id = QQmlDebugService::idForObject(obj);
QCOMPARE(QQmlDebugService::objectForId(id), obj);
delete obj;
- QCOMPARE(QQmlDebugService::objectForId(id), static_cast<QObject*>(0));
+ QCOMPARE(QQmlDebugService::objectForId(id), static_cast<QObject*>(nullptr));
}
void tst_QQmlDebugService::checkSupportForOldDataStreamVersion()
diff --git a/tests/auto/qml/debugger/qqmlenginecontrol/qqmlenginecontrol.pro b/tests/auto/qml/debugger/qqmlenginecontrol/qqmlenginecontrol.pro
index 2518650493..36957628b2 100644
--- a/tests/auto/qml/debugger/qqmlenginecontrol/qqmlenginecontrol.pro
+++ b/tests/auto/qml/debugger/qqmlenginecontrol/qqmlenginecontrol.pro
@@ -4,13 +4,11 @@ osx:CONFIG -= app_bundle
SOURCES += tst_qqmlenginecontrol.cpp
-INCLUDEPATH += ../shared
-include(../../../shared/util.pri)
include(../shared/debugutil.pri)
TESTDATA = data/*
-QT += core qml testlib gui-private core-private
+QT += core testlib gui-private core-private
OTHER_FILES += \
data/test.qml \
diff --git a/tests/auto/qml/debugger/qqmlenginecontrol/tst_qqmlenginecontrol.cpp b/tests/auto/qml/debugger/qqmlenginecontrol/tst_qqmlenginecontrol.cpp
index 3f8731ce6b..a8c43b1c75 100644
--- a/tests/auto/qml/debugger/qqmlenginecontrol/tst_qqmlenginecontrol.cpp
+++ b/tests/auto/qml/debugger/qqmlenginecontrol/tst_qqmlenginecontrol.cpp
@@ -37,9 +37,6 @@
#include <QtTest/qtest.h>
#include <QtCore/qlibraryinfo.h>
-#define STR_PORT_FROM "13773"
-#define STR_PORT_TO "13783"
-
class QQmlEngineBlocker : public QObject
{
Q_OBJECT
@@ -64,77 +61,37 @@ void QQmlEngineBlocker::blockEngine(int engineId, const QString &name)
static_cast<QQmlEngineControlClient *>(parent())->blockEngine(engineId);
}
-class tst_QQmlEngineControl : public QQmlDataTest
+class tst_QQmlEngineControl : public QQmlDebugTest
{
Q_OBJECT
-public:
- tst_QQmlEngineControl()
- : m_process(0)
- , m_connection(0)
- , m_client(0)
- {}
-
private:
- QQmlDebugProcess *m_process;
- QQmlDebugConnection *m_connection;
- QQmlEngineControlClient *m_client;
+ ConnectResult connect(const QString &testFile, bool restrictServices);
+ QList<QQmlDebugClient *> createClients() override;
- void connect(const QString &testFile, bool restrictServices);
void engine_data();
+ QPointer<QQmlEngineControlClient> m_client;
private slots:
- void cleanup();
-
void startEngine_data();
void startEngine();
void stopEngine_data();
void stopEngine();
};
-void tst_QQmlEngineControl::connect(const QString &testFile, bool restrictServices)
+QQmlDebugTest::ConnectResult tst_QQmlEngineControl::connect(const QString &file,
+ bool restrictServices)
{
- const QString executable = QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene";
- QStringList arguments;
- arguments << QString::fromLatin1("-qmljsdebugger=port:%1,%2,block%3")
- .arg(STR_PORT_FROM).arg(STR_PORT_TO)
- .arg(restrictServices ? QStringLiteral(",services:EngineControl") : QString());
-
- arguments << QQmlDataTest::instance()->testFile(testFile);
-
- m_process = new QQmlDebugProcess(executable, this);
- m_process->start(QStringList() << arguments);
- QVERIFY2(m_process->waitForSessionStart(), "Could not launch application, or did not get 'Waiting for connection'.");
-
- m_connection = new QQmlDebugConnection();
- m_client = new QQmlEngineControlClient(m_connection);
- new QQmlEngineBlocker(m_client);
- QList<QQmlDebugClient *> others = QQmlDebugTest::createOtherClients(m_connection);
-
- const int port = m_process->debugPort();
- m_connection->connectToHost(QLatin1String("127.0.0.1"), port);
-
- QTRY_COMPARE(m_client->state(), QQmlDebugClient::Enabled);
- foreach (QQmlDebugClient *other, others)
- QCOMPARE(other->state(), restrictServices ? QQmlDebugClient::Unavailable :
- QQmlDebugClient::Enabled);
- qDeleteAll(others);
+ return QQmlDebugTest::connect(QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene",
+ restrictServices ? QStringLiteral("EngineControl") : QString(),
+ testFile(file), true);
}
-void tst_QQmlEngineControl::cleanup()
+QList<QQmlDebugClient *> tst_QQmlEngineControl::createClients()
{
- if (QTest::currentTestFailed()) {
- qDebug() << "Process State:" << (m_process ? m_process->state() : QLatin1String("null"));
- qDebug() << "Application Output:" << (m_process ? m_process->output() : QLatin1String("null"));
- qDebug() << "Connection State:" << QQmlDebugTest::connectionStateString(m_connection);
- qDebug() << "Client State:" << QQmlDebugTest::clientStateString(m_client);
- }
- delete m_process;
- m_process = 0;
- delete m_client;
- m_client = 0;
- delete m_connection;
- m_connection = 0;
+ m_client = new QQmlEngineControlClient(m_connection);
+ new QQmlEngineBlocker(m_client);
+ return QList<QQmlDebugClient *>({m_client});
}
void tst_QQmlEngineControl::engine_data()
@@ -152,14 +109,16 @@ void tst_QQmlEngineControl::startEngine_data()
void tst_QQmlEngineControl::startEngine()
{
QFETCH(bool, restrictMode);
-
- connect("test.qml", restrictMode);
+ QCOMPARE(connect("test.qml", restrictMode), ConnectSuccess);
QTRY_VERIFY(!m_client->blockedEngines().empty());
m_client->releaseEngine(m_client->blockedEngines().last());
+ QVERIFY(m_client->blockedEngines().isEmpty());
QVERIFY2(QQmlDebugTest::waitForSignal(m_client, SIGNAL(engineAdded(int,QString))),
"No engine start message received in time.");
+
+ QVERIFY(m_client->blockedEngines().isEmpty());
}
void tst_QQmlEngineControl::stopEngine_data()
@@ -171,19 +130,23 @@ void tst_QQmlEngineControl::stopEngine()
{
QFETCH(bool, restrictMode);
- connect("exit.qml", restrictMode);
+ QCOMPARE(connect("exit.qml", restrictMode), ConnectSuccess);
QTRY_VERIFY(!m_client->blockedEngines().empty());
m_client->releaseEngine(m_client->blockedEngines().last());
+ QVERIFY(m_client->blockedEngines().isEmpty());
QVERIFY2(QQmlDebugTest::waitForSignal(m_client, SIGNAL(engineAdded(int,QString))),
"No engine start message received in time.");
+ QVERIFY(m_client->blockedEngines().isEmpty());
QVERIFY2(QQmlDebugTest::waitForSignal(m_client, SIGNAL(engineAboutToBeRemoved(int,QString))),
"No engine about to stop message received in time.");
m_client->releaseEngine(m_client->blockedEngines().last());
+ QVERIFY(m_client->blockedEngines().isEmpty());
QVERIFY2(QQmlDebugTest::waitForSignal(m_client, SIGNAL(engineRemoved(int,QString))),
"No engine stop message received in time.");
+ QVERIFY(m_client->blockedEngines().isEmpty());
}
QTEST_MAIN(tst_QQmlEngineControl)
diff --git a/tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/qqmlenginedebuginspectorintegrationtest.pro b/tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/qqmlenginedebuginspectorintegrationtest.pro
index e11ccdc6ca..454a1e3ab0 100644
--- a/tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/qqmlenginedebuginspectorintegrationtest.pro
+++ b/tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/qqmlenginedebuginspectorintegrationtest.pro
@@ -1,15 +1,11 @@
CONFIG += testcase
TARGET = tst_qqmlenginedebuginspectorintegration
-QT += qml testlib gui-private core-private
+QT += testlib gui-private core-private
osx:CONFIG -= app_bundle
SOURCES += tst_qqmlenginedebuginspectorintegration.cpp
-INCLUDEPATH += ../shared
-include(../../../shared/util.pri)
-include(../shared/qqmlinspectorclient.pri)
-include(../shared/qqmlenginedebugclient.pri)
include(../shared/debugutil.pri)
TESTDATA = data/*
diff --git a/tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/tst_qqmlenginedebuginspectorintegration.cpp b/tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/tst_qqmlenginedebuginspectorintegration.cpp
index 940f89e936..980e2be1f1 100644
--- a/tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/tst_qqmlenginedebuginspectorintegration.cpp
+++ b/tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/tst_qqmlenginedebuginspectorintegration.cpp
@@ -26,12 +26,12 @@
**
****************************************************************************/
-#include "qqmlinspectorclient.h"
-#include "qqmlenginedebugclient.h"
#include "../shared/debugutil_p.h"
#include "../../../shared/util.h"
#include <private/qqmldebugconnection_p.h>
+#include <private/qqmlenginedebugclient_p.h>
+#include <private/qqmlinspectorclient_p.h>
#include <QtTest/qtest.h>
#include <QtTest/qsignalspy.h>
@@ -41,35 +41,21 @@
#include <QtCore/qthread.h>
#include <QtCore/qlibraryinfo.h>
-#define STR_PORT_FROM "3776"
-#define STR_PORT_TO "3786"
-
-class tst_QQmlEngineDebugInspectorIntegration : public QQmlDataTest
+class tst_QQmlEngineDebugInspectorIntegration : public QQmlDebugTest
{
Q_OBJECT
-public:
- tst_QQmlEngineDebugInspectorIntegration()
- : m_process(0)
- , m_inspectorClient(0)
- , m_engineDebugClient(0)
- , m_recipient(0)
- {
- }
-
-
private:
- void init(bool restrictServices);
- QmlDebugObjectReference findRootObject();
+ ConnectResult init(bool restrictServices);
+ QList<QQmlDebugClient *> createClients() override;
- QQmlDebugProcess *m_process;
- QQmlInspectorClient *m_inspectorClient;
- QQmlEngineDebugClient *m_engineDebugClient;
- QQmlInspectorResultRecipient *m_recipient;
+ QQmlEngineDebugObjectReference findRootObject();
-private slots:
- void cleanup();
+ QPointer<QQmlInspectorClient> m_inspectorClient;
+ QPointer<QQmlEngineDebugClient> m_engineDebugClient;
+ QPointer<QQmlInspectorResultRecipient> m_recipient;
+private slots:
void connect_data();
void connect();
void objectLocationLookup();
@@ -79,73 +65,42 @@ private slots:
void destroyObject();
};
-QmlDebugObjectReference tst_QQmlEngineDebugInspectorIntegration::findRootObject()
+QQmlEngineDebugObjectReference tst_QQmlEngineDebugInspectorIntegration::findRootObject()
{
bool success = false;
m_engineDebugClient->queryAvailableEngines(&success);
if (!QQmlDebugTest::waitForSignal(m_engineDebugClient, SIGNAL(result())))
- return QmlDebugObjectReference();
+ return QQmlEngineDebugObjectReference();
- m_engineDebugClient->queryRootContexts(m_engineDebugClient->engines()[0].debugId, &success);
+ m_engineDebugClient->queryRootContexts(m_engineDebugClient->engines()[0], &success);
if (!QQmlDebugTest::waitForSignal(m_engineDebugClient, SIGNAL(result())))
- return QmlDebugObjectReference();
+ return QQmlEngineDebugObjectReference();
int count = m_engineDebugClient->rootContext().contexts.count();
m_engineDebugClient->queryObject(
m_engineDebugClient->rootContext().contexts[count - 1].objects[0], &success);
if (!QQmlDebugTest::waitForSignal(m_engineDebugClient, SIGNAL(result())))
- return QmlDebugObjectReference();
+ return QQmlEngineDebugObjectReference();
return m_engineDebugClient->object();
}
-void tst_QQmlEngineDebugInspectorIntegration::init(bool restrictServices)
+QQmlDebugTest::ConnectResult tst_QQmlEngineDebugInspectorIntegration::init(bool restrictServices)
{
- const QString argument = QString::fromLatin1("-qmljsdebugger=port:%1,%2,block%3")
- .arg(STR_PORT_FROM).arg(STR_PORT_TO)
- .arg(restrictServices ? QStringLiteral(",services:QmlDebugger,QmlInspector") :
- QString());
-
- m_process = new QQmlDebugProcess(QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qml",
- this);
- m_process->start(QStringList() << argument << testFile("qtquick2.qml"));
- QVERIFY2(m_process->waitForSessionStart(),
- "Could not launch application, or did not get 'Waiting for connection'.");
-
- QQmlDebugConnection *m_connection = new QQmlDebugConnection(this);
- m_inspectorClient = new QQmlInspectorClient(m_connection);
- m_engineDebugClient = new QQmlEngineDebugClient(m_connection);
- m_recipient = new QQmlInspectorResultRecipient(this);
- QObject::connect(m_inspectorClient, &QQmlInspectorClient::responseReceived,
- m_recipient, &QQmlInspectorResultRecipient::recordResponse);
-
- QList<QQmlDebugClient *> others = QQmlDebugTest::createOtherClients(m_connection);
-
- m_connection->connectToHost(QLatin1String("127.0.0.1"), m_process->debugPort());
- QVERIFY(m_connection->waitForConnected());
- foreach (QQmlDebugClient *other, others)
- QCOMPARE(other->state(), restrictServices ? QQmlDebugClient::Unavailable :
- QQmlDebugClient::Enabled);
- qDeleteAll(others);
-
- QTRY_COMPARE(m_inspectorClient->state(), QQmlDebugClient::Enabled);
- QTRY_COMPARE(m_engineDebugClient->state(), QQmlDebugClient::Enabled);
+ return QQmlDebugTest::connect(
+ QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qml",
+ restrictServices ? QStringLiteral("QmlDebugger,QmlInspector") : QString(),
+ testFile("qtquick2.qml"), true);
}
-void tst_QQmlEngineDebugInspectorIntegration::cleanup()
+QList<QQmlDebugClient *> tst_QQmlEngineDebugInspectorIntegration::createClients()
{
- if (QTest::currentTestFailed()) {
- qDebug() << "Process State:" << m_process->state();
- qDebug() << "Application Output:" << m_process->output();
- }
- delete m_process;
- m_process = 0;
- delete m_engineDebugClient;
- m_engineDebugClient = 0;
- delete m_inspectorClient;
- m_inspectorClient = 0;
- delete m_recipient;
- m_recipient = 0;
+ m_inspectorClient = new QQmlInspectorClient(m_connection);
+ m_engineDebugClient = new QQmlEngineDebugClient(m_connection);
+ m_recipient = new QQmlInspectorResultRecipient(m_inspectorClient);
+ QObject::connect(m_inspectorClient.data(), &QQmlInspectorClient::responseReceived,
+ m_recipient.data(), &QQmlInspectorResultRecipient::recordResponse);
+ return QList<QQmlDebugClient *>({m_inspectorClient, m_engineDebugClient});
}
void tst_QQmlEngineDebugInspectorIntegration::connect_data()
@@ -158,15 +113,15 @@ void tst_QQmlEngineDebugInspectorIntegration::connect_data()
void tst_QQmlEngineDebugInspectorIntegration::connect()
{
QFETCH(bool, restrictMode);
- init(restrictMode);
+ QCOMPARE(init(restrictMode), ConnectSuccess);
}
void tst_QQmlEngineDebugInspectorIntegration::objectLocationLookup()
{
- init(true);
+ QCOMPARE(init(true), ConnectSuccess);
bool success = false;
- QmlDebugObjectReference rootObject = findRootObject();
+ QQmlEngineDebugObjectReference rootObject = findRootObject();
QVERIFY(rootObject.debugId != -1);
const QString fileName = QFileInfo(rootObject.source.url.toString()).fileName();
int lineNumber = rootObject.source.lineNumber;
@@ -176,7 +131,7 @@ void tst_QQmlEngineDebugInspectorIntegration::objectLocationLookup()
QVERIFY(success);
QVERIFY(QQmlDebugTest::waitForSignal(m_engineDebugClient, SIGNAL(result())));
- foreach (QmlDebugObjectReference child, rootObject.children) {
+ foreach (QQmlEngineDebugObjectReference child, rootObject.children) {
success = false;
lineNumber = child.source.lineNumber;
columnNumber = child.source.columnNumber;
@@ -189,11 +144,12 @@ void tst_QQmlEngineDebugInspectorIntegration::objectLocationLookup()
void tst_QQmlEngineDebugInspectorIntegration::select()
{
- init(true);
- QmlDebugObjectReference rootObject = findRootObject();
+ QCOMPARE(init(true), ConnectSuccess);
+
+ QQmlEngineDebugObjectReference rootObject = findRootObject();
QList<int> childIds;
int requestId = 0;
- foreach (const QmlDebugObjectReference &child, rootObject.children) {
+ foreach (const QQmlEngineDebugObjectReference &child, rootObject.children) {
requestId = m_inspectorClient->select(QList<int>() << child.debugId);
QTRY_COMPARE(m_recipient->lastResponseId, requestId);
QVERIFY(m_recipient->lastResult);
@@ -206,7 +162,7 @@ void tst_QQmlEngineDebugInspectorIntegration::select()
void tst_QQmlEngineDebugInspectorIntegration::createObject()
{
- init(true);
+ QCOMPARE(init(true), ConnectSuccess);
QString qml = QLatin1String("Rectangle {\n"
" id: xxxyxxx\n"
@@ -215,7 +171,7 @@ void tst_QQmlEngineDebugInspectorIntegration::createObject()
" color: \"blue\"\n"
"}");
- QmlDebugObjectReference rootObject = findRootObject();
+ QQmlEngineDebugObjectReference rootObject = findRootObject();
QVERIFY(rootObject.debugId != -1);
QCOMPARE(rootObject.children.length(), 2);
@@ -233,8 +189,10 @@ void tst_QQmlEngineDebugInspectorIntegration::createObject()
void tst_QQmlEngineDebugInspectorIntegration::moveObject()
{
- init(true);
- QmlDebugObjectReference rootObject = findRootObject();
+ QCOMPARE(init(true), ConnectSuccess);
+
+ QCOMPARE(m_inspectorClient->state(), QQmlDebugClient::Enabled);
+ QQmlEngineDebugObjectReference rootObject = findRootObject();
QVERIFY(rootObject.debugId != -1);
QCOMPARE(rootObject.children.length(), 2);
@@ -256,8 +214,10 @@ void tst_QQmlEngineDebugInspectorIntegration::moveObject()
void tst_QQmlEngineDebugInspectorIntegration::destroyObject()
{
- init(true);
- QmlDebugObjectReference rootObject = findRootObject();
+ QCOMPARE(init(true), ConnectSuccess);
+
+ QCOMPARE(m_inspectorClient->state(), QQmlDebugClient::Enabled);
+ QQmlEngineDebugObjectReference rootObject = findRootObject();
QVERIFY(rootObject.debugId != -1);
QCOMPARE(rootObject.children.length(), 2);
diff --git a/tests/auto/qml/debugger/qqmlenginedebugservice/qqmlenginedebugservice.pro b/tests/auto/qml/debugger/qqmlenginedebugservice/qqmlenginedebugservice.pro
index 06250d9940..5ff65ba276 100644
--- a/tests/auto/qml/debugger/qqmlenginedebugservice/qqmlenginedebugservice.pro
+++ b/tests/auto/qml/debugger/qqmlenginedebugservice/qqmlenginedebugservice.pro
@@ -5,11 +5,8 @@ osx:CONFIG -= app_bundle
SOURCES += \
tst_qqmlenginedebugservice.cpp
-INCLUDEPATH += ../shared
-include(../../../shared/util.pri)
-include(../shared/qqmlenginedebugclient.pri)
include(../shared/debugutil.pri)
DEFINES += QT_QML_DEBUG_NO_WARNING
-QT += core-private qml-private quick-private testlib gui-private
+QT += quick qml-private testlib
diff --git a/tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp b/tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp
index d9a4777115..99c90c142f 100644
--- a/tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp
+++ b/tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp
@@ -26,7 +26,6 @@
**
****************************************************************************/
-#include "qqmlenginedebugclient.h"
#include "debugutil_p.h"
#include "../../../shared/util.h"
@@ -36,6 +35,7 @@
#include <private/qqmlmetatype_p.h>
#include <private/qqmlproperty_p.h>
#include <private/qqmldebugconnection_p.h>
+#include <private/qqmlenginedebugclient_p.h>
#include <QtTest/qtest.h>
#include <QtTest/qsignalspy.h>
@@ -53,11 +53,14 @@
#include <QtCore/qdebug.h>
#include <QtCore/qthread.h>
#include <QtCore/qabstractitemmodel.h>
+#include <QtCore/qjsonobject.h>
+#include <QtCore/qjsonarray.h>
+#include <QtCore/qjsondocument.h>
#define QVERIFYOBJECT(statement) \
do {\
if (!QTest::qVerify((statement), #statement, "", __FILE__, __LINE__)) {\
- return QmlDebugObjectReference();\
+ return QQmlEngineDebugObjectReference();\
}\
} while (0)
@@ -77,28 +80,64 @@ class CustomTypes : public QObject
Q_OBJECT
Q_PROPERTY(QModelIndex modelIndex READ modelIndex)
public:
- CustomTypes(QObject *parent = 0) : QObject(parent) {}
+ CustomTypes(QObject *parent = nullptr) : QObject(parent) {}
QModelIndex modelIndex() { return QModelIndex(); }
};
+class JsonTest : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QJsonObject data READ data WRITE setData NOTIFY dataChanged)
+
+public:
+ JsonTest(QObject *parent = 0) : QObject(parent)
+ {
+ m_data["foo"] = QJsonValue(12);
+ m_data["ttt"] = QJsonArray({4, 5, 4, 3, 2});
+ m_data["a"] = QJsonValue(QJsonValue::Null);
+ m_data["b"] = QJsonValue(QJsonValue::Undefined);
+ m_data["c"] = QJsonValue("fffff");
+ }
+
+ QJsonObject data() const { return m_data; }
+
+signals:
+ void dataChanged(const QJsonObject &data);
+
+public slots:
+ void setData(const QJsonObject &data)
+ {
+ if (data != m_data) {
+ m_data = data;
+ emit dataChanged(data);
+ }
+ }
+
+private:
+ QJsonObject m_data;
+};
+
+
class tst_QQmlEngineDebugService : public QObject
{
Q_OBJECT
public:
- tst_QQmlEngineDebugService() : m_conn(0), m_dbg(0), m_engine(0), m_rootItem(0) {}
+ tst_QQmlEngineDebugService() : m_conn(nullptr), m_dbg(nullptr), m_engine(nullptr), m_rootItem(nullptr) {}
private:
- QmlDebugObjectReference findRootObject(int context = 0,
+ QQmlEngineDebugObjectReference findRootObject(int context = 0,
bool recursive = false);
- QmlDebugPropertyReference findProperty(
- const QList<QmlDebugPropertyReference> &props,
+ QQmlEngineDebugPropertyReference findProperty(
+ const QList<QQmlEngineDebugPropertyReference> &props,
const QString &name) const;
void recursiveObjectTest(QObject *o,
- const QmlDebugObjectReference &oref,
+ const QQmlEngineDebugObjectReference &oref,
bool recursive) const;
+ void getContexts();
+
QQmlDebugConnection *m_conn;
QQmlEngineDebugClient *m_dbg;
QQmlEngine *m_engine;
@@ -137,10 +176,13 @@ private slots:
void regression_QTCREATORBUG_7451();
void queryObjectWithNonStreamableTypes();
+ void jsonData();
void asynchronousCreate();
+ void invalidContexts();
+ void createObjectOnDestruction();
};
-QmlDebugObjectReference tst_QQmlEngineDebugService::findRootObject(
+QQmlEngineDebugObjectReference tst_QQmlEngineDebugService::findRootObject(
int context, bool recursive)
{
bool success = false;
@@ -149,7 +191,7 @@ QmlDebugObjectReference tst_QQmlEngineDebugService::findRootObject(
QVERIFYOBJECT(QQmlDebugTest::waitForSignal(m_dbg, SIGNAL(result())));
QVERIFYOBJECT(m_dbg->engines().count());
- m_dbg->queryRootContexts(m_dbg->engines()[0].debugId, &success);
+ m_dbg->queryRootContexts(m_dbg->engines()[0], &success);
QVERIFYOBJECT(success);
QVERIFYOBJECT(QQmlDebugTest::waitForSignal(m_dbg, SIGNAL(result())));
@@ -165,18 +207,18 @@ QmlDebugObjectReference tst_QQmlEngineDebugService::findRootObject(
return m_dbg->object();
}
-QmlDebugPropertyReference tst_QQmlEngineDebugService::findProperty(
- const QList<QmlDebugPropertyReference> &props, const QString &name) const
+QQmlEngineDebugPropertyReference tst_QQmlEngineDebugService::findProperty(
+ const QList<QQmlEngineDebugPropertyReference> &props, const QString &name) const
{
- foreach (const QmlDebugPropertyReference &p, props) {
+ foreach (const QQmlEngineDebugPropertyReference &p, props) {
if (p.name == name)
return p;
}
- return QmlDebugPropertyReference();
+ return QQmlEngineDebugPropertyReference();
}
void tst_QQmlEngineDebugService::recursiveObjectTest(
- QObject *o, const QmlDebugObjectReference &oref, bool recursive) const
+ QObject *o, const QQmlEngineDebugObjectReference &oref, bool recursive) const
{
const QMetaObject *meta = o->metaObject();
@@ -194,8 +236,8 @@ void tst_QQmlEngineDebugService::recursiveObjectTest(
int debugId = QQmlDebugService::idForObject(child);
QVERIFY(debugId >= 0);
- QmlDebugObjectReference cref;
- foreach (const QmlDebugObjectReference &ref, oref.children) {
+ QQmlEngineDebugObjectReference cref;
+ foreach (const QQmlEngineDebugObjectReference &ref, oref.children) {
QVERIFY(!ref.className.isEmpty());
if (ref.debugId == debugId) {
cref = ref;
@@ -208,7 +250,7 @@ void tst_QQmlEngineDebugService::recursiveObjectTest(
recursiveObjectTest(child, cref, true);
}
- foreach (const QmlDebugPropertyReference &p, oref.properties) {
+ foreach (const QQmlEngineDebugPropertyReference &p, oref.properties) {
QCOMPARE(p.objectDebugId, QQmlDebugService::idForObject(o));
// signal properties are fake - they are generated from QQmlAbstractBoundSignal children
@@ -226,9 +268,24 @@ void tst_QQmlEngineDebugService::recursiveObjectTest(
QCOMPARE(p.name, QString::fromUtf8(pmeta.name()));
- if (pmeta.type() < QVariant::UserType && pmeta.userType() !=
- QMetaType::QVariant) // TODO test complex types
- QCOMPARE(p.value , pmeta.read(o));
+ if (pmeta.userType() == QMetaType::QObjectStar) {
+ const QQmlEngineDebugObjectReference ref
+ = qvariant_cast<QQmlEngineDebugObjectReference>(p.value);
+ QObject *pobj = qvariant_cast<QObject *>(pmeta.read(o));
+ if (pobj) {
+ if (pobj->objectName().isEmpty())
+ QCOMPARE(ref.name, QString("<unnamed object>"));
+ else
+ QCOMPARE(ref.name, pobj->objectName());
+ } else {
+ QCOMPARE(ref.name, QString("<unknown value>"));
+ }
+ } else if (pmeta.type() < QVariant::UserType && pmeta.userType() != QMetaType::QVariant) {
+ const QVariant expected = pmeta.read(o);
+ QVERIFY2(p.value == expected, QString::fromLatin1("%1 != %2. Details: %3/%4/%5/%6")
+ .arg(QTest::toString(p.value)).arg(QTest::toString(expected)).arg(p.name)
+ .arg(p.valueTypeName).arg(pmeta.type()).arg(pmeta.userType()).toUtf8());
+ }
if (p.name == "parent")
QVERIFY(p.valueTypeName == "QGraphicsObject*" ||
@@ -248,6 +305,22 @@ void tst_QQmlEngineDebugService::recursiveObjectTest(
}
}
+void tst_QQmlEngineDebugService::getContexts()
+{
+ bool success = false;
+
+ m_dbg->queryAvailableEngines(&success);
+ QVERIFY(success);
+ QVERIFY(QQmlDebugTest::waitForSignal(m_dbg, SIGNAL(result())));
+
+ QList<QQmlEngineDebugEngineReference> engines = m_dbg->engines();
+ QCOMPARE(engines.count(), 1);
+ m_dbg->queryRootContexts(engines.first(), &success);
+
+ QVERIFY(success);
+ QVERIFY(QQmlDebugTest::waitForSignal(m_dbg, SIGNAL(result())));
+}
+
void tst_QQmlEngineDebugService::initTestCase()
{
qmlRegisterType<NonScriptProperty>("Test", 1, 0, "NonScriptPropertyElement");
@@ -329,6 +402,11 @@ void tst_QQmlEngineDebugService::initTestCase()
"CustomTypes {}"
;
+ qmlRegisterType<JsonTest>("JsonTest", 1, 0, "JsonTest");
+ qml << "import JsonTest 1.0\n"
+ "JsonTest {}"
+ ;
+
for (int i=0; i<qml.count(); i++) {
QQmlComponent component(m_engine);
component.setData(qml[i], QUrl::fromLocalFile(""));
@@ -364,7 +442,7 @@ void tst_QQmlEngineDebugService::cleanupTestCase()
void tst_QQmlEngineDebugService::setMethodBody()
{
bool success;
- QmlDebugObjectReference obj = findRootObject(2);
+ QQmlEngineDebugObjectReference obj = findRootObject(2);
QVERIFY(!obj.className.isEmpty());
QObject *root = m_components.at(2);
@@ -406,18 +484,18 @@ void tst_QQmlEngineDebugService::setMethodBody()
void tst_QQmlEngineDebugService::watch_property()
{
- QmlDebugObjectReference obj = findRootObject();
+ QQmlEngineDebugObjectReference obj = findRootObject();
QVERIFY(!obj.className.isEmpty());
- QmlDebugPropertyReference prop = findProperty(obj.properties, "width");
+ QQmlEngineDebugPropertyReference prop = findProperty(obj.properties, "width");
bool success;
- QQmlEngineDebugClient *unconnected = new QQmlEngineDebugClient(0);
+ QQmlEngineDebugClient *unconnected = new QQmlEngineDebugClient(nullptr);
unconnected->addWatch(prop, &success);
QVERIFY(!success);
delete unconnected;
- m_dbg->addWatch(QmlDebugPropertyReference(), &success);
+ m_dbg->addWatch(QQmlEngineDebugPropertyReference(), &success);
QVERIFY(success);
QVERIFY(QQmlDebugTest::waitForSignal(m_dbg, SIGNAL(result())));
QCOMPARE(m_dbg->valid(), false);
@@ -451,17 +529,17 @@ void tst_QQmlEngineDebugService::watch_property()
void tst_QQmlEngineDebugService::watch_object()
{
- QmlDebugObjectReference obj = findRootObject();
+ QQmlEngineDebugObjectReference obj = findRootObject();
QVERIFY(!obj.className.isEmpty());
bool success;
- QQmlEngineDebugClient *unconnected = new QQmlEngineDebugClient(0);
+ QQmlEngineDebugClient *unconnected = new QQmlEngineDebugClient(nullptr);
unconnected->addWatch(obj, &success);
QVERIFY(!success);
delete unconnected;
- m_dbg->addWatch(QmlDebugObjectReference(), &success);
+ m_dbg->addWatch(QQmlEngineDebugObjectReference(), &success);
QVERIFY(success);
QVERIFY(QQmlDebugTest::waitForSignal(m_dbg, SIGNAL(result())));
QCOMPARE(m_dbg->valid(), false);
@@ -517,17 +595,17 @@ void tst_QQmlEngineDebugService::watch_expression()
int origWidth = m_rootItem->property("width").toInt();
- QmlDebugObjectReference obj = findRootObject();
+ QQmlEngineDebugObjectReference obj = findRootObject();
QVERIFY(!obj.className.isEmpty());
bool success;
- QQmlEngineDebugClient *unconnected = new QQmlEngineDebugClient(0);
+ QQmlEngineDebugClient *unconnected = new QQmlEngineDebugClient(nullptr);
unconnected->addWatch(obj, expr, &success);
QVERIFY(!success);
delete unconnected;
- m_dbg->addWatch(QmlDebugObjectReference(), expr, &success);
+ m_dbg->addWatch(QQmlEngineDebugObjectReference(), expr, &success);
QVERIFY(success);
QVERIFY(QQmlDebugTest::waitForSignal(m_dbg, SIGNAL(result())));
QCOMPARE(m_dbg->valid(), false);
@@ -577,7 +655,7 @@ void tst_QQmlEngineDebugService::watch_expression_data()
void tst_QQmlEngineDebugService::watch_context()
{
- QmlDebugContextReference c;
+ QQmlEngineDebugContextReference c;
QTest::ignoreMessage(QtWarningMsg, "QQmlEngineDebugClient::addWatch(): Not implemented");
bool success;
m_dbg->addWatch(c, QString(), &success);
@@ -586,7 +664,7 @@ void tst_QQmlEngineDebugService::watch_context()
void tst_QQmlEngineDebugService::watch_file()
{
- QmlDebugFileReference f;
+ QQmlEngineDebugFileReference f;
QTest::ignoreMessage(QtWarningMsg, "QQmlEngineDebugClient::addWatch(): Not implemented");
bool success;
m_dbg->addWatch(f, &success);
@@ -597,7 +675,7 @@ void tst_QQmlEngineDebugService::queryAvailableEngines()
{
bool success;
- QQmlEngineDebugClient *unconnected = new QQmlEngineDebugClient(0);
+ QQmlEngineDebugClient *unconnected = new QQmlEngineDebugClient(nullptr);
unconnected->queryAvailableEngines(&success);
QVERIFY(!success);
delete unconnected;
@@ -607,10 +685,10 @@ void tst_QQmlEngineDebugService::queryAvailableEngines()
QVERIFY(QQmlDebugTest::waitForSignal(m_dbg, SIGNAL(result())));
// TODO test multiple engines
- QList<QmlDebugEngineReference> engines = m_dbg->engines();
+ QList<QQmlEngineDebugEngineReference> engines = m_dbg->engines();
QCOMPARE(engines.count(), 1);
- foreach (const QmlDebugEngineReference &e, engines) {
+ foreach (const QQmlEngineDebugEngineReference &e, engines) {
QCOMPARE(e.debugId, QQmlDebugService::idForObject(m_engine));
QCOMPARE(e.name, m_engine->objectName());
}
@@ -623,26 +701,26 @@ void tst_QQmlEngineDebugService::queryRootContexts()
QVERIFY(success);
QVERIFY(QQmlDebugTest::waitForSignal(m_dbg, SIGNAL(result())));
QVERIFY(m_dbg->engines().count());
- int engineId = m_dbg->engines()[0].debugId;
+ const QQmlEngineDebugEngineReference engine = m_dbg->engines()[0];
- QQmlEngineDebugClient *unconnected = new QQmlEngineDebugClient(0);
- unconnected->queryRootContexts(engineId, &success);
+ QQmlEngineDebugClient *unconnected = new QQmlEngineDebugClient(nullptr);
+ unconnected->queryRootContexts(engine, &success);
QVERIFY(!success);
delete unconnected;
- m_dbg->queryRootContexts(engineId, &success);
+ m_dbg->queryRootContexts(engine, &success);
QVERIFY(success);
QVERIFY(QQmlDebugTest::waitForSignal(m_dbg, SIGNAL(result())));
QQmlContext *actualContext = m_engine->rootContext();
- QmlDebugContextReference context = m_dbg->rootContext();
+ QQmlEngineDebugContextReference context = m_dbg->rootContext();
QCOMPARE(context.debugId, QQmlDebugService::idForObject(actualContext));
QCOMPARE(context.name, actualContext->objectName());
// root context query sends only root object data - it doesn't fill in
// the children or property info
QCOMPARE(context.objects.count(), 0);
- QCOMPARE(context.contexts.count(), 6);
+ QCOMPARE(context.contexts.count(), 7);
QVERIFY(context.contexts[0].debugId >= 0);
QCOMPARE(context.contexts[0].name, QString("tst_QQmlDebug_childContext"));
}
@@ -653,10 +731,10 @@ void tst_QQmlEngineDebugService::queryObject()
bool success;
- QmlDebugObjectReference rootObject = findRootObject();
+ QQmlEngineDebugObjectReference rootObject = findRootObject();
QVERIFY(!rootObject.className.isEmpty());
- QQmlEngineDebugClient *unconnected = new QQmlEngineDebugClient(0);
+ QQmlEngineDebugClient *unconnected = new QQmlEngineDebugClient(nullptr);
recursive ? unconnected->queryObjectRecursive(rootObject, &success) : unconnected->queryObject(rootObject, &success);
QVERIFY(!success);
delete unconnected;
@@ -665,11 +743,11 @@ void tst_QQmlEngineDebugService::queryObject()
QVERIFY(success);
QVERIFY(QQmlDebugTest::waitForSignal(m_dbg, SIGNAL(result())));
- QmlDebugObjectReference obj = m_dbg->object();
+ QQmlEngineDebugObjectReference obj = m_dbg->object();
QVERIFY(!obj.className.isEmpty());
// check source as defined in main()
- QmlDebugFileReference source = obj.source;
+ QQmlEngineDebugFileReference source = obj.source;
QCOMPARE(source.url, QUrl::fromLocalFile(""));
QCOMPARE(source.lineNumber, 3);
QCOMPARE(source.columnNumber, 1);
@@ -678,14 +756,14 @@ void tst_QQmlEngineDebugService::queryObject()
recursiveObjectTest(m_rootItem, obj, recursive);
if (recursive) {
- foreach (const QmlDebugObjectReference &child, obj.children) {
+ foreach (const QQmlEngineDebugObjectReference &child, obj.children) {
QVERIFY(!child.className.isEmpty());
QVERIFY(child.properties.count() > 0);
}
- QmlDebugObjectReference rect;
- QmlDebugObjectReference text;
- foreach (const QmlDebugObjectReference &child, obj.children) {
+ QQmlEngineDebugObjectReference rect;
+ QQmlEngineDebugObjectReference text;
+ foreach (const QQmlEngineDebugObjectReference &child, obj.children) {
QVERIFY(!child.className.isEmpty());
if (child.className == "Rectangle")
rect = child;
@@ -700,7 +778,7 @@ void tst_QQmlEngineDebugService::queryObject()
QCOMPARE(findProperty(text.properties, "color").value, qVariantFromValue(QColor("blue")));
} else {
- foreach (const QmlDebugObjectReference &child, obj.children) {
+ foreach (const QQmlEngineDebugObjectReference &child, obj.children) {
QVERIFY(!child.className.isEmpty());
QCOMPARE(child.properties.count(), 0);
}
@@ -721,14 +799,14 @@ void tst_QQmlEngineDebugService::queryObjectsForLocation()
bool success;
- QmlDebugObjectReference rootObject = findRootObject();
+ QQmlEngineDebugObjectReference rootObject = findRootObject();
QVERIFY(!rootObject.className.isEmpty());
const QString fileName = QFileInfo(rootObject.source.url.toString()).fileName();
int lineNumber = rootObject.source.lineNumber;
int columnNumber = rootObject.source.columnNumber;
- QQmlEngineDebugClient *unconnected = new QQmlEngineDebugClient(0);
+ QQmlEngineDebugClient *unconnected = new QQmlEngineDebugClient(nullptr);
recursive ? unconnected->queryObjectsForLocationRecursive(fileName, lineNumber,
columnNumber, &success)
: unconnected->queryObjectsForLocation(fileName, lineNumber,
@@ -744,11 +822,11 @@ void tst_QQmlEngineDebugService::queryObjectsForLocation()
QVERIFY(QQmlDebugTest::waitForSignal(m_dbg, SIGNAL(result())));
QCOMPARE(m_dbg->objects().count(), 1);
- QmlDebugObjectReference obj = m_dbg->objects().first();
+ QQmlEngineDebugObjectReference obj = m_dbg->objects().first();
QVERIFY(!obj.className.isEmpty());
// check source as defined in main()
- QmlDebugFileReference source = obj.source;
+ QQmlEngineDebugFileReference source = obj.source;
QCOMPARE(source.url, QUrl(fileName));
QCOMPARE(source.lineNumber, lineNumber);
QCOMPARE(source.columnNumber, columnNumber);
@@ -757,14 +835,14 @@ void tst_QQmlEngineDebugService::queryObjectsForLocation()
recursiveObjectTest(m_rootItem, obj, recursive);
if (recursive) {
- foreach (const QmlDebugObjectReference &child, obj.children) {
+ foreach (const QQmlEngineDebugObjectReference &child, obj.children) {
QVERIFY(!child.className.isEmpty());
QVERIFY(child.properties.count() > 0);
}
- QmlDebugObjectReference rect;
- QmlDebugObjectReference text;
- foreach (const QmlDebugObjectReference &child, obj.children) {
+ QQmlEngineDebugObjectReference rect;
+ QQmlEngineDebugObjectReference text;
+ foreach (const QQmlEngineDebugObjectReference &child, obj.children) {
QVERIFY(!child.className.isEmpty());
if (child.className == "Rectangle")
rect = child;
@@ -779,7 +857,7 @@ void tst_QQmlEngineDebugService::queryObjectsForLocation()
QCOMPARE(findProperty(text.properties, "color").value, qVariantFromValue(QColor("blue")));
} else {
- foreach (const QmlDebugObjectReference &child, obj.children) {
+ foreach (const QQmlEngineDebugObjectReference &child, obj.children) {
QVERIFY(!child.className.isEmpty());
QCOMPARE(child.properties.count(), 0);
}
@@ -796,7 +874,7 @@ void tst_QQmlEngineDebugService::queryObjectsForLocation_data()
void tst_QQmlEngineDebugService::regression_QTCREATORBUG_7451()
{
- QmlDebugObjectReference rootObject = findRootObject();
+ QQmlEngineDebugObjectReference rootObject = findRootObject();
QVERIFY(!rootObject.className.isEmpty());
int contextId = rootObject.contextDebugId;
QQmlContext *context = qobject_cast<QQmlContext *>(QQmlDebugService::objectForId(contextId));
@@ -823,7 +901,7 @@ void tst_QQmlEngineDebugService::regression_QTCREATORBUG_7451()
QVERIFY(success);
QVERIFY(QQmlDebugTest::waitForSignal(m_dbg, SIGNAL(result())));
- foreach (QmlDebugObjectReference child, rootObject.children) {
+ foreach (QQmlEngineDebugObjectReference child, rootObject.children) {
QVERIFY(!child.className.isEmpty());
success = false;
lineNumber = child.source.lineNumber;
@@ -846,7 +924,7 @@ void tst_QQmlEngineDebugService::regression_QTCREATORBUG_7451()
QVERIFY(success);
QVERIFY(QQmlDebugTest::waitForSignal(m_dbg, SIGNAL(result())));
- foreach (QmlDebugObjectReference child, rootObject.children) {
+ foreach (QQmlEngineDebugObjectReference child, rootObject.children) {
QVERIFY(!child.className.isEmpty());
success = false;
lineNumber = child.source.lineNumber;
@@ -862,10 +940,10 @@ void tst_QQmlEngineDebugService::queryObjectWithNonStreamableTypes()
{
bool success;
- QmlDebugObjectReference rootObject = findRootObject(4, true);
+ QQmlEngineDebugObjectReference rootObject = findRootObject(4, true);
QVERIFY(!rootObject.className.isEmpty());
- QQmlEngineDebugClient *unconnected = new QQmlEngineDebugClient(0);
+ QQmlEngineDebugClient *unconnected = new QQmlEngineDebugClient(nullptr);
unconnected->queryObject(rootObject, &success);
QVERIFY(!success);
delete unconnected;
@@ -874,12 +952,31 @@ void tst_QQmlEngineDebugService::queryObjectWithNonStreamableTypes()
QVERIFY(success);
QVERIFY(QQmlDebugTest::waitForSignal(m_dbg, SIGNAL(result())));
- QmlDebugObjectReference obj = m_dbg->object();
+ QQmlEngineDebugObjectReference obj = m_dbg->object();
QVERIFY(!obj.className.isEmpty());
- QCOMPARE(findProperty(obj.properties, "modelIndex").value, QVariant());
+ QCOMPARE(findProperty(obj.properties, "modelIndex").value,
+ QVariant(QLatin1String("QModelIndex()")));
}
+void tst_QQmlEngineDebugService::jsonData()
+{
+ bool success;
+
+ QQmlEngineDebugObjectReference rootObject = findRootObject(5, true);
+ QVERIFY(!rootObject.className.isEmpty());
+
+ m_dbg->queryObject(rootObject, &success);
+ QVERIFY(success);
+ QVERIFY(QQmlDebugTest::waitForSignal(m_dbg, SIGNAL(result())));
+
+ QQmlEngineDebugObjectReference obj = m_dbg->object();
+ QVERIFY(!obj.className.isEmpty());
+
+ QCOMPARE(findProperty(obj.properties, "data").value,
+ QJsonDocument::fromJson("{\"a\":null,\"c\":\"fffff\",\"foo\":12,\"ttt\":[4,5,4,3,2]}")
+ .toVariant());
+}
void tst_QQmlEngineDebugService::queryExpressionResult()
{
@@ -890,7 +987,7 @@ void tst_QQmlEngineDebugService::queryExpressionResult()
bool success;
- QQmlEngineDebugClient *unconnected = new QQmlEngineDebugClient(0);
+ QQmlEngineDebugClient *unconnected = new QQmlEngineDebugClient(nullptr);
unconnected->queryExpressionResult(objectId, expr, &success);
QVERIFY(!success);
delete unconnected;
@@ -938,7 +1035,7 @@ void tst_QQmlEngineDebugService::queryExpressionResultBC()
bool success;
- QQmlEngineDebugClient *unconnected = new QQmlEngineDebugClient(0);
+ QQmlEngineDebugClient *unconnected = new QQmlEngineDebugClient(nullptr);
unconnected->queryExpressionResultBC(objectId, expr, &success);
QVERIFY(!success);
delete unconnected;
@@ -968,10 +1065,10 @@ void tst_QQmlEngineDebugService::queryExpressionResultBC_data()
void tst_QQmlEngineDebugService::setBindingForObject()
{
- QmlDebugObjectReference rootObject = findRootObject();
+ QQmlEngineDebugObjectReference rootObject = findRootObject();
QVERIFY(!rootObject.className.isEmpty());
QVERIFY(rootObject.debugId != -1);
- QmlDebugPropertyReference widthPropertyRef = findProperty(rootObject.properties, "width");
+ QQmlEngineDebugPropertyReference widthPropertyRef = findProperty(rootObject.properties, "width");
QCOMPARE(widthPropertyRef.value, QVariant(10));
QCOMPARE(widthPropertyRef.binding, QString());
@@ -1016,7 +1113,7 @@ void tst_QQmlEngineDebugService::setBindingForObject()
rootObject = findRootObject();
QVERIFY(!rootObject.className.isEmpty());
QCOMPARE(rootObject.children.size(), 5); // Rectangle, Text, MouseArea, Component.onCompleted, NonScriptPropertyElement
- QmlDebugObjectReference mouseAreaObject = rootObject.children.at(2);
+ QQmlEngineDebugObjectReference mouseAreaObject = rootObject.children.at(2);
QVERIFY(!mouseAreaObject.className.isEmpty());
m_dbg->queryObjectRecursive(mouseAreaObject, &success);
QVERIFY(success);
@@ -1024,11 +1121,11 @@ void tst_QQmlEngineDebugService::setBindingForObject()
mouseAreaObject = m_dbg->object();
QCOMPARE(mouseAreaObject.className, QString("MouseArea"));
- QmlDebugPropertyReference onEnteredRef = findProperty(mouseAreaObject.properties, "onEntered");
+ QQmlEngineDebugPropertyReference onEnteredRef = findProperty(mouseAreaObject.properties, "onEntered");
QCOMPARE(onEnteredRef.name, QString("onEntered"));
// Sorry, can't do that anymore: QCOMPARE(onEnteredRef.value, QVariant("{ console.log('hello') }"));
- QCOMPARE(onEnteredRef.value, QVariant("function() { [code] }"));
+ QCOMPARE(onEnteredRef.value, QVariant("function() { [native code] }"));
m_dbg->setBindingForObject(mouseAreaObject.debugId, "onEntered",
"{console.log('hello, world') }", false,
@@ -1048,15 +1145,15 @@ void tst_QQmlEngineDebugService::setBindingForObject()
QVERIFY(!mouseAreaObject.className.isEmpty());
onEnteredRef = findProperty(mouseAreaObject.properties, "onEntered");
QCOMPARE(onEnteredRef.name, QString("onEntered"));
- QCOMPARE(onEnteredRef.value, QVariant("function() { [code] }"));
+ QCOMPARE(onEnteredRef.value, QVariant("function() { [native code] }"));
}
void tst_QQmlEngineDebugService::resetBindingForObject()
{
- QmlDebugObjectReference rootObject = findRootObject();
+ QQmlEngineDebugObjectReference rootObject = findRootObject();
QVERIFY(!rootObject.className.isEmpty());
QVERIFY(rootObject.debugId != -1);
- QmlDebugPropertyReference widthPropertyRef = findProperty(rootObject.properties, "width");
+ QQmlEngineDebugPropertyReference widthPropertyRef = findProperty(rootObject.properties, "width");
bool success = false;
@@ -1092,7 +1189,7 @@ void tst_QQmlEngineDebugService::resetBindingForObject()
rootObject = findRootObject();
QVERIFY(!rootObject.className.isEmpty());
- QmlDebugPropertyReference boldPropertyRef = findProperty(rootObject.properties, "font.bold");
+ QQmlEngineDebugPropertyReference boldPropertyRef = findProperty(rootObject.properties, "font.bold");
QCOMPARE(boldPropertyRef.value.toBool(), false);
QCOMPARE(boldPropertyRef.binding, QString());
@@ -1104,7 +1201,7 @@ void tst_QQmlEngineDebugService::setBindingInStates()
const int sourceIndex = 3;
- QmlDebugObjectReference obj = findRootObject(sourceIndex);
+ QQmlEngineDebugObjectReference obj = findRootObject(sourceIndex);
QVERIFY(!obj.className.isEmpty());
QVERIFY(obj.debugId != -1);
QVERIFY(obj.children.count() >= 2);
@@ -1137,11 +1234,11 @@ void tst_QQmlEngineDebugService::setBindingInStates()
// change the binding
- QmlDebugObjectReference state = obj.children[1];
+ QQmlEngineDebugObjectReference state = obj.children[1];
QCOMPARE(state.className, QString("State"));
QVERIFY(state.children.count() > 0);
- QmlDebugObjectReference propertyChange = state.children[0];
+ QQmlEngineDebugObjectReference propertyChange = state.children[0];
QVERIFY(!propertyChange.className.isEmpty());
QVERIFY(propertyChange.debugId != -1);
@@ -1220,51 +1317,53 @@ void tst_QQmlEngineDebugService::queryObjectTree()
{
const int sourceIndex = 3;
- QmlDebugObjectReference obj = findRootObject(sourceIndex, true);
+ QQmlEngineDebugObjectReference obj = findRootObject(sourceIndex, true);
QVERIFY(!obj.className.isEmpty());
QVERIFY(obj.debugId != -1);
QVERIFY(obj.children.count() >= 2);
// check state
- QmlDebugObjectReference state = obj.children[1];
+ QQmlEngineDebugObjectReference state = obj.children[1];
QCOMPARE(state.className, QString("State"));
QVERIFY(state.children.count() > 0);
- QmlDebugObjectReference propertyChange = state.children[0];
+ QQmlEngineDebugObjectReference propertyChange = state.children[0];
QVERIFY(!propertyChange.className.isEmpty());
QVERIFY(propertyChange.debugId != -1);
- QmlDebugPropertyReference propertyChangeTarget = findProperty(propertyChange.properties,"target");
+ QQmlEngineDebugPropertyReference propertyChangeTarget = findProperty(propertyChange.properties,"target");
QCOMPARE(propertyChangeTarget.objectDebugId, propertyChange.debugId);
- QmlDebugObjectReference targetReference = qvariant_cast<QmlDebugObjectReference>(propertyChangeTarget.value);
+ QQmlEngineDebugObjectReference targetReference = qvariant_cast<QQmlEngineDebugObjectReference>(propertyChangeTarget.value);
QVERIFY(!targetReference.className.isEmpty());
- QVERIFY(targetReference.debugId != -1);
+ QCOMPARE(targetReference.debugId, -1);
+ QCOMPARE(targetReference.name, QString("<unnamed object>"));
// check transition
- QmlDebugObjectReference transition = obj.children[0];
+ QQmlEngineDebugObjectReference transition = obj.children[0];
QCOMPARE(transition.className, QString("Transition"));
QCOMPARE(findProperty(transition.properties,"from").value.toString(), QString("*"));
QCOMPARE(findProperty(transition.properties,"to").value, findProperty(state.properties,"name").value);
QVERIFY(transition.children.count() > 0);
- QmlDebugObjectReference animation = transition.children[0];
+ QQmlEngineDebugObjectReference animation = transition.children[0];
QVERIFY(!animation.className.isEmpty());
QVERIFY(animation.debugId != -1);
- QmlDebugPropertyReference animationTarget = findProperty(animation.properties,"target");
+ QQmlEngineDebugPropertyReference animationTarget = findProperty(animation.properties,"target");
QCOMPARE(animationTarget.objectDebugId, animation.debugId);
- targetReference = qvariant_cast<QmlDebugObjectReference>(animationTarget.value);
+ targetReference = qvariant_cast<QQmlEngineDebugObjectReference>(animationTarget.value);
QVERIFY(!targetReference.className.isEmpty());
- QVERIFY(targetReference.debugId != -1);
+ QCOMPARE(targetReference.debugId, -1);
+ QCOMPARE(targetReference.name, QString("<unnamed object>"));
QCOMPARE(findProperty(animation.properties,"property").value.toString(), QString("width"));
QCOMPARE(findProperty(animation.properties,"duration").value.toInt(), 100);
}
void tst_QQmlEngineDebugService::asynchronousCreate() {
- QmlDebugObjectReference object;
+ QQmlEngineDebugObjectReference object;
auto connection = connect(m_dbg, &QQmlEngineDebugClient::newObject, this, [&](int objectId) {
object.debugId = objectId;
});
@@ -1289,6 +1388,49 @@ void tst_QQmlEngineDebugService::asynchronousCreate() {
QTRY_COMPARE(m_dbg->object().idString, QLatin1String("asyncRect"));
}
+void tst_QQmlEngineDebugService::invalidContexts()
+{
+ getContexts();
+ const int base = m_dbg->rootContext().contexts.count();
+ QQmlContext context(m_engine);
+ getContexts();
+ QCOMPARE(m_dbg->rootContext().contexts.count(), base + 1);
+ QQmlContextData *contextData = QQmlContextData::get(&context);
+ contextData->invalidate();
+ getContexts();
+ QCOMPARE(m_dbg->rootContext().contexts.count(), base);
+ QQmlContextData *rootData = QQmlContextData::get(m_engine->rootContext());
+ rootData->invalidate();
+ getContexts();
+ QCOMPARE(m_dbg->rootContext().contexts.count(), 0);
+ contextData->setParent(rootData); // makes context valid again, but not root.
+ getContexts();
+ QCOMPARE(m_dbg->rootContext().contexts.count(), 0);
+}
+
+void tst_QQmlEngineDebugService::createObjectOnDestruction()
+{
+ QSignalSpy spy(m_dbg, SIGNAL(newObject(int)));
+ {
+ QQmlEngine engine;
+ QQmlComponent component(&engine);
+ component.setData(
+ "import QtQml 2.0;"
+ "QtObject {"
+ "property Component x:"
+ "Qt.createQmlObject('import QtQml 2.0; Component { QtObject { } }',"
+ "this, 'x.qml');"
+ "Component.onDestruction: x.createObject(this, {});"
+ "}", QUrl::fromLocalFile("x.qml"));
+ QVERIFY(component.isReady());
+ QVERIFY(component.create());
+ QTRY_COMPARE(spy.count(), 2);
+ }
+ // Doesn't crash and doesn't give us another signal for the object created on destruction.
+ QTest::qWait(500);
+ QCOMPARE(spy.count(), 2);
+}
+
int main(int argc, char *argv[])
{
int _argc = argc + 1;
diff --git a/tests/auto/qml/debugger/qqmlinspector/qqmlinspector.pro b/tests/auto/qml/debugger/qqmlinspector/qqmlinspector.pro
index ee5f3c708a..0d42030b52 100644
--- a/tests/auto/qml/debugger/qqmlinspector/qqmlinspector.pro
+++ b/tests/auto/qml/debugger/qqmlinspector/qqmlinspector.pro
@@ -1,14 +1,11 @@
CONFIG += testcase
TARGET = tst_qqmlinspector
-QT += qml testlib gui-private core-private
+QT += testlib gui-private core-private
osx:CONFIG -= app_bundle
SOURCES += tst_qqmlinspector.cpp
-INCLUDEPATH += ../shared
-include(../../../shared/util.pri)
-include(../shared/qqmlinspectorclient.pri)
include(../shared/debugutil.pri)
TESTDATA = data/*
diff --git a/tests/auto/qml/debugger/qqmlinspector/tst_qqmlinspector.cpp b/tests/auto/qml/debugger/qqmlinspector/tst_qqmlinspector.cpp
index 9461922eff..6685558bb5 100644
--- a/tests/auto/qml/debugger/qqmlinspector/tst_qqmlinspector.cpp
+++ b/tests/auto/qml/debugger/qqmlinspector/tst_qqmlinspector.cpp
@@ -26,11 +26,12 @@
**
****************************************************************************/
-#include "qqmlinspectorclient.h"
#include "../shared/debugutil_p.h"
+#include "../shared/qqmldebugprocess_p.h"
#include "../../../shared/util.h"
#include <private/qqmldebugconnection_p.h>
+#include <private/qqmlinspectorclient_p.h>
#include <QtTest/qtest.h>
#include <QtTest/qsignalspy.h>
@@ -40,64 +41,32 @@
#include <QtCore/qlibraryinfo.h>
#include <QtNetwork/qhostaddress.h>
-#define STR_PORT_FROM "3772"
-#define STR_PORT_TO "3782"
-
-
-class tst_QQmlInspector : public QQmlDataTest
+class tst_QQmlInspector : public QQmlDebugTest
{
Q_OBJECT
private:
- void startQmlProcess(const QString &qmlFile, bool restrictMode = true);
+ ConnectResult startQmlProcess(const QString &qmlFile, bool restrictMode = true);
void checkAnimationSpeed(int targetMillisPerDegree);
+ QList<QQmlDebugClient *> createClients() override;
+ QQmlDebugProcess *createProcess(const QString &executable) override;
-private:
- QScopedPointer<QQmlDebugProcess> m_process;
- QScopedPointer<QQmlDebugConnection> m_connection;
- QScopedPointer<QQmlInspectorClient> m_client;
- QScopedPointer<QQmlInspectorResultRecipient> m_recipient;
+ QPointer<QQmlInspectorClient> m_client;
+ QPointer<QQmlInspectorResultRecipient> m_recipient;
private slots:
- void cleanup();
-
void connect_data();
void connect();
void setAnimationSpeed();
void showAppOnTop();
};
-void tst_QQmlInspector::startQmlProcess(const QString &qmlFile, bool restrictServices)
+QQmlDebugTest::ConnectResult tst_QQmlInspector::startQmlProcess(const QString &qmlFile,
+ bool restrictServices)
{
- const QString argument = QString::fromLatin1("-qmljsdebugger=port:%1,%2,block%3")
- .arg(STR_PORT_FROM).arg(STR_PORT_TO)
- .arg(restrictServices ? QStringLiteral(",services:QmlInspector") : QString());
-
- m_process.reset(new QQmlDebugProcess(QLibraryInfo::location(QLibraryInfo::BinariesPath) +
- "/qml"));
- // Make sure the animation timing is exact
- m_process->addEnvironment(QLatin1String("QSG_RENDER_LOOP=basic"));
- m_process->start(QStringList() << argument << testFile(qmlFile));
- QVERIFY2(m_process->waitForSessionStart(),
- "Could not launch application, or did not get 'Waiting for connection'.");
-
- m_client.reset();
- m_connection.reset(new QQmlDebugConnection);
- m_client.reset(new QQmlInspectorClient(m_connection.data()));
-
- m_recipient.reset(new QQmlInspectorResultRecipient);
- QObject::connect(m_client.data(), &QQmlInspectorClient::responseReceived,
- m_recipient.data(), &QQmlInspectorResultRecipient::recordResponse);
-
- QList<QQmlDebugClient *> others = QQmlDebugTest::createOtherClients(m_connection.data());
-
- m_connection->connectToHost(QLatin1String("127.0.0.1"), m_process->debugPort());
- QTRY_COMPARE(m_client->state(), QQmlDebugClient::Enabled);
-
- foreach (QQmlDebugClient *other, others)
- QCOMPARE(other->state(), restrictServices ? QQmlDebugClient::Unavailable :
- QQmlDebugClient::Enabled);
- qDeleteAll(others);
+ return QQmlDebugTest::connect(QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qml",
+ restrictServices ? QStringLiteral("QmlInspector") : QString(),
+ testFile(qmlFile), true);
}
void tst_QQmlInspector::checkAnimationSpeed(int targetMillisPerDegree)
@@ -114,8 +83,7 @@ void tst_QQmlInspector::checkAnimationSpeed(int targetMillisPerDegree)
QString output = m_process->output();
int position = output.length();
do {
- QVERIFY(QQmlDebugTest::waitForSignal(m_process.data(),
- SIGNAL(readyReadStandardOutput())));
+ QVERIFY(QQmlDebugTest::waitForSignal(m_process, SIGNAL(readyReadStandardOutput())));
output = m_process->output();
} while (!output.mid(position).contains(markerString));
@@ -144,12 +112,21 @@ void tst_QQmlInspector::checkAnimationSpeed(int targetMillisPerDegree)
.arg(targetMillisPerDegree).toLocal8Bit().constData());
}
-void tst_QQmlInspector::cleanup()
+QList<QQmlDebugClient *> tst_QQmlInspector::createClients()
{
- if (QTest::currentTestFailed()) {
- qDebug() << "Process State:" << m_process->state();
- qDebug() << "Application Output:" << m_process->output();
- }
+ m_client = new QQmlInspectorClient(m_connection);
+ m_recipient = new QQmlInspectorResultRecipient(m_client);
+ QObject::connect(m_client.data(), &QQmlInspectorClient::responseReceived,
+ m_recipient.data(), &QQmlInspectorResultRecipient::recordResponse);
+ return QList<QQmlDebugClient *>({m_client});
+}
+
+QQmlDebugProcess *tst_QQmlInspector::createProcess(const QString &executable)
+{
+ QQmlDebugProcess *process = QQmlDebugTest::createProcess(executable);
+ // Make sure the animation timing is exact
+ process->addEnvironment(QLatin1String("QSG_RENDER_LOOP=basic"));
+ return process;
}
void tst_QQmlInspector::connect_data()
@@ -166,7 +143,7 @@ void tst_QQmlInspector::connect()
{
QFETCH(QString, file);
QFETCH(bool, restrictMode);
- startQmlProcess(file, restrictMode);
+ QCOMPARE(startQmlProcess(file, restrictMode), ConnectSuccess);
QVERIFY(m_client);
QTRY_COMPARE(m_client->state(), QQmlDebugClient::Enabled);
@@ -181,7 +158,7 @@ void tst_QQmlInspector::connect()
void tst_QQmlInspector::showAppOnTop()
{
- startQmlProcess("qtquick2.qml");
+ QCOMPARE(startQmlProcess("qtquick2.qml"), ConnectSuccess);
QVERIFY(m_client);
QTRY_COMPARE(m_client->state(), QQmlDebugClient::Enabled);
@@ -196,7 +173,7 @@ void tst_QQmlInspector::showAppOnTop()
void tst_QQmlInspector::setAnimationSpeed()
{
- startQmlProcess("qtquick2.qml");
+ QCOMPARE(startQmlProcess("qtquick2.qml"), ConnectSuccess);
QVERIFY(m_client);
QTRY_COMPARE(m_client->state(), QQmlDebugClient::Enabled);
checkAnimationSpeed(10);
diff --git a/tests/auto/qml/debugger/qqmlnativeconnector/tst_qqmlnativeconnector.cpp b/tests/auto/qml/debugger/qqmlnativeconnector/tst_qqmlnativeconnector.cpp
index 33d3c6369f..6283a93881 100644
--- a/tests/auto/qml/debugger/qqmlnativeconnector/tst_qqmlnativeconnector.cpp
+++ b/tests/auto/qml/debugger/qqmlnativeconnector/tst_qqmlnativeconnector.cpp
@@ -113,7 +113,7 @@ int main(int argc, char *argv[])
argv2[i] = argv[i];
argv2[argc] = strdup("-qmljsdebugger=native,services:NativeQmlDebugger");
++argc;
- argv2[argc] = 0;
+ argv2[argc] = nullptr;
Application app(argc, argv2);
return QTest::qExec(&app, argc, argv);
}
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/i18n/qml_fr_FR.qm b/tests/auto/qml/debugger/qqmlpreview/data/i18n/qml_fr_FR.qm
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/auto/qml/debugger/qqmlpreview/data/i18n/qml_fr_FR.qm
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..2c27306517
--- /dev/null
+++ b/tests/auto/qml/debugger/qqmlpreview/qqmlpreview.pro
@@ -0,0 +1,25 @@
+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 \
+ data/i18n/qml_fr_FR.qm
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..4c4c514832
--- /dev/null
+++ b/tests/auto/qml/debugger/qqmlpreview/tst_qqmlpreview.cpp
@@ -0,0 +1,365 @@
+/****************************************************************************
+**
+** 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;
+ void verifyProcessOutputContains(const QString &string) const;
+
+ QPointer<QQmlPreviewClient> m_client;
+
+ QStringList m_files;
+ QStringList m_filesNotFound;
+ QStringList m_directories;
+ QStringList m_serviceErrors;
+ QQmlPreviewClient::FpsInfo m_frameStats;
+
+private slots:
+ void cleanup() final;
+
+ void connect();
+ void load();
+ void rerun();
+ void blacklist();
+ void error();
+ void zoom();
+ void fps();
+ void language();
+};
+
+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.data(), &QQmlPreviewClient::request, this, &tst_QQmlPreview::serveRequest);
+ QObject::connect(m_client.data(), &QQmlPreviewClient::error, this, [this](const QString &error) {
+ m_serviceErrors.append(error);
+ });
+ QObject::connect(m_client.data(), &QQmlPreviewClient::fps,
+ this, [this](const QQmlPreviewClient::FpsInfo &info) {
+ m_frameStats = info;
+ });
+
+ return QList<QQmlDebugClient *>({m_client});
+}
+
+void tst_QQmlPreview::verifyProcessOutputContains(const QString &string) const
+{
+ QTRY_VERIFY_WITH_TIMEOUT(m_process->output().contains(string), 30000);
+}
+
+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();
+ m_frameStats = QQmlPreviewClient::FpsInfo();
+}
+
+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)));
+ verifyProcessOutputContains(file);
+ 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)));
+ verifyProcessOutputContains("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)));
+ verifyProcessOutputContains(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("window.qml");
+ verifyProcessOutputContains(message);
+ const int pos = m_process->output().lastIndexOf(message) + message.size();
+ QVERIFY(pos >= 0);
+
+ m_client->triggerRerun();
+ QTRY_VERIFY_WITH_TIMEOUT(m_process->output().indexOf(message, pos) >= pos, 30000);
+
+ 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;
+}
+
+static void verifyZoomFactor(const QQmlDebugProcess *process, float factor)
+{
+ QTRY_VERIFY_WITH_TIMEOUT(qFuzzyCompare(parseZoomFactor(process->output()), factor), 30000);
+}
+
+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_WITH_TIMEOUT((baseZoomFactor = parseZoomFactor(m_process->output())) > 0, 30000);
+ m_client->triggerZoom(2.0f);
+ verifyZoomFactor(m_process, baseZoomFactor * 2.0f);
+ m_client->triggerZoom(1.5f);
+ verifyZoomFactor(m_process, baseZoomFactor * 1.5f);
+ m_client->triggerZoom(0.5f);
+ verifyZoomFactor(m_process, baseZoomFactor * 0.5f);
+ m_client->triggerZoom(-1.0f);
+ verifyZoomFactor(m_process, baseZoomFactor);
+ m_process->stop();
+ QVERIFY(m_serviceErrors.isEmpty());
+}
+
+void tst_QQmlPreview::fps()
+{
+ const QString file("qtquick2.qml");
+ QCOMPARE(startQmlProcess(file), ConnectSuccess);
+ QVERIFY(m_client);
+ m_client->triggerLoad(testFileUrl(file));
+ if (QGuiApplication::platformName() != "offscreen") {
+ QTRY_VERIFY(m_frameStats.numSyncs > 10);
+ QVERIFY(m_frameStats.minSync <= m_frameStats.maxSync);
+ QVERIFY(m_frameStats.totalSync / m_frameStats.numSyncs >= m_frameStats.minSync - 1);
+ QVERIFY(m_frameStats.totalSync / m_frameStats.numSyncs <= m_frameStats.maxSync);
+
+ QVERIFY(m_frameStats.numRenders > 0);
+ QVERIFY(m_frameStats.minRender <= m_frameStats.maxRender);
+ QVERIFY(m_frameStats.totalRender / m_frameStats.numRenders >= m_frameStats.minRender - 1);
+ QVERIFY(m_frameStats.totalRender / m_frameStats.numRenders <= m_frameStats.maxRender);
+ } else {
+ QSKIP("offscreen rendering doesn't produce any frames");
+ }
+}
+
+void tst_QQmlPreview::language()
+{
+ QCOMPARE(startQmlProcess("window.qml"), ConnectSuccess);
+ QVERIFY(m_client);
+ m_client->triggerLanguage(dataDirectoryUrl(), "fr_FR");
+ QTRY_VERIFY_WITH_TIMEOUT(m_files.contains(testFile("i18n/qml_fr_FR.qm")), 30000);
+}
+
+QTEST_MAIN(tst_QQmlPreview)
+
+#include "tst_qqmlpreview.moc"
diff --git a/tests/auto/qml/debugger/qqmlprofilerservice/data/batchOverflow.qml b/tests/auto/qml/debugger/qqmlprofilerservice/data/batchOverflow.qml
new file mode 100644
index 0000000000..dde1def947
--- /dev/null
+++ b/tests/auto/qml/debugger/qqmlprofilerservice/data/batchOverflow.qml
@@ -0,0 +1,20 @@
+import QtQml 2.2
+
+QtObject {
+ function iterate(dictionaryTable, j) {
+ var word = "a" + j.toString()
+ dictionaryTable[word] = null;
+ }
+
+ Component.onCompleted: {
+ var dictionaryTable = {};
+ for (var j = 0; j < 256; ++j)
+ iterate(dictionaryTable, j);
+ }
+
+ property Timer timer: Timer {
+ interval: 1
+ running: true;
+ onTriggered: Qt.quit();
+ }
+}
diff --git a/tests/auto/qml/debugger/qqmlprofilerservice/data/controlFromJS.qml b/tests/auto/qml/debugger/qqmlprofilerservice/data/controlFromJS.qml
index dd7cb2055d..4235a2d55f 100644
--- a/tests/auto/qml/debugger/qqmlprofilerservice/data/controlFromJS.qml
+++ b/tests/auto/qml/debugger/qqmlprofilerservice/data/controlFromJS.qml
@@ -43,13 +43,6 @@ QtObject {
interval: 1000
onTriggered: {
console.profileEnd();
- endTimer.start();
}
}
-
- property var endTimer: Timer {
- id: endTimer
- interval: 1000
- onTriggered: Qt.quit();
- }
}
diff --git a/tests/auto/qml/debugger/qqmlprofilerservice/data/exit.qml b/tests/auto/qml/debugger/qqmlprofilerservice/data/exit.qml
index 4236d70ea3..3b28e65174 100644
--- a/tests/auto/qml/debugger/qqmlprofilerservice/data/exit.qml
+++ b/tests/auto/qml/debugger/qqmlprofilerservice/data/exit.qml
@@ -1,7 +1,7 @@
import QtQml 2.0
QtObject {
- Timer {
+ property Timer timer: Timer {
running: true
interval: 1
onTriggered: Qt.quit();
diff --git a/tests/auto/qml/debugger/qqmlprofilerservice/data/memory.qml b/tests/auto/qml/debugger/qqmlprofilerservice/data/memory.qml
new file mode 100644
index 0000000000..f39dcdf16a
--- /dev/null
+++ b/tests/auto/qml/debugger/qqmlprofilerservice/data/memory.qml
@@ -0,0 +1,17 @@
+import QtQml 2.0
+
+Timer {
+ interval: 1
+ running: true
+
+ function recurse(i) {
+ var x = { t: [1, 2, 3, 4] }
+ console.log(x.t[i]);
+ if (i < 3)
+ recurse(i + 1);
+ else
+ Qt.quit();
+ }
+
+ onTriggered: recurse(0)
+}
diff --git a/tests/auto/qml/debugger/qqmlprofilerservice/data/qstr.qml b/tests/auto/qml/debugger/qqmlprofilerservice/data/qstr.qml
new file mode 100644
index 0000000000..09dcd34b5c
--- /dev/null
+++ b/tests/auto/qml/debugger/qqmlprofilerservice/data/qstr.qml
@@ -0,0 +1,9 @@
+import QtQml 2.0
+
+Timer {
+ property string stuff: qsTr("foo")
+
+ running: true
+ interval: 1
+ onTriggered: Qt.quit();
+}
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/qqmlprofilerservice.pro b/tests/auto/qml/debugger/qqmlprofilerservice/qqmlprofilerservice.pro
index 71a58d6f34..0cd4b331f2 100644
--- a/tests/auto/qml/debugger/qqmlprofilerservice/qqmlprofilerservice.pro
+++ b/tests/auto/qml/debugger/qqmlprofilerservice/qqmlprofilerservice.pro
@@ -4,13 +4,11 @@ osx:CONFIG -= app_bundle
SOURCES += tst_qqmlprofilerservice.cpp
-INCLUDEPATH += ../shared
-include(../../../shared/util.pri)
include(../shared/debugutil.pri)
TESTDATA = data/*
-QT += core qml testlib gui-private core-private
+QT += testlib gui-private
OTHER_FILES += \
data/pixmapCacheTest.qml \
@@ -21,4 +19,7 @@ OTHER_FILES += \
data/TestImage_2x2.png \
data/signalSourceLocation.qml \
data/javascript.qml \
- data/timer.qml
+ data/timer.qml \
+ data/qstr.qml \
+ data/memory.qml \
+ data/batchOverflow.qml
diff --git a/tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp b/tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp
index 692e70d7da..085eb7b87a 100644
--- a/tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp
+++ b/tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp
@@ -27,254 +27,160 @@
****************************************************************************/
#include "debugutil_p.h"
+#include "qqmldebugprocess_p.h"
#include "../../../shared/util.h"
#include <private/qqmlprofilerclient_p.h>
#include <private/qqmldebugconnection_p.h>
#include <QtTest/qtest.h>
+#include <QtTest/qsignalspy.h>
#include <QtCore/qlibraryinfo.h>
-#define STR_PORT_FROM "13773"
-#define STR_PORT_TO "13783"
+#include <QtGui/private/qguiapplication_p.h>
+#include <QtGui/qpa/qplatformintegration.h>
-struct QQmlProfilerData
-{
- QQmlProfilerData(qint64 time = -2, int messageType = -1, int detailType = -1,
- const QString &detailData = QString()) :
- time(time), messageType(messageType), detailType(detailType), detailData(detailData),
- line(-1), column(-1), framerate(-1), animationcount(-1), amount(-1)
- {}
-
- qint64 time;
- int messageType;
- int detailType;
-
- //###
- QString detailData; //used by RangeData and RangeLocation
- int line; //used by RangeLocation
- int column; //used by RangeLocation
- int framerate; //used by animation events
- int animationcount; //used by animation events
- qint64 amount; //used by heap events
-};
-
-class QQmlProfilerTestClient : public QQmlProfilerClient
+class QQmlProfilerTestClient : public QQmlProfilerEventReceiver
{
Q_OBJECT
public:
- QQmlProfilerTestClient(QQmlDebugConnection *connection) : QQmlProfilerClient(connection),
- lastTimestamp(-1) {}
+ QQmlProfilerTestClient(QQmlDebugConnection *connection) :
+ client(new QQmlProfilerClient(connection, this))
+ {
+ connect(client.data(), &QQmlProfilerClient::traceStarted,
+ this, &QQmlProfilerTestClient::startTrace);
+ connect(client.data(), &QQmlProfilerClient::traceFinished,
+ this, &QQmlProfilerTestClient::endTrace);
+ }
+
+ void startTrace(qint64 timestamp, const QList<int> &engineIds);
+ void endTrace(qint64 timestamp, const QList<int> &engineIds);
- QVector<QQmlProfilerData> qmlMessages;
- QVector<QQmlProfilerData> javascriptMessages;
- QVector<QQmlProfilerData> jsHeapMessages;
- QVector<QQmlProfilerData> asynchronousMessages;
- QVector<QQmlProfilerData> pixmapMessages;
+ QPointer<QQmlProfilerClient> client; // Owned by QQmlDebugTest
+ QVector<QQmlProfilerEventType> types;
- qint64 lastTimestamp;
+ QVector<QQmlProfilerEvent> qmlMessages;
+ QVector<QQmlProfilerEvent> javascriptMessages;
+ QVector<QQmlProfilerEvent> jsHeapMessages;
+ QVector<QQmlProfilerEvent> asynchronousMessages;
+ QVector<QQmlProfilerEvent> pixmapMessages;
-signals:
- void recordingFinished();
+ int numLoadedEventTypes() const override;
+ void addEventType(const QQmlProfilerEventType &type) override;
+ void addEvent(const QQmlProfilerEvent &event) override;
private:
- void traceStarted(qint64 time, int engineId);
- void traceFinished(qint64 time, int engineId);
- void rangeStart(QQmlProfilerDefinitions::RangeType type, qint64 startTime);
- void rangeData(QQmlProfilerDefinitions::RangeType type, qint64 time, const QString &data);
- void rangeLocation(QQmlProfilerDefinitions::RangeType type, qint64 time,
- const QQmlEventLocation &location);
- void rangeEnd(QQmlProfilerDefinitions::RangeType type, qint64 endTime);
- void animationFrame(qint64 time, int frameRate, int animationCount, int threadId);
- void sceneGraphEvent(QQmlProfilerDefinitions::SceneGraphFrameType type, qint64 time,
- qint64 numericData1, qint64 numericData2, qint64 numericData3,
- qint64 numericData4, qint64 numericData5);
- void pixmapCacheEvent(QQmlProfilerDefinitions::PixmapEventType type, qint64 time,
- const QString &url, int numericData1, int numericData2);
- void memoryAllocation(QQmlProfilerDefinitions::MemoryType type, qint64 time, qint64 amount);
- void inputEvent(QQmlProfilerDefinitions::InputEventType type, qint64 time, int a, int b);
- void complete();
-
- void unknownEvent(QQmlProfilerDefinitions::Message messageType, qint64 time, int detailType);
- void unknownData(QPacket &stream);
+ qint64 lastTimestamp = -1;
};
-void QQmlProfilerTestClient::traceStarted(qint64 time, int engineId)
+void QQmlProfilerTestClient::startTrace(qint64 timestamp, const QList<int> &engineIds)
{
- asynchronousMessages.append(QQmlProfilerData(time, QQmlProfilerDefinitions::Event,
- QQmlProfilerDefinitions::StartTrace,
- QString::number(engineId)));
+ types.append(QQmlProfilerEventType(Event, MaximumRangeType, StartTrace));
+ asynchronousMessages.append(QQmlProfilerEvent(timestamp, types.length() - 1,
+ engineIds.toVector()));
}
-void QQmlProfilerTestClient::traceFinished(qint64 time, int engineId)
+void QQmlProfilerTestClient::endTrace(qint64 timestamp, const QList<int> &engineIds)
{
- asynchronousMessages.append(QQmlProfilerData(time, QQmlProfilerDefinitions::Event,
- QQmlProfilerDefinitions::EndTrace,
- QString::number(engineId)));
+ types.append(QQmlProfilerEventType(Event, MaximumRangeType, EndTrace));
+ asynchronousMessages.append(QQmlProfilerEvent(timestamp, types.length() - 1,
+ engineIds.toVector()));
}
-void QQmlProfilerTestClient::rangeStart(QQmlProfilerDefinitions::RangeType type, qint64 startTime)
+int QQmlProfilerTestClient::numLoadedEventTypes() const
{
- QVERIFY(type >= 0 && type < QQmlProfilerDefinitions::MaximumRangeType);
- QVERIFY(lastTimestamp <= startTime);
- lastTimestamp = startTime;
- QQmlProfilerData data(startTime, QQmlProfilerDefinitions::RangeStart, type);
- if (type == QQmlProfilerDefinitions::Javascript)
- javascriptMessages.append(data);
- else
- qmlMessages.append(data);
+ return types.length();
}
-void QQmlProfilerTestClient::rangeData(QQmlProfilerDefinitions::RangeType type, qint64 time,
- const QString &string)
+void QQmlProfilerTestClient::addEventType(const QQmlProfilerEventType &type)
{
- QVERIFY(type >= 0 && type < QQmlProfilerDefinitions::MaximumRangeType);
- QVERIFY(lastTimestamp <= time);
- lastTimestamp = time;
- QQmlProfilerData data(time, QQmlProfilerDefinitions::RangeData, type, string);
- if (type == QQmlProfilerDefinitions::Javascript)
- javascriptMessages.append(data);
- else
- qmlMessages.append(data);
+ types.append(type);
}
-void QQmlProfilerTestClient::rangeLocation(QQmlProfilerDefinitions::RangeType type, qint64 time,
- const QQmlEventLocation &location)
+void QQmlProfilerTestClient::addEvent(const QQmlProfilerEvent &event)
{
- QVERIFY(type >= 0 && type < QQmlProfilerDefinitions::MaximumRangeType);
- QVERIFY(location.line >= -2);
- QVERIFY(lastTimestamp <= time);
- lastTimestamp = time;
- QQmlProfilerData data(time, QQmlProfilerDefinitions::RangeLocation, type, location.filename);
- data.line = location.line;
- data.column = location.column;
- if (type == QQmlProfilerDefinitions::Javascript)
- javascriptMessages.append(data);
- else
- qmlMessages.append(data);
-}
+ const int typeIndex = event.typeIndex();
+ QVERIFY(typeIndex < types.length());
-void QQmlProfilerTestClient::rangeEnd(QQmlProfilerDefinitions::RangeType type, qint64 endTime)
-{
- QVERIFY(type >= 0 && type < QQmlProfilerDefinitions::MaximumRangeType);
- QVERIFY(lastTimestamp <= endTime);
- lastTimestamp = endTime;
- QQmlProfilerData data(endTime, QQmlProfilerDefinitions::RangeEnd, type);
- if (type == QQmlProfilerDefinitions::Javascript)
- javascriptMessages.append(data);
- else
- qmlMessages.append(data);
-}
+ const QQmlProfilerEventType &type = types[typeIndex];
-void QQmlProfilerTestClient::animationFrame(qint64 time, int frameRate, int animationCount, int threadId)
-{
- QVERIFY(threadId >= 0);
- QVERIFY(frameRate != -1);
- QVERIFY(animationCount != -1);
- QVERIFY(lastTimestamp <= time);
- lastTimestamp = time;
- QQmlProfilerData data(time, QQmlProfilerDefinitions::Event,
- QQmlProfilerDefinitions::AnimationFrame);
- data.framerate = frameRate;
- data.animationcount = animationCount;
- asynchronousMessages.append(data);
-}
+ QVERIFY(event.timestamp() >= lastTimestamp);
+ lastTimestamp = event.timestamp();
-void QQmlProfilerTestClient::sceneGraphEvent(QQmlProfilerDefinitions::SceneGraphFrameType type,
- qint64 time, qint64 numericData1, qint64 numericData2,
- qint64 numericData3, qint64 numericData4,
- qint64 numericData5)
-{
- Q_UNUSED(numericData1);
- Q_UNUSED(numericData2);
- Q_UNUSED(numericData3);
- Q_UNUSED(numericData4);
- Q_UNUSED(numericData5);
- QVERIFY(lastTimestamp <= time);
- lastTimestamp = time;
- asynchronousMessages.append(QQmlProfilerData(time, QQmlProfilerDefinitions::SceneGraphFrame,
- type));
-}
-
-void QQmlProfilerTestClient::pixmapCacheEvent(QQmlProfilerDefinitions::PixmapEventType type,
- qint64 time, const QString &url, int numericData1,
- int numericData2)
-{
- QVERIFY(lastTimestamp <= time);
- lastTimestamp = time;
- QQmlProfilerData data(time, QQmlProfilerDefinitions::PixmapCacheEvent, type, url);
- switch (type) {
- case QQmlProfilerDefinitions::PixmapSizeKnown:
- data.line = numericData1;
- data.column = numericData2;
+ switch (type.message()) {
+ case Event: {
+ switch (type.detailType()) {
+ case StartTrace:
+ QFAIL("StartTrace should not be passed on as event");
+ break;
+ case EndTrace:
+ QFAIL("EndTrace should not be passed on as event");
+ break;
+ case AnimationFrame:
+ asynchronousMessages.append(event);
+ break;
+ case Mouse:
+ case Key:
+ qmlMessages.append(event);
+ break;
+ default:
+ QFAIL(qPrintable(QString::fromLatin1("Event with unknown detailType %1 received at %2.")
+ .arg(type.detailType()).arg(event.timestamp())));
+ break;
+ }
+ break;
+ }
+ case RangeStart:
+ case RangeData:
+ case RangeLocation:
+ case RangeEnd:
+ QFAIL("Range stages are transmitted as part of events");
+ break;
+ case Complete:
+ QFAIL("Complete should not be passed on as event");
+ break;
+ case PixmapCacheEvent:
+ pixmapMessages.append(event);
break;
- case QQmlProfilerDefinitions::PixmapReferenceCountChanged:
- case QQmlProfilerDefinitions::PixmapCacheCountChanged:
- data.animationcount = numericData1;
+ case SceneGraphFrame:
+ asynchronousMessages.append(event);
break;
- default:
+ case MemoryAllocation:
+ jsHeapMessages.append(event);
+ break;
+ case DebugMessage:
+ // Unhandled
+ break;
+ case MaximumMessage:
+ switch (type.rangeType()) {
+ case Painting:
+ QFAIL("QtQuick1 paint message received.");
+ break;
+ case Compiling:
+ case Creating:
+ case Binding:
+ case HandlingSignal:
+ qmlMessages.append(event);
+ break;
+ case Javascript:
+ javascriptMessages.append(event);
+ break;
+ default:
+ QFAIL(qPrintable(
+ QString::fromLatin1("Unknown range event %1 received at %2.")
+ .arg(type.rangeType()).arg(event.timestamp())));
+ break;
+ }
break;
}
- pixmapMessages.append(data);
-}
-
-void QQmlProfilerTestClient::memoryAllocation(QQmlProfilerDefinitions::MemoryType type, qint64 time,
- qint64 amount)
-{
- QVERIFY(lastTimestamp <= time);
- lastTimestamp = time;
- QQmlProfilerData data(time, QQmlProfilerDefinitions::MemoryAllocation, type);
- data.amount = amount;
- jsHeapMessages.append(data);
}
-void QQmlProfilerTestClient::inputEvent(QQmlProfilerDefinitions::InputEventType type, qint64 time,
- int a, int b)
-{
- QVERIFY(lastTimestamp <= time);
- lastTimestamp = time;
- qmlMessages.append(QQmlProfilerData(time, QQmlProfilerDefinitions::Event, type,
- QString::number(a) + QLatin1Char('x') +
- QString::number(b)));
-}
-
-void QQmlProfilerTestClient::unknownEvent(QQmlProfilerDefinitions::Message messageType, qint64 time,
- int detailType)
-{
- QFAIL(qPrintable(QString::fromLatin1("Unknown event %1 with detail type %2 received at %3.")
- .arg(messageType).arg(detailType).arg(time)));
-}
-
-void QQmlProfilerTestClient::unknownData(QPacket &stream)
-{
- QFAIL(qPrintable(QString::fromLatin1("%1 bytes of extra data after receiving message.")
- .arg(stream.device()->bytesAvailable())));
-}
-
-void QQmlProfilerTestClient::complete()
-{
- emit recordingFinished();
-}
-
-class tst_QQmlProfilerService : public QQmlDataTest
+class tst_QQmlProfilerService : public QQmlDebugTest
{
Q_OBJECT
-public:
- tst_QQmlProfilerService()
- : m_process(0)
- , m_connection(0)
- , m_client(0)
- {
- }
-
-
private:
- QQmlDebugProcess *m_process;
- QQmlDebugConnection *m_connection;
- QQmlProfilerTestClient *m_client;
-
enum MessageListType {
MessageListQML,
MessageListJavaScript,
@@ -289,18 +195,28 @@ private:
CheckLine = 1 << 2,
CheckColumn = 1 << 3,
CheckDataEndsWith = 1 << 4,
+ CheckFileEndsWith = 1 << 5,
+ CheckNumbers = 1 << 6,
- CheckAll = CheckMessageType | CheckDetailType | CheckLine | CheckColumn | CheckDataEndsWith
+ CheckType = CheckMessageType | CheckDetailType | CheckLine | CheckColumn | CheckFileEndsWith
};
- void connect(bool block, const QString &testFile, bool restrictServices = true);
+ ConnectResult connect(bool block, const QString &file, bool recordFromStart = true,
+ uint flushInterval = 0, bool restrictServices = true,
+ const QString &executable
+ = QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene");
+ void checkProcessTerminated();
void checkTraceReceived();
void checkJsHeap();
- bool verify(MessageListType type, int expectedPosition, const QQmlProfilerData &expected,
- quint32 checks);
+ bool verify(MessageListType type, int expectedPosition,
+ const QQmlProfilerEventType &expected, quint32 checks,
+ const QVector<qint64> &expectedNumbers);
+
+ QList<QQmlDebugClient *> createClients() override;
+ QScopedPointer<QQmlProfilerTestClient> m_client;
private slots:
- void cleanup();
+ void cleanup() override;
void connect_data();
void connect();
@@ -311,58 +227,75 @@ private slots:
void signalSourceLocation();
void javascript();
void flushInterval();
+ void translationBinding();
+ void memory();
+ void compile();
+ void multiEngine();
+ void batchOverflow();
+
+private:
+ bool m_recordFromStart = true;
+ bool m_flushInterval = false;
+ bool m_isComplete = false;
+
+ // Don't use ({...}) here as MSVC will interpret that as the "QVector(int size)" ctor.
+ const QVector<qint64> m_rangeStart = (QVector<qint64>() << RangeStart);
+ const QVector<qint64> m_rangeEnd = (QVector<qint64>() << RangeEnd);
};
-#define VERIFY(type, position, expected, checks) QVERIFY(verify(type, position, expected, checks))
+#define VERIFY(type, position, expected, checks, numbers) \
+ QVERIFY(verify(type, position, expected, checks, numbers))
-void tst_QQmlProfilerService::connect(bool block, const QString &testFile, bool restrictServices)
+QQmlDebugTest::ConnectResult tst_QQmlProfilerService::connect(
+ bool block, const QString &file, bool recordFromStart, uint flushInterval,
+ bool restrictServices, const QString &executable)
{
+ m_recordFromStart = recordFromStart;
+ m_flushInterval = flushInterval;
+ m_isComplete = false;
+
// ### Still using qmlscene due to QTBUG-33377
- const QString executable = QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene";
- QStringList arguments;
- arguments << QString::fromLatin1("-qmljsdebugger=port:%1,%2%3%4")
- .arg(STR_PORT_FROM).arg(STR_PORT_TO)
- .arg(block ? QStringLiteral(",block") : QString())
- .arg(restrictServices ? QStringLiteral(",services:CanvasFrameRate") : QString())
- << QQmlDataTest::instance()->testFile(testFile);
-
- m_process = new QQmlDebugProcess(executable, this);
- m_process->start(QStringList() << arguments);
- QVERIFY2(m_process->waitForSessionStart(), "Could not launch application, or did not get 'Waiting for connection'.");
-
- m_connection = new QQmlDebugConnection();
- m_client = new QQmlProfilerTestClient(m_connection);
- QList<QQmlDebugClient *> others = QQmlDebugTest::createOtherClients(m_connection);
-
- const int port = m_process->debugPort();
- m_connection->connectToHost(QLatin1String("127.0.0.1"), port);
- QVERIFY(m_client);
- QTRY_COMPARE(m_client->state(), QQmlDebugClient::Enabled);
+ return QQmlDebugTest::connect(
+ executable,
+ restrictServices ? "CanvasFrameRate,EngineControl,DebugMessages" : QString(),
+ testFile(file), block);
+}
- foreach (QQmlDebugClient *other, others)
- QCOMPARE(other->state(), restrictServices ? QQmlDebugClient::Unavailable :
- QQmlDebugClient::Enabled);
- qDeleteAll(others);
+void tst_QQmlProfilerService::checkProcessTerminated()
+{
+ // If the process ends before connect(), we get a non-success value from connect()
+ // That's not a problem as we will still receive the trace. We check that process has terminated
+ // cleanly here.
+
+ // Wait for the process to finish by itself, if that hasn't happened already
+ QVERIFY(m_client);
+ 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()
{
- QVERIFY2(QQmlDebugTest::waitForSignal(m_client, SIGNAL(recordingFinished())),
- "No trace received in time.");
+ QVERIFY(m_process->exitStatus() != QProcess::CrashExit);
+ QTRY_VERIFY2(m_isComplete, "No trace received in time.");
+
+ QVector<qint64> numbers;
// must start with "StartTrace"
- QQmlProfilerData expected(0, QQmlProfilerDefinitions::Event,
- QQmlProfilerDefinitions::StartTrace);
- VERIFY(MessageListAsynchronous, 0, expected, CheckMessageType | CheckDetailType);
+ QQmlProfilerEventType expected(Event, MaximumRangeType, StartTrace);
+ VERIFY(MessageListAsynchronous, 0, expected, CheckMessageType | CheckDetailType, numbers);
// must end with "EndTrace"
- expected.detailType = QQmlProfilerDefinitions::EndTrace;
+ expected = QQmlProfilerEventType(Event, MaximumRangeType, EndTrace);
VERIFY(MessageListAsynchronous, m_client->asynchronousMessages.length() - 1, expected,
- CheckMessageType | CheckDetailType);
+ CheckMessageType | CheckDetailType, numbers);
}
void tst_QQmlProfilerService::checkJsHeap()
{
+ QVERIFY(m_client);
QVERIFY2(m_client->jsHeapMessages.count() > 0, "no JavaScript heap messages received");
bool seen_alloc = false;
@@ -371,33 +304,36 @@ void tst_QQmlProfilerService::checkJsHeap()
qint64 allocated = 0;
qint64 used = 0;
qint64 lastTimestamp = -1;
- foreach (const QQmlProfilerData &message, m_client->jsHeapMessages) {
- switch (message.detailType) {
- case QV4::Profiling::HeapPage:
- allocated += message.amount;
+ foreach (const QQmlProfilerEvent &message, m_client->jsHeapMessages) {
+ const auto amount = message.number<qint64>(0);
+ const QQmlProfilerEventType &type = m_client->types.at(message.typeIndex());
+ switch (type.detailType()) {
+ case HeapPage:
+ allocated += amount;
seen_alloc = true;
break;
- case QV4::Profiling::SmallItem:
- used += message.amount;
+ case SmallItem:
+ used += amount;
seen_small = true;
break;
- case QV4::Profiling::LargeItem:
- allocated += message.amount;
- used += message.amount;
+ case LargeItem:
+ allocated += amount;
+ used += amount;
seen_large = true;
break;
}
- QVERIFY(message.time >= lastTimestamp);
+ QVERIFY(message.timestamp() >= lastTimestamp);
// The heap will only be consistent after all events of the same timestamp are processed.
if (lastTimestamp == -1) {
- lastTimestamp = message.time;
- continue;
- } else if (message.time == lastTimestamp) {
+ lastTimestamp = message.timestamp();
continue;
}
- lastTimestamp = message.time;
+ if (message.timestamp() == lastTimestamp)
+ continue;
+
+ lastTimestamp = message.timestamp();
QVERIFY2(used >= 0, QString::fromLatin1("Negative memory usage seen: %1")
.arg(used).toUtf8().constData());
@@ -416,10 +352,15 @@ void tst_QQmlProfilerService::checkJsHeap()
}
bool tst_QQmlProfilerService::verify(tst_QQmlProfilerService::MessageListType type,
- int expectedPosition, const QQmlProfilerData &expected,
- quint32 checks)
+ int expectedPosition, const QQmlProfilerEventType &expected,
+ quint32 checks, const QVector<qint64> &expectedNumbers)
{
- QVector<QQmlProfilerData> *target = 0;
+ if (!m_client) {
+ qWarning() << "No debug client available";
+ return false;
+ }
+
+ const QVector<QQmlProfilerEvent> *target = nullptr;
switch (type) {
case MessageListQML: target = &(m_client->qmlMessages); break;
case MessageListJavaScript: target = &(m_client->javascriptMessages); break;
@@ -428,48 +369,93 @@ 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();
return false;
}
- uint position = expectedPosition;
- qint64 timestamp = target->at(expectedPosition).time;
- while (position > 0 && target->at(position - 1).time == timestamp)
+ int position = expectedPosition;
+ qint64 timestamp = target->at(expectedPosition).timestamp();
+ while (position > 0 && target->at(position - 1).timestamp() == timestamp)
--position;
QStringList warnings;
do {
- const QQmlProfilerData &actual = target->at(position);
- if ((checks & CheckMessageType) && actual.messageType != expected.messageType) {
- warnings << QString::fromLatin1("%1: unexpected messageType. actual: %2 - expected: %3")
- .arg(position).arg(actual.messageType).arg(expected.messageType);
+ const QQmlProfilerEvent &event = target->at(position);
+ const QQmlProfilerEventType &actual = m_client->types.at(event.typeIndex());
+ if ((checks & CheckMessageType) &&
+ (actual.message() != expected.message()
+ || actual.rangeType() != expected.rangeType())) {
+ warnings << QString::fromLatin1("%1: unexpected messageType or rangeType. "
+ "actual: %2, %3 - expected: %4, %5")
+ .arg(position).arg(actual.message()).arg(actual.rangeType())
+ .arg(expected.message()).arg(expected.rangeType());
continue;
}
- if ((checks & CheckDetailType) && actual.detailType != expected.detailType) {
+ if ((checks & CheckDetailType) && actual.detailType() != expected.detailType()) {
warnings << QString::fromLatin1("%1: unexpected detailType. actual: %2 - expected: %3")
- .arg(position).arg(actual.detailType).arg(expected.detailType);
+ .arg(position).arg(actual.detailType()).arg(expected.detailType());
continue;
}
- if ((checks & CheckLine) && actual.line != expected.line) {
+
+ const QQmlProfilerEventLocation expectedLocation = expected.location();
+ const QQmlProfilerEventLocation actualLocation = actual.location();
+
+ if ((checks & CheckLine) && actualLocation.line() != expectedLocation.line()) {
warnings << QString::fromLatin1("%1: unexpected line. actual: %2 - expected: %3")
- .arg(position).arg(actual.line).arg(expected.line);
+ .arg(position).arg(actualLocation.line())
+ .arg(expectedLocation.line());
continue;
}
- if ((checks & CheckColumn) && actual.column != expected.column) {
+ if ((checks & CheckColumn) && actualLocation.column() != expectedLocation.column()) {
warnings << QString::fromLatin1("%1: unexpected column. actual: %2 - expected: %3")
- .arg(position).arg(actual.column).arg(expected.column);
+ .arg(position).arg(actualLocation.column())
+ .arg(expectedLocation.column());
continue;
}
- if ((checks & CheckDataEndsWith) && !actual.detailData.endsWith(expected.detailData)) {
+ if ((checks & CheckFileEndsWith) &&
+ !actualLocation.filename().endsWith(expectedLocation.filename())) {
+ warnings << QString::fromLatin1("%1: unexpected fileName. actual: %2 - expected: %3")
+ .arg(position).arg(actualLocation.filename())
+ .arg(expectedLocation.filename());
+ continue;
+ }
+
+ if ((checks & CheckDataEndsWith) && !actual.data().endsWith(expected.data())) {
warnings << QString::fromLatin1("%1: unexpected detailData. actual: %2 - expected: %3")
- .arg(position).arg(actual.detailData).arg(expected.detailData);
+ .arg(position).arg(actual.data()).arg(expected.data());
continue;
}
+
+ if (checks & CheckNumbers) {
+ const QVector<qint64> actualNumbers = event.numbers<QVector<qint64>>();
+ if (actualNumbers != expectedNumbers) {
+
+ QStringList expectedList;
+ for (qint64 number : expectedNumbers)
+ expectedList.append(QString::number(number));
+ QStringList actualList;
+ for (qint64 number : actualNumbers)
+ actualList.append(QString::number(number));
+
+ warnings << QString::fromLatin1(
+ "%1: unexpected numbers. actual [%2] - expected: [%3]")
+ .arg(position)
+ .arg(actualList.join(QLatin1String(", ")))
+ .arg(expectedList.join(QLatin1String(", ")));
+ continue;
+ }
+ }
+
return true;
- } while (target->at(++position).time == timestamp);
+ } while (++position < target->length() && target->at(position).timestamp() == timestamp);
foreach (const QString &message, warnings)
qWarning() << message.toLocal8Bit().constData();
@@ -477,54 +463,62 @@ bool tst_QQmlProfilerService::verify(tst_QQmlProfilerService::MessageListType ty
return false;
}
+QList<QQmlDebugClient *> tst_QQmlProfilerService::createClients()
+{
+ m_client.reset(new QQmlProfilerTestClient(m_connection));
+ m_client->client->setRecording(m_recordFromStart);
+ m_client->client->setFlushInterval(m_flushInterval);
+ QObject::connect(m_client->client.data(), &QQmlProfilerClient::complete,
+ this, [this](){ m_isComplete = true; });
+ return QList<QQmlDebugClient *>({m_client->client});
+}
+
void tst_QQmlProfilerService::cleanup()
{
+ auto log = [this](const QQmlProfilerEvent &data, int i) {
+ const QQmlProfilerEventType &type = m_client->types.at(data.typeIndex());
+ const QQmlProfilerEventLocation location = type.location();
+ qDebug() << i << data.timestamp() << type.message() << type.rangeType() << type.detailType()
+ << location.filename() << location.line() << location.column()
+ << data.numbers<QVector<qint64>>();
+ };
+
if (m_client && QTest::currentTestFailed()) {
qDebug() << "QML Messages:" << m_client->qmlMessages.count();
int i = 0;
- foreach (const QQmlProfilerData &data, m_client->qmlMessages) {
- qDebug() << i++ << data.time << data.messageType << data.detailType << data.detailData
- << data.line << data.column;
- }
+ for (const QQmlProfilerEvent &data : qAsConst(m_client->qmlMessages))
+ log(data, i++);
+
qDebug() << " ";
qDebug() << "JavaScript Messages:" << m_client->javascriptMessages.count();
i = 0;
- foreach (const QQmlProfilerData &data, m_client->javascriptMessages) {
- qDebug() << i++ << data.time << data.messageType << data.detailType << data.detailData
- << data.line << data.column;
- }
+
+ for (const QQmlProfilerEvent &data : qAsConst(m_client->javascriptMessages))
+ log(data, i++);
+
qDebug() << " ";
qDebug() << "Asynchronous Messages:" << m_client->asynchronousMessages.count();
i = 0;
- foreach (const QQmlProfilerData &data, m_client->asynchronousMessages) {
- qDebug() << i++ << data.time << data.messageType << data.detailType << data.detailData
- << data.framerate << data.animationcount << data.line << data.column;
- }
+ for (const QQmlProfilerEvent &data : qAsConst(m_client->asynchronousMessages))
+ log(data, i++);
+
qDebug() << " ";
qDebug() << "Pixmap Cache Messages:" << m_client->pixmapMessages.count();
i = 0;
- foreach (const QQmlProfilerData &data, m_client->pixmapMessages) {
- qDebug() << i++ << data.time << data.messageType << data.detailType << data.detailData
- << data.line << data.column;
- }
+ for (const QQmlProfilerEvent &data : qAsConst(m_client->pixmapMessages))
+ log(data, i++);
+
qDebug() << " ";
qDebug() << "Javascript Heap Messages:" << m_client->jsHeapMessages.count();
i = 0;
- foreach (const QQmlProfilerData &data, m_client->jsHeapMessages) {
- qDebug() << i++ << data.time << data.messageType << data.detailType;
- }
+ for (const QQmlProfilerEvent &data : qAsConst(m_client->jsHeapMessages))
+ log(data, i++);
+
qDebug() << " ";
- qDebug() << "Process State:" << (m_process ? m_process->state() : QLatin1String("null"));
- qDebug() << "Application Output:" << (m_process ? m_process->output() : QLatin1String("null"));
- qDebug() << "Connection State:" << QQmlDebugTest::connectionStateString(m_connection);
- qDebug() << "Client State:" << QQmlDebugTest::clientStateString(m_client);
}
- delete m_process;
- m_process = 0;
- delete m_client;
- m_client = 0;
- delete m_connection;
- m_connection = 0;
+
+ m_client.reset();
+ QQmlDebugTest::cleanup();
}
void tst_QQmlProfilerService::connect_data()
@@ -548,63 +542,63 @@ void tst_QQmlProfilerService::connect()
QFETCH(bool, restrictMode);
QFETCH(bool, traceEnabled);
- connect(blockMode, "test.qml", restrictMode);
+ QCOMPARE(connect(blockMode, "test.qml", traceEnabled, 0, restrictMode), ConnectSuccess);
- // if the engine is waiting, then the first message determines if it starts with trace enabled
if (!traceEnabled)
- m_client->sendRecordingStatus(false);
- m_client->sendRecordingStatus(true);
- m_client->sendRecordingStatus(false);
+ m_client->client->setRecording(true);
+
+ QTRY_VERIFY(m_client->numLoadedEventTypes() > 0);
+ m_client->client->setRecording(false);
checkTraceReceived();
checkJsHeap();
}
void tst_QQmlProfilerService::pixmapCacheData()
{
- connect(true, "pixmapCacheTest.qml");
- m_client->sendRecordingStatus(true);
- QVERIFY(QQmlDebugTest::waitForSignal(m_process, SIGNAL(readyReadStandardOutput())));
+ QCOMPARE(connect(true, "pixmapCacheTest.qml"), ConnectSuccess);
+ // Don't wait for readyReadStandardOutput before the loop. It may have already arrived.
while (m_process->output().indexOf(QLatin1String("image loaded")) == -1 &&
m_process->output().indexOf(QLatin1String("image error")) == -1)
QVERIFY(QQmlDebugTest::waitForSignal(m_process, SIGNAL(readyReadStandardOutput())));
- m_client->sendRecordingStatus(false);
+ m_client->client->setRecording(false);
checkTraceReceived();
checkJsHeap();
- QQmlProfilerData expected(0, QQmlProfilerDefinitions::PixmapCacheEvent);
+ auto createType = [](PixmapEventType type) {
+ return QQmlProfilerEventType(PixmapCacheEvent, MaximumRangeType, type);
+ };
+
+ QVector<qint64> numbers;
// image starting to load
- expected.detailType = QQmlProfilerDefinitions::PixmapLoadingStarted;
- VERIFY(MessageListPixmap, 0, expected, CheckMessageType | CheckDetailType);
+ VERIFY(MessageListPixmap, 0, createType(PixmapLoadingStarted),
+ CheckMessageType | CheckDetailType, numbers);
// image size
- expected.detailType = QQmlProfilerDefinitions::PixmapSizeKnown;
- expected.line = expected.column = 2; // width and height, in fact
- VERIFY(MessageListPixmap, 1, expected,
- CheckMessageType | CheckDetailType | CheckLine | CheckColumn);
+ numbers = QVector<qint64>({2, 2, 1});
+ VERIFY(MessageListPixmap, 1, createType(PixmapSizeKnown),
+ CheckMessageType | CheckDetailType | CheckNumbers, numbers);
// image loaded
- expected.detailType = QQmlProfilerDefinitions::PixmapLoadingFinished;
- VERIFY(MessageListPixmap, 2, expected, CheckMessageType | CheckDetailType);
+ VERIFY(MessageListPixmap, 2, createType(PixmapLoadingFinished),
+ CheckMessageType | CheckDetailType, numbers);
// cache size
- expected.detailType = QQmlProfilerDefinitions::PixmapCacheCountChanged;
- VERIFY(MessageListPixmap, 3, expected, CheckMessageType | CheckDetailType);
+ VERIFY(MessageListPixmap, 3, createType(PixmapCacheCountChanged),
+ CheckMessageType | CheckDetailType, numbers);
}
void tst_QQmlProfilerService::scenegraphData()
{
- connect(true, "scenegraphTest.qml");
-
- m_client->sendRecordingStatus(true);
+ QCOMPARE(connect(true, "scenegraphTest.qml"), ConnectSuccess);
while (!m_process->output().contains(QLatin1String("tick")))
QVERIFY(QQmlDebugTest::waitForSignal(m_process, SIGNAL(readyReadStandardOutput())));
- m_client->sendRecordingStatus(false);
+ m_client->client->setRecording(false);
checkTraceReceived();
checkJsHeap();
@@ -619,34 +613,39 @@ void tst_QQmlProfilerService::scenegraphData()
qint64 contextFrameTime = -1;
qint64 renderFrameTime = -1;
#if QT_CONFIG(opengl) //Software renderer doesn't have context frames
- foreach (const QQmlProfilerData &msg, m_client->asynchronousMessages) {
- if (msg.messageType == QQmlProfilerDefinitions::SceneGraphFrame) {
- if (msg.detailType == QQmlProfilerDefinitions::SceneGraphContextFrame) {
- contextFrameTime = msg.time;
- break;
+ if (QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL)) {
+ foreach (const QQmlProfilerEvent &msg, m_client->asynchronousMessages) {
+ const QQmlProfilerEventType &type = m_client->types.at(msg.typeIndex());
+ if (type.message() == SceneGraphFrame) {
+ if (type.detailType() == SceneGraphContextFrame) {
+ contextFrameTime = msg.timestamp();
+ break;
+ }
}
}
- }
- QVERIFY(contextFrameTime != -1);
+ QVERIFY(contextFrameTime != -1);
+ }
#endif
- foreach (const QQmlProfilerData &msg, m_client->asynchronousMessages) {
- if (msg.detailType == QQmlProfilerDefinitions::SceneGraphRendererFrame) {
- QVERIFY(msg.time >= contextFrameTime);
- renderFrameTime = msg.time;
+ foreach (const QQmlProfilerEvent &msg, m_client->asynchronousMessages) {
+ const QQmlProfilerEventType &type = m_client->types.at(msg.typeIndex());
+ if (type.detailType() == SceneGraphRendererFrame) {
+ QVERIFY(msg.timestamp() >= contextFrameTime);
+ renderFrameTime = msg.timestamp();
break;
}
}
QVERIFY(renderFrameTime != -1);
- foreach (const QQmlProfilerData &msg, m_client->asynchronousMessages) {
- if (msg.detailType == QQmlProfilerDefinitions::SceneGraphRenderLoopFrame) {
- if (msg.time >= contextFrameTime) {
+ foreach (const QQmlProfilerEvent &msg, m_client->asynchronousMessages) {
+ const QQmlProfilerEventType &type = m_client->types.at(msg.typeIndex());
+ if (type.detailType() == SceneGraphRenderLoopFrame) {
+ if (msg.timestamp() >= contextFrameTime) {
// Make sure SceneGraphRenderLoopFrame is not between SceneGraphContextFrame and
// SceneGraphRendererFrame. A SceneGraphRenderLoopFrame before everything else is
// OK as the scene graph might decide to do an initial rendering.
- QVERIFY(msg.time >= renderFrameTime);
+ QVERIFY(msg.timestamp() >= renderFrameTime);
break;
}
}
@@ -655,9 +654,8 @@ void tst_QQmlProfilerService::scenegraphData()
void tst_QQmlProfilerService::profileOnExit()
{
- connect(true, "exit.qml");
-
- m_client->sendRecordingStatus(true);
+ QCOMPARE(connect(true, "exit.qml"), ConnectSuccess);
+ checkProcessTerminated();
checkTraceReceived();
checkJsHeap();
@@ -665,78 +663,182 @@ void tst_QQmlProfilerService::profileOnExit()
void tst_QQmlProfilerService::controlFromJS()
{
- connect(true, "controlFromJS.qml");
+ QCOMPARE(connect(true, "controlFromJS.qml", false), ConnectSuccess);
- m_client->sendRecordingStatus(false);
+ QTRY_VERIFY(m_client->numLoadedEventTypes() > 0);
+ m_client->client->setRecording(false);
checkTraceReceived();
checkJsHeap();
}
void tst_QQmlProfilerService::signalSourceLocation()
{
- connect(true, "signalSourceLocation.qml");
+ QCOMPARE(connect(true, "signalSourceLocation.qml"), ConnectSuccess);
- m_client->sendRecordingStatus(true);
while (!(m_process->output().contains(QLatin1String("500"))))
QVERIFY(QQmlDebugTest::waitForSignal(m_process, SIGNAL(readyReadStandardOutput())));
- m_client->sendRecordingStatus(false);
+ m_client->client->setRecording(false);
checkTraceReceived();
checkJsHeap();
- QQmlProfilerData expected(0, QQmlProfilerDefinitions::RangeLocation,
- QQmlProfilerDefinitions::HandlingSignal,
- QLatin1String("signalSourceLocation.qml"));
- expected.line = 8;
- expected.column = 28;
- VERIFY(MessageListQML, 9, expected, CheckAll);
+ auto createType = [](int line, int column) {
+ return QQmlProfilerEventType(
+ MaximumMessage, HandlingSignal, -1,
+ QQmlProfilerEventLocation(QLatin1String("signalSourceLocation.qml"), line,
+ column));
+ };
- expected.line = 7;
- expected.column = 21;
- VERIFY(MessageListQML, 11, expected, CheckAll);
+ VERIFY(MessageListQML, 4, createType(8, 28), CheckType | CheckNumbers, m_rangeStart);
+ VERIFY(MessageListQML, 6, createType(7, 21), CheckType | CheckNumbers, m_rangeEnd);
}
void tst_QQmlProfilerService::javascript()
{
- connect(true, "javascript.qml");
+ QCOMPARE(connect(true, "javascript.qml"), ConnectSuccess);
- m_client->sendRecordingStatus(true);
while (!(m_process->output().contains(QLatin1String("done"))))
QVERIFY(QQmlDebugTest::waitForSignal(m_process, SIGNAL(readyReadStandardOutput())));
- m_client->sendRecordingStatus(false);
+ m_client->client->setRecording(false);
checkTraceReceived();
checkJsHeap();
- QQmlProfilerData expected(0, QQmlProfilerDefinitions::RangeStart,
- QQmlProfilerDefinitions::Javascript);
- VERIFY(MessageListJavaScript, 6, expected, CheckMessageType | CheckDetailType);
+ VERIFY(MessageListJavaScript, 2, QQmlProfilerEventType(MaximumMessage, Javascript),
+ CheckMessageType | CheckDetailType | CheckNumbers, m_rangeStart);
- expected.messageType = QQmlProfilerDefinitions::RangeLocation;
- expected.detailData = QLatin1String("javascript.qml");
- expected.line = 4;
- expected.column = 5;
- VERIFY(MessageListJavaScript, 7, expected, CheckAll);
+ VERIFY(MessageListJavaScript, 3,
+ QQmlProfilerEventType(
+ MaximumMessage, Javascript, -1,
+ QQmlProfilerEventLocation(QLatin1String("javascript.qml"), 4, 5)),
+ CheckType | CheckNumbers, m_rangeStart);
- expected.messageType = QQmlProfilerDefinitions::RangeData;
- expected.detailData = QLatin1String("something");
- VERIFY(MessageListJavaScript, 8, expected,
- CheckMessageType | CheckDetailType | CheckDataEndsWith);
+ VERIFY(MessageListJavaScript, 4, QQmlProfilerEventType(
+ MaximumMessage, Javascript, -1,
+ QQmlProfilerEventLocation(), QLatin1String("something")),
+ CheckMessageType | CheckDetailType | CheckDataEndsWith | CheckNumbers, m_rangeStart);
- expected.messageType = QQmlProfilerDefinitions::RangeEnd;
- VERIFY(MessageListJavaScript, 21, expected, CheckMessageType | CheckDetailType);
+ VERIFY(MessageListJavaScript, 10, QQmlProfilerEventType(MaximumMessage, Javascript),
+ CheckMessageType | CheckDetailType | CheckNumbers, m_rangeEnd);
}
void tst_QQmlProfilerService::flushInterval()
{
- connect(true, "timer.qml");
-
- m_client->sendRecordingStatus(true, -1, 1);
+ QCOMPARE(connect(true, "timer.qml", true, 1), ConnectSuccess);
// Make sure we get multiple messages
QTRY_VERIFY(m_client->qmlMessages.length() > 0);
QVERIFY(m_client->qmlMessages.length() < 100);
QTRY_VERIFY(m_client->qmlMessages.length() > 100);
- m_client->sendRecordingStatus(false);
+ m_client->client->setRecording(false);
+ checkTraceReceived();
+ checkJsHeap();
+}
+
+void tst_QQmlProfilerService::translationBinding()
+{
+ QCOMPARE(connect(true, "qstr.qml"), ConnectSuccess);
+ checkProcessTerminated();
+
+ checkTraceReceived();
+ checkJsHeap();
+
+ const QQmlProfilerEventType type(MaximumMessage, Binding);
+
+ VERIFY(MessageListQML, 4, type, CheckDetailType | CheckMessageType | CheckNumbers,
+ m_rangeStart);
+ VERIFY(MessageListQML, 5, type, CheckDetailType | CheckMessageType | CheckNumbers,
+ m_rangeEnd);
+}
+
+void tst_QQmlProfilerService::memory()
+{
+ QCOMPARE(connect(true, "memory.qml"), ConnectSuccess);
+ checkProcessTerminated();
+
+ checkTraceReceived();
+ checkJsHeap();
+
+ QVERIFY(m_client);
+ int smallItems = 0;
+ for (const auto& message : m_client->jsHeapMessages) {
+ const QQmlProfilerEventType &type = m_client->types[message.typeIndex()];
+ if (type.detailType() == SmallItem)
+ ++smallItems;
+ }
+
+ QVERIFY(smallItems > 5);
+}
+
+static bool hasCompileEvents(const QVector<QQmlProfilerEventType> &types)
+{
+ for (const QQmlProfilerEventType &type : types) {
+ if (type.message() == MaximumMessage && type.rangeType() == Compiling)
+ return true;
+ }
+ return false;
+}
+
+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));
+ m_client->client->setRecording(false);
+
+ checkTraceReceived();
+ checkJsHeap();
+
+ Message rangeStage = MaximumMessage;
+ for (const auto& message : m_client->qmlMessages) {
+ const QQmlProfilerEventType &type = m_client->types[message.typeIndex()];
+ if (type.rangeType() == Compiling) {
+ switch (rangeStage) {
+ case MaximumMessage:
+ QCOMPARE(message.rangeStage(), RangeStart);
+ break;
+ case RangeStart:
+ QCOMPARE(message.rangeStage(), RangeEnd);
+ break;
+ default:
+ QFAIL("Wrong range stage");
+ }
+ rangeStage = message.rangeStage();
+ QCOMPARE(type.message(), MaximumMessage);
+ QCOMPARE(type.location().filename(), testFileUrl("test.qml").toString());
+ QCOMPARE(type.location().line(), 0);
+ QCOMPARE(type.location().column(), 0);
+ }
+ }
+
+ 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);
+}
+
+void tst_QQmlProfilerService::batchOverflow()
+{
+ // The trace client checks that the events are received in order.
+ QCOMPARE(connect(true, "batchOverflow.qml"), ConnectSuccess);
+ checkProcessTerminated();
checkTraceReceived();
checkJsHeap();
}
diff --git a/tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp b/tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp
index 441f8c113f..b75fb6b895 100644
--- a/tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp
+++ b/tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp
@@ -38,7 +38,6 @@
#include <private/qv4debugging_p.h>
#include <private/qv8engine_p.h>
#include <private/qv4objectiterator_p.h>
-#include <private/qv4isel_moth_p.h>
#include <private/qv4string_p.h>
#include <private/qqmlbuiltinfunctions_p.h>
#include <private/qqmldebugservice_p.h>
@@ -46,7 +45,7 @@
using namespace QV4;
using namespace QV4::Debugging;
-typedef void (*InjectedFunction)(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+typedef QV4::ReturnedValue (*InjectedFunction)(const FunctionObject *b, const QV4::Value *, const QV4::Value *, int);
Q_DECLARE_METATYPE(InjectedFunction)
static bool waitForSignal(QObject* obj, const char* signal, int timeout = 10000)
@@ -79,7 +78,7 @@ public:
emit evaluateFinished();
}
- QV4::ExecutionEngine *v4Engine() { return QV8Engine::getV4(this); }
+ QV4::ExecutionEngine *v4Engine() { return handle(); }
Q_INVOKABLE void injectFunction(const QString &functionName, InjectedFunction injectedFunction)
{
@@ -87,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, BuiltinFunction::create(ctx, name, injectedFunction));
+ QV4::ScopedValue function(scope, FunctionObject::createBuiltinFunction(v4, name, injectedFunction, 0));
v4->globalObject->put(name, function);
}
@@ -107,7 +105,7 @@ public:
void run() {
QV4::Scope scope(collector->engine());
QV4::ScopedValue v(scope, *collector->engine()->exceptionValue);
- exception = collector->collect(v);
+ exception = collector->addValueRef(v);
}
QV4DataCollector::Ref exceptionValue() const { return exception; }
@@ -167,7 +165,7 @@ public:
, m_thrownValue(-1)
, collector(engine)
, m_resumeSpeed(QV4Debugger::FullThrottle)
- , m_debugger(0)
+ , m_debugger(nullptr)
{
}
@@ -221,16 +219,26 @@ 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();
object = object.value(QLatin1String("object")).toObject();
- if (object.contains("ref") && !object.contains("properties")) {
- QVERIFY(collector.redundantRefs());
- object = collector.lookupRef(object.value("ref").toInt(), true);
- QVERIFY(object.contains("properties"));
- }
+ QVERIFY(!object.contains("ref") || object.contains("properties"));
foreach (const QJsonValue &value, object.value(QLatin1String("properties")).toArray()) {
QJsonObject property = value.toObject();
QString name = property.value(QLatin1String("name")).toString();
@@ -296,13 +304,10 @@ private slots:
void conditionalBreakPointInQml();
// context access:
- void readArguments_data() { redundancy_data(); }
void readArguments();
- void readLocals_data() { redundancy_data(); }
+ void readComplicatedArguments();
void readLocals();
- void readObject_data() { redundancy_data(); }
void readObject();
- void readContextInAllFrames_data() { redundancy_data(); }
void readContextInAllFrames();
// exceptions:
@@ -310,13 +315,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();
+
+ void readThis();
private:
QV4Debugger *debugger() const
{
@@ -330,8 +335,6 @@ private:
waitForSignal(m_engine, SIGNAL(evaluateFinished()), /*timeout*/0);
}
- void redundancy_data();
-
TestEngine *m_engine;
QV4::ExecutionEngine *m_v4;
TestAgent *m_debuggerAgent;
@@ -343,7 +346,6 @@ void tst_qv4debugger::init()
m_javaScriptThread = new QThread;
m_engine = new TestEngine;
m_v4 = m_engine->v4Engine();
- m_v4->iselFactory.reset(new QV4::Moth::ISelFactory);
m_v4->setDebugger(new QV4Debugger(m_v4));
m_engine->moveToThread(m_javaScriptThread);
m_javaScriptThread->start();
@@ -357,10 +359,10 @@ void tst_qv4debugger::cleanup()
m_javaScriptThread->wait();
delete m_engine;
delete m_javaScriptThread;
- m_engine = 0;
- m_v4 = 0;
+ m_engine = nullptr;
+ m_v4 = nullptr;
delete m_debuggerAgent;
- m_debuggerAgent = 0;
+ m_debuggerAgent = nullptr;
}
void tst_qv4debugger::breakAnywhere()
@@ -438,9 +440,9 @@ void tst_qv4debugger::addBreakPointWhilePaused()
QCOMPARE(state.lineNumber, 2);
}
-static void someCall(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *)
+static QV4::ReturnedValue someCall(const FunctionObject *function, const QV4::Value *, const QV4::Value *, int)
{
- static_cast<QV4Debugger *>(scope.engine->debugger())
+ static_cast<QV4Debugger *>(function->engine()->debugger())
->removeBreakPoint("removeBreakPointForNextInstruction", 2);
RETURN_UNDEFINED();
}
@@ -464,7 +466,7 @@ void tst_qv4debugger::conditionalBreakPoint()
{
m_debuggerAgent->m_captureContextInfo = true;
QString script =
- "function test() {\n"
+ "var test = function() {\n"
" for (var i = 0; i < 15; ++i) {\n"
" var x = i;\n"
" }\n"
@@ -481,7 +483,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);
}
@@ -489,9 +491,8 @@ void tst_qv4debugger::conditionalBreakPoint()
void tst_qv4debugger::conditionalBreakPointInQml()
{
QQmlEngine engine;
- QV4::ExecutionEngine *v4 = QV8Engine::getV4(&engine);
+ QV4::ExecutionEngine *v4 = engine.handle();
QV4Debugger *v4Debugger = new QV4Debugger(v4);
- v4->iselFactory.reset(new QV4::Moth::ISelFactory);
v4->setDebugger(v4Debugger);
QScopedPointer<QThread> debugThread(new QThread);
@@ -526,12 +527,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"
+ "var f = function(a, b, c, d) {\n"
" return a === b\n"
"}\n"
"var four;\n"
@@ -541,7 +539,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);
@@ -550,14 +548,31 @@ void tst_qv4debugger::readArguments()
QCOMPARE(frame0.value(QStringLiteral("b")).toString(), QStringLiteral("two"));
}
-void tst_qv4debugger::readLocals()
+void tst_qv4debugger::readComplicatedArguments()
{
- QFETCH(bool, redundantRefs);
- m_debuggerAgent->collector.setRedundantRefs(redundantRefs);
+ m_debuggerAgent->m_captureContextInfo = true;
+ QString script =
+ "var f = function(a) {\n"
+ " a = 12;\n"
+ " return a;\n"
+ "}\n"
+ "f(1, 2);\n";
+ debugger()->addBreakPoint("readArguments", 3);
+ evaluateJavaScript(script, "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(), 2);
+ QVERIFY(frame0.contains(QStringLiteral("a")));
+ QCOMPARE(frame0.type(QStringLiteral("a")), QStringLiteral("number"));
+ QCOMPARE(frame0.value(QStringLiteral("a")).toInt(), 12);
+}
+void tst_qv4debugger::readLocals()
+{
m_debuggerAgent->m_captureContextInfo = true;
QString script =
- "function f(a, b) {\n"
+ "var f = function(a, b) {\n"
" var c = a + b\n"
" var d = a - b\n" // breakpoint, c should be set, d should be undefined
" return c === d\n"
@@ -568,7 +583,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);
@@ -578,12 +593,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"
+ "var f = function(a) {\n"
" var b = a\n"
" return b\n"
"}\n"
@@ -593,7 +605,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");
@@ -602,7 +614,7 @@ void tst_qv4debugger::readObject()
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);
+ b = m_debuggerAgent->collector.lookupRef(b.value("ref").toInt());
QVERIFY(b.contains(QStringLiteral("properties")));
QVERIFY(b.value("properties").isArray());
QJsonArray b_props = b.value("properties").toArray();
@@ -618,8 +630,7 @@ 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(),
- true);
+ QJsonObject b_tail_value = m_debuggerAgent->collector.lookupRef(b_tail.value("ref").toInt());
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();
@@ -630,18 +641,15 @@ void tst_qv4debugger::readObject()
QCOMPARE(b_tail_head.value("value").toString(), QStringLiteral("asdf"));
QJsonObject b_tail_tail = b_tail_props.at(1).toObject();
QCOMPARE(b_tail_tail.value("name").toString(), QStringLiteral("tail"));
- QCOMPARE(b_tail_tail.value("type").toString(), QStringLiteral("null"));
+ QCOMPARE(b_tail_tail.value("type").toString(), QStringLiteral("object"));
QVERIFY(b_tail_tail.value("value").isNull());
}
void tst_qv4debugger::readContextInAllFrames()
{
- QFETCH(bool, redundantRefs);
- m_debuggerAgent->collector.setRedundantRefs(redundantRefs);
-
m_debuggerAgent->m_captureContextInfo = true;
QString script =
- "function fact(n) {\n"
+ "var fact = function(n) {\n"
" if (n > 1) {\n"
" var n_1 = n - 1;\n"
" n_1 = fact(n_1);\n"
@@ -658,7 +666,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);
@@ -686,8 +694,7 @@ 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,
- true);
+ QJsonObject exception = m_debuggerAgent->collector.lookupRef(m_debuggerAgent->m_thrownValue);
// DUMP_JSON(exception);
QCOMPARE(exception.value("type").toString(), QStringLiteral("string"));
QCOMPARE(exception.value("value").toString(), QStringLiteral("hard"));
@@ -731,9 +738,6 @@ 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"
@@ -775,9 +779,6 @@ void tst_qv4debugger::evaluateExpression()
void tst_qv4debugger::stepToEndOfScript()
{
- QFETCH(bool, redundantRefs);
- m_debuggerAgent->collector.setRedundantRefs(redundantRefs);
-
QString script =
"var ret = 0;\n"
"ret += 4;\n"
@@ -814,13 +815,13 @@ void tst_qv4debugger::lastLineOfConditional_data()
QTest::newRow("do..while {block}") << "do {\n" << "} while (ret < 10);" << 4 << 7;
QTest::newRow("if true {block}") << "if (true) {\n" << "}"
- << 4 << 7;
+ << 4 << 8;
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;
+ << 4 << 10;
QTest::newRow("if false else {block}") << "if (false) {\n" << "} else {\n ret += 8;\n}"
- << 8 << 9;
+ << 8 << 10;
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;
@@ -829,11 +830,11 @@ void tst_qv4debugger::lastLineOfConditional_data()
// 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 true statement") << "if (true)\n" << "" << 4 << 8;
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 true else statement") << "if (true)\n" << "else\n ret += 8;" << 4 << 9;
QTest::newRow("if false else statement") << "if (false)\n" << "else\n ret += 8;" << 8 << 9;
}
@@ -868,11 +869,34 @@ void tst_qv4debugger::lastLineOfConditional()
QCOMPARE(secondState.lineNumber, lastLine);
}
-void tst_qv4debugger::redundancy_data()
+void tst_qv4debugger::readThis()
{
- QTest::addColumn<bool>("redundantRefs");
- QTest::addRow("redundant") << true;
- QTest::addRow("sparse") << false;
+ m_debuggerAgent->m_captureContextInfo = true;
+ QString script =
+ "var x = function() {\n"
+ " return this.a;\n"
+ "}.apply({a : 5}, []);\n";
+
+ TestAgent::ExpressionRequest request;
+ request.expression = "this";
+ request.frameNr = 0;
+ request.context = -1; // no extra context
+ m_debuggerAgent->m_expressionRequests << request;
+
+ debugger()->addBreakPoint("applyThis", 2);
+ evaluateJavaScript(script, "applyThis");
+ QVERIFY(m_debuggerAgent->m_wasPaused);
+
+ QCOMPARE(m_debuggerAgent->m_expressionResults.count(), 1);
+ QJsonObject result0 = m_debuggerAgent->m_expressionResults[0];
+ QCOMPARE(result0.value("type").toString(), QStringLiteral("object"));
+ QCOMPARE(result0.value("value").toInt(), 1);
+ QJsonArray properties = result0.value("properties").toArray();
+ QCOMPARE(properties.size(), 1);
+ QJsonObject a = properties.first().toObject();
+ QCOMPARE(a.value("name").toString(), QStringLiteral("a"));
+ QCOMPARE(a.value("type").toString(), QStringLiteral("number"));
+ QCOMPARE(a.value("value").toInt(), 5);
}
QTEST_MAIN(tst_qv4debugger)
diff --git a/tests/auto/qml/debugger/shared/debugutil.cpp b/tests/auto/qml/debugger/shared/debugutil.cpp
index 7b9e935678..68446b53a4 100644
--- a/tests/auto/qml/debugger/shared/debugutil.cpp
+++ b/tests/auto/qml/debugger/shared/debugutil.cpp
@@ -27,13 +27,12 @@
****************************************************************************/
#include "debugutil_p.h"
+#include "qqmldebugprocess_p.h"
#include <private/qqmldebugconnection_p.h>
#include <QtCore/qeventloop.h>
#include <QtCore/qtimer.h>
-#include <QtCore/qfileinfo.h>
-#include <QtCore/qdir.h>
bool QQmlDebugTest::waitForSignal(QObject *receiver, const char *member, int timeout) {
QEventLoop loop;
@@ -51,15 +50,23 @@ bool QQmlDebugTest::waitForSignal(QObject *receiver, const char *member, int tim
QList<QQmlDebugClient *> QQmlDebugTest::createOtherClients(QQmlDebugConnection *connection)
{
QList<QQmlDebugClient *> ret;
- foreach (const QString &service, QQmlDebuggingEnabler::debuggerServices()) {
+
+ static const auto debuggerServices
+ = QStringList({"V8Debugger", "QmlDebugger", "DebugMessages"});
+ static const auto inspectorServices
+ = QStringList({"QmlInspector"});
+ static const auto profilerServices
+ = QStringList({"CanvasFrameRate", "EngineControl", "DebugMessages"});
+
+ for (const QString &service : debuggerServices) {
if (!connection->client(service))
ret << new QQmlDebugClient(service, connection);
}
- foreach (const QString &service, QQmlDebuggingEnabler::inspectorServices()) {
+ for (const QString &service : inspectorServices) {
if (!connection->client(service))
ret << new QQmlDebugClient(service, connection);
}
- foreach (const QString &service, QQmlDebuggingEnabler::profilerServices()) {
+ for (const QString &service : profilerServices) {
if (!connection->client(service))
ret << new QQmlDebugClient(service, connection);
}
@@ -91,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()
@@ -104,201 +114,150 @@ 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);
}
-QQmlDebugProcess::QQmlDebugProcess(const QString &executable, QObject *parent)
- : QObject(parent)
- , m_executable(executable)
- , m_started(false)
- , m_port(0)
- , m_maximumBindErrors(0)
- , m_receivedBindErrors(0)
+QQmlDebugTest::ConnectResult QQmlDebugTest::connect(
+ const QString &executable, const QString &services, const QString &extraArgs,
+ bool block)
{
- m_process.setProcessChannelMode(QProcess::MergedChannels);
- m_timer.setSingleShot(true);
- m_timer.setInterval(5000);
- connect(&m_process, SIGNAL(readyReadStandardOutput()), this, SLOT(processAppOutput()));
- connect(&m_process, SIGNAL(errorOccurred(QProcess::ProcessError)),
- this, SLOT(processError(QProcess::ProcessError)));
- connect(&m_timer, SIGNAL(timeout()), SLOT(timeout()));
-}
+ QStringList arguments;
+ arguments << QString::fromLatin1("-qmljsdebugger=port:13773,13783%3%4")
+ .arg(block ? QStringLiteral(",block") : QString())
+ .arg(services.isEmpty() ? services : (QStringLiteral(",services:") + services))
+ << extraArgs;
-QQmlDebugProcess::~QQmlDebugProcess()
-{
- stop();
-}
+ m_process = createProcess(executable);
+ if (!m_process)
+ return ProcessFailed;
-QString QQmlDebugProcess::state()
-{
- QString stateStr;
- switch (m_process.state()) {
- case QProcess::NotRunning: {
- stateStr = "not running";
- if (m_process.exitStatus() == QProcess::CrashExit)
- stateStr += " (crashed!)";
- else
- stateStr += ", return value " + QString::number(m_process.exitCode());
- break;
- }
- case QProcess::Starting: stateStr = "starting"; break;
- case QProcess::Running: stateStr = "running"; break;
- }
- return stateStr;
-}
+ m_process->start(QStringList() << arguments);
+ if (!m_process->waitForSessionStart())
+ return SessionFailed;
-void QQmlDebugProcess::start(const QStringList &arguments)
-{
-#ifdef Q_OS_MAC
- // make sure m_executable points to the actual binary even if it's inside an app bundle
- QFileInfo binFile(m_executable);
- if (!binFile.isExecutable()) {
- QDir bundleDir(m_executable + ".app");
- if (bundleDir.exists()) {
- m_executable = bundleDir.absoluteFilePath("Contents/MacOS/" + binFile.baseName());
- //qDebug() << Q_FUNC_INFO << "found bundled binary" << m_executable;
- }
- }
-#endif
- m_mutex.lock();
- m_port = 0;
- m_process.setEnvironment(QProcess::systemEnvironment() + m_environment);
- m_process.start(m_executable, arguments);
- if (!m_process.waitForStarted()) {
- qWarning() << "QML Debug Client: Could not launch app " << m_executable
- << ": " << m_process.errorString();
- m_eventLoop.quit();
- } else {
- m_timer.start();
- }
- m_mutex.unlock();
+ m_connection = createConnection();
+ if (!m_connection)
+ return ConnectionFailed;
+
+ m_clients = createClients();
+ if (m_clients.contains(nullptr))
+ return ClientsFailed;
+
+ ClientStateHandler stateHandler(m_clients, createOtherClients(m_connection), services.isEmpty()
+ ? QQmlDebugClient::Enabled : QQmlDebugClient::Unavailable);
+
+
+ const int port = m_process->debugPort();
+ m_connection->connectToHost(QLatin1String("127.0.0.1"), port);
+
+ 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;
+
+ if (!stateHandler.othersAsExpected())
+ return RestrictFailed;
+
+ return ConnectSuccess;
}
-void QQmlDebugProcess::stop()
+QList<QQmlDebugClient *> QQmlDebugTest::createClients()
{
- if (m_process.state() != QProcess::NotRunning) {
- m_process.kill();
- m_process.waitForFinished(5000);
- }
+ return QList<QQmlDebugClient *>();
}
-void QQmlDebugProcess::setMaximumBindErrors(int ignore)
+QQmlDebugProcess *QQmlDebugTest::createProcess(const QString &executable)
{
- m_maximumBindErrors = ignore;
+ return new QQmlDebugProcess(executable, this);
}
-void QQmlDebugProcess::timeout()
+QQmlDebugConnection *QQmlDebugTest::createConnection()
{
- qWarning() << "Timeout while waiting for QML debugging messages "
- "in application output. Process is in state" << m_process.state() << ", Output:" << m_output << ".";
- m_eventLoop.quit();
+ return new QQmlDebugConnection(this);
}
-bool QQmlDebugProcess::waitForSessionStart()
+void QQmlDebugTest::cleanup()
{
- if (m_process.state() != QProcess::Running) {
- qWarning() << "Could not start up " << m_executable;
- return false;
+ if (QTest::currentTestFailed()) {
+ const QString null = QStringLiteral("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) {
+ if (client)
+ qDebug() << client->name() << "State:" << QQmlDebugTest::clientStateString(client);
+ else
+ qDebug() << "Failed Client:" << null;
+ }
}
- m_eventLoop.exec();
- return m_started;
-}
+ qDeleteAll(m_clients);
+ m_clients.clear();
-int QQmlDebugProcess::debugPort() const
-{
- return m_port;
-}
+ delete m_connection;
+ m_connection = nullptr;
-bool QQmlDebugProcess::waitForFinished()
-{
- return m_process.waitForFinished();
+ if (m_process) {
+ m_process->stop();
+ delete m_process;
+ m_process = nullptr;
+ }
}
-QProcess::ExitStatus QQmlDebugProcess::exitStatus() const
+ClientStateHandler::ClientStateHandler(const QList<QQmlDebugClient *> &clients,
+ const QList<QQmlDebugClient *> &others,
+ QQmlDebugClient::State expectedOthers) :
+ m_clients(clients), m_others(others), m_expectedOthers(expectedOthers)
{
- return m_process.exitStatus();
+ 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);
+ }
}
-void QQmlDebugProcess::addEnvironment(const QString &environment)
+ClientStateHandler::~ClientStateHandler()
{
- m_environment.append(environment);
+ qDeleteAll(m_others);
}
-QString QQmlDebugProcess::output() const
+void ClientStateHandler::checkStates()
{
- return m_output;
-}
+ for (QQmlDebugClient *client : m_clients) {
+ if (client->state() != QQmlDebugClient::Enabled)
+ return;
+ }
-void QQmlDebugProcess::processAppOutput()
-{
- m_mutex.lock();
-
- bool outputFromAppItself = false;
-
- QString newOutput = m_process.readAll();
- m_output.append(newOutput);
- m_outputBuffer.append(newOutput);
-
- while (true) {
- const int nlIndex = m_outputBuffer.indexOf(QLatin1Char('\n'));
- if (nlIndex < 0) // no further complete lines
- break;
- const QString line = m_outputBuffer.left(nlIndex);
- m_outputBuffer = m_outputBuffer.right(m_outputBuffer.size() - nlIndex - 1);
-
- if (line.contains("QML Debugger:")) {
- const QRegExp portRx("Waiting for connection on port (\\d+)");
- if (portRx.indexIn(line) != -1) {
- m_port = portRx.cap(1).toInt();
- m_timer.stop();
- m_started = true;
- m_eventLoop.quit();
- continue;
- }
- if (line.contains("Unable to listen")) {
- if (++m_receivedBindErrors >= m_maximumBindErrors) {
- if (m_maximumBindErrors == 0)
- qWarning() << "App was unable to bind to port!";
- m_timer.stop();
- m_eventLoop.quit();
- }
- continue;
- }
- } else {
- // set to true if there is output not coming from the debugger
- outputFromAppItself = true;
- }
+ m_allEnabled = true;
+
+ for (QQmlDebugClient *other : m_others) {
+ if (other->state() != m_expectedOthers)
+ return;
}
- m_mutex.unlock();
- if (outputFromAppItself)
- emit readyReadStandardOutput();
+ m_othersAsExpected = true;
+ emit allOk();
}
-void QQmlDebugProcess::processError(QProcess::ProcessError error)
+QString debugJsServerPath(const QString &selfPath)
{
- if (!m_eventLoop.isRunning())
- return;
-
- qDebug() << "An error occurred while waiting for debug process to become available:";
- switch (error) {
- case QProcess::FailedToStart: qDebug() << "Process failed to start."; break;
- case QProcess::Crashed: qDebug() << "Process crashed."; break;
- case QProcess::Timedout: qDebug() << "Process timed out."; break;
- case QProcess::WriteError: qDebug() << "Error while writing to process."; break;
- case QProcess::ReadError: qDebug() << "Error while reading from process."; break;
- case QProcess::UnknownError: qDebug() << "Unknown process error."; break;
- }
-
- m_eventLoop.exit();
+ 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.pri b/tests/auto/qml/debugger/shared/debugutil.pri
index 1983f3583e..13dcdb91d8 100644
--- a/tests/auto/qml/debugger/shared/debugutil.pri
+++ b/tests/auto/qml/debugger/shared/debugutil.pri
@@ -1,4 +1,11 @@
QT += qmldebug-private
-HEADERS += $$PWD/debugutil_p.h
-SOURCES += $$PWD/debugutil.cpp
+INCLUDEPATH += $$PWD
+include($$PWD/../../../shared/util.pri)
+
+HEADERS += \
+ $$PWD/debugutil_p.h \
+ $$PWD/qqmldebugprocess_p.h
+SOURCES += \
+ $$PWD/debugutil.cpp \
+ $$PWD/qqmldebugprocess.cpp
diff --git a/tests/auto/qml/debugger/shared/debugutil_p.h b/tests/auto/qml/debugger/shared/debugutil_p.h
index 1ec0a6513d..1c32590305 100644
--- a/tests/auto/qml/debugger/shared/debugutil_p.h
+++ b/tests/auto/qml/debugger/shared/debugutil_p.h
@@ -1,4 +1,3 @@
-
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
@@ -41,23 +40,43 @@
// We mean it.
//
+#include <../../../shared/util.h>
#include <private/qqmldebugclient_p.h>
-#include <QtCore/qeventloop.h>
-#include <QtCore/qtimer.h>
-#include <QtCore/qthread.h>
-#include <QtCore/qprocess.h>
-#include <QtCore/qmutex.h>
-#include <QtTest/qtest.h>
-#include <QtQml/qqmlengine.h>
-
-class QQmlDebugTest
+class QQmlDebugProcess;
+class QQmlDebugTest : public QQmlDataTest
{
+ Q_OBJECT
public:
static bool waitForSignal(QObject *receiver, const char *member, int timeout = 5000);
static QList<QQmlDebugClient *> createOtherClients(QQmlDebugConnection *connection);
static QString clientStateString(const QQmlDebugClient *client);
static QString connectionStateString(const QQmlDebugConnection *connection);
+
+protected:
+ enum ConnectResult {
+ ConnectSuccess,
+ ProcessFailed,
+ SessionFailed,
+ ConnectionFailed,
+ ClientsFailed,
+ EnableFailed,
+ RestrictFailed
+ };
+
+ ConnectResult connect(const QString &executable, const QString &services,
+ const QString &extraArgs, bool block);
+
+ virtual QQmlDebugProcess *createProcess(const QString &executable);
+ virtual QQmlDebugConnection *createConnection();
+ virtual QList<QQmlDebugClient *> createClients();
+
+ QQmlDebugProcess *m_process = nullptr;
+ QQmlDebugConnection *m_connection = nullptr;
+ QList<QQmlDebugClient *> m_clients;
+
+protected slots:
+ virtual void cleanup();
};
class QQmlDebugTestClient : public QQmlDebugClient
@@ -69,62 +88,15 @@ public:
QByteArray waitForResponse();
signals:
- void stateHasChanged();
void serverMessage(const QByteArray &);
protected:
- virtual void stateChanged(State state);
virtual void messageReceived(const QByteArray &ba);
private:
QByteArray lastMsg;
};
-class QQmlDebugProcess : public QObject
-{
- Q_OBJECT
-public:
- QQmlDebugProcess(const QString &executable, QObject *parent = 0);
- ~QQmlDebugProcess();
-
- QString state();
-
- void addEnvironment(const QString &environment);
-
- void start(const QStringList &arguments);
- bool waitForSessionStart();
- int debugPort() const;
-
- bool waitForFinished();
- QProcess::ExitStatus exitStatus() const;
-
- QString output() const;
- void stop();
- void setMaximumBindErrors(int numErrors);
-
-signals:
- void readyReadStandardOutput();
-
-private slots:
- void timeout();
- void processAppOutput();
- void processError(QProcess::ProcessError error);
-
-private:
- QString m_executable;
- QProcess m_process;
- QString m_outputBuffer;
- QString m_output;
- QTimer m_timer;
- QEventLoop m_eventLoop;
- QMutex m_mutex;
- bool m_started;
- QStringList m_environment;
- int m_port;
- int m_maximumBindErrors;
- int m_receivedBindErrors;
-};
-
class QQmlInspectorResultRecipient : public QObject
{
Q_OBJECT
@@ -142,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
new file mode 100644
index 0000000000..956e97e7ba
--- /dev/null
+++ b/tests/auto/qml/debugger/shared/qqmldebugprocess.cpp
@@ -0,0 +1,249 @@
+/****************************************************************************
+**
+** 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 "qqmldebugprocess_p.h"
+
+#include <QtCore/qdebug.h>
+#include <QtCore/qfileinfo.h>
+#include <QtCore/qdir.h>
+
+QQmlDebugProcess::QQmlDebugProcess(const QString &executable, QObject *parent)
+ : QObject(parent)
+ , m_executable(executable)
+ , m_state(SessionUnknown)
+ , m_port(0)
+ , m_maximumBindErrors(0)
+ , m_receivedBindErrors(0)
+{
+ m_process.setProcessChannelMode(QProcess::MergedChannels);
+ m_timer.setInterval(15000);
+ connect(&m_process, &QProcess::readyReadStandardOutput,
+ this, &QQmlDebugProcess::processAppOutput);
+ connect(&m_process, &QProcess::errorOccurred,
+ this, &QQmlDebugProcess::processError);
+ connect(&m_process, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
+ this, [this]() {
+ m_timer.stop();
+ m_eventLoop.quit();
+ emit finished();
+ });
+ connect(&m_timer, &QTimer::timeout,
+ this, &QQmlDebugProcess::timeout);
+}
+
+QQmlDebugProcess::~QQmlDebugProcess()
+{
+ stop();
+}
+
+QString QQmlDebugProcess::stateString() const
+{
+ QString stateStr;
+ switch (m_process.state()) {
+ case QProcess::NotRunning: {
+ stateStr = "not running";
+ if (m_process.exitStatus() == QProcess::CrashExit)
+ stateStr += " (crashed!)";
+ else
+ stateStr += ", return value " + QString::number(m_process.exitCode());
+ break;
+ }
+ case QProcess::Starting:
+ stateStr = "starting";
+ break;
+ case QProcess::Running:
+ stateStr = "running";
+ break;
+ }
+ return stateStr;
+}
+
+void QQmlDebugProcess::start(const QStringList &arguments)
+{
+#ifdef Q_OS_MAC
+ // make sure m_executable points to the actual binary even if it's inside an app bundle
+ QFileInfo binFile(m_executable);
+ if (!binFile.isExecutable()) {
+ QDir bundleDir(m_executable + ".app");
+ if (bundleDir.exists()) {
+ m_executable = bundleDir.absoluteFilePath("Contents/MacOS/" + binFile.baseName());
+ //qDebug() << Q_FUNC_INFO << "found bundled binary" << m_executable;
+ }
+ }
+#endif
+ m_mutex.lock();
+ m_port = 0;
+ m_process.setEnvironment(QProcess::systemEnvironment() + m_environment);
+ m_process.start(m_executable, arguments);
+ if (!m_process.waitForStarted()) {
+ qWarning() << "QML Debug Client: Could not launch app " << m_executable
+ << ": " << m_process.errorString();
+ m_eventLoop.quit();
+ }
+ m_mutex.unlock();
+}
+
+void QQmlDebugProcess::stop()
+{
+ if (m_process.state() != QProcess::NotRunning) {
+ disconnect(&m_process, &QProcess::errorOccurred, this, &QQmlDebugProcess::processError);
+ m_process.kill();
+ m_process.waitForFinished(5000);
+ }
+}
+
+void QQmlDebugProcess::setMaximumBindErrors(int ignore)
+{
+ m_maximumBindErrors = ignore;
+}
+
+void QQmlDebugProcess::timeout()
+{
+ qWarning() << "Timeout while waiting for QML debugging messages "
+ "in application output. Process is in state" << m_process.state()
+ << ", Output:" << m_output << ".";
+}
+
+bool QQmlDebugProcess::waitForSessionStart()
+{
+ if (m_process.state() != QProcess::Running) {
+ qWarning() << "Could not start up " << m_executable;
+ return false;
+ } else if (m_state == SessionStarted) {
+ return true;
+ } else if (m_state == SessionFailed) {
+ return false;
+ }
+
+ m_timer.start();
+ m_eventLoop.exec();
+
+ return m_state == SessionStarted;
+}
+
+int QQmlDebugProcess::debugPort() const
+{
+ return m_port;
+}
+
+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();
+}
+
+void QQmlDebugProcess::addEnvironment(const QString &environment)
+{
+ m_environment.append(environment);
+}
+
+QString QQmlDebugProcess::output() const
+{
+ return m_output;
+}
+
+void QQmlDebugProcess::processAppOutput()
+{
+ m_mutex.lock();
+
+ bool outputFromAppItself = false;
+
+ QString newOutput = m_process.readAll();
+ m_output.append(newOutput);
+ m_outputBuffer.append(newOutput);
+
+ while (true) {
+ const int nlIndex = m_outputBuffer.indexOf(QLatin1Char('\n'));
+ if (nlIndex < 0) // no further complete lines
+ break;
+ const QString line = m_outputBuffer.left(nlIndex);
+ m_outputBuffer = m_outputBuffer.right(m_outputBuffer.size() - nlIndex - 1);
+
+ if (line.contains("QML Debugger:")) {
+ const QRegExp portRx("Waiting for connection on port (\\d+)");
+ if (portRx.indexIn(line) != -1) {
+ m_port = portRx.cap(1).toInt();
+ m_timer.stop();
+ m_state = SessionStarted;
+ m_eventLoop.quit();
+ continue;
+ }
+ if (line.contains("Unable to listen")) {
+ if (++m_receivedBindErrors >= m_maximumBindErrors) {
+ if (m_maximumBindErrors == 0)
+ qWarning() << "App was unable to bind to port!";
+ m_timer.stop();
+ m_state = SessionFailed;
+ m_eventLoop.quit();
+ }
+ continue;
+ }
+ }
+
+ // set to true if there is output not coming from the debugger or we don't understand it
+ outputFromAppItself = true;
+ }
+ m_mutex.unlock();
+
+ if (outputFromAppItself)
+ emit readyReadStandardOutput();
+}
+
+void QQmlDebugProcess::processError(QProcess::ProcessError error)
+{
+ qDebug() << "An error occurred while waiting for debug process to become available:";
+ switch (error) {
+ case QProcess::FailedToStart:
+ qDebug() << "Process failed to start.";
+ break;
+ case QProcess::Crashed:
+ qDebug() << "Process crashed.";
+ break;
+ case QProcess::Timedout:
+ qDebug() << "Process timed out.";
+ break;
+ case QProcess::WriteError:
+ qDebug() << "Error while writing to process.";
+ break;
+ case QProcess::ReadError:
+ qDebug() << "Error while reading from process.";
+ break;
+ case QProcess::UnknownError:
+ qDebug() << "Unknown process error.";
+ break;
+ }
+}
diff --git a/tests/auto/qml/debugger/shared/qqmldebugprocess_p.h b/tests/auto/qml/debugger/shared/qqmldebugprocess_p.h
new file mode 100644
index 0000000000..945cc58c85
--- /dev/null
+++ b/tests/auto/qml/debugger/shared/qqmldebugprocess_p.h
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+#ifndef QQMLDEBUGPROCESS_P_H
+#define QQMLDEBUGPROCESS_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qprocess.h>
+#include <QtCore/qtimer.h>
+#include <QtCore/qeventloop.h>
+#include <QtCore/qmutex.h>
+
+class QQmlDebugProcess : public QObject
+{
+ Q_OBJECT
+public:
+ QQmlDebugProcess(const QString &executable, QObject *parent = 0);
+ ~QQmlDebugProcess();
+
+ QString stateString() const;
+
+ void addEnvironment(const QString &environment);
+
+ void start(const QStringList &arguments);
+ bool waitForSessionStart();
+ int debugPort() const;
+
+ bool waitForFinished();
+ QProcess::ProcessState state() const;
+ QProcess::ExitStatus exitStatus() const;
+
+ QString output() const;
+ void stop();
+ void setMaximumBindErrors(int numErrors);
+
+signals:
+ void readyReadStandardOutput();
+ void finished();
+
+private slots:
+ void timeout();
+ void processAppOutput();
+ void processError(QProcess::ProcessError error);
+
+private:
+ enum SessionState {
+ SessionUnknown,
+ SessionStarted,
+ SessionFailed
+ };
+
+ QString m_executable;
+ QProcess m_process;
+ QString m_outputBuffer;
+ QString m_output;
+ QTimer m_timer;
+ QEventLoop m_eventLoop;
+ QMutex m_mutex;
+ SessionState m_state;
+ QStringList m_environment;
+ int m_port;
+ int m_maximumBindErrors;
+ int m_receivedBindErrors;
+};
+
+#endif // QQMLDEBUGPROCESS_P_H
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);
diff --git a/tests/auto/qml/debugger/shared/qqmlenginedebugclient.cpp b/tests/auto/qml/debugger/shared/qqmlenginedebugclient.cpp
deleted file mode 100644
index c0252a0290..0000000000
--- a/tests/auto/qml/debugger/shared/qqmlenginedebugclient.cpp
+++ /dev/null
@@ -1,508 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQml module 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 "qqmlenginedebugclient.h"
-#include <private/qqmldebugconnection_p.h>
-
-struct QmlObjectData {
- QUrl url;
- int lineNumber;
- int columnNumber;
- QString idString;
- QString objectName;
- QString objectType;
- int objectId;
- int contextId;
- int parentId;
-};
-
-QPacket &operator>>(QPacket &ds, QmlObjectData &data)
-{
- ds >> data.url >> data.lineNumber >> data.columnNumber >> data.idString
- >> data.objectName >> data.objectType >> data.objectId >> data.contextId
- >> data.parentId;
- return ds;
-}
-
-struct QmlObjectProperty {
- enum Type { Unknown, Basic, Object, List, SignalProperty };
- Type type;
- QString name;
- QVariant value;
- QString valueTypeName;
- QString binding;
- bool hasNotifySignal;
-};
-
-QPacket &operator>>(QPacket &ds, QmlObjectProperty &data)
-{
- int type;
- ds >> type >> data.name >> data.value >> data.valueTypeName
- >> data.binding >> data.hasNotifySignal;
- data.type = (QmlObjectProperty::Type)type;
- return ds;
-}
-
-QQmlEngineDebugClient::QQmlEngineDebugClient(
- QQmlDebugConnection *connection)
- : QQmlDebugClient(QLatin1String("QmlDebugger"), connection),
- m_nextId(0),
- m_valid(false)
-{
-}
-
-quint32 QQmlEngineDebugClient::addWatch(
- const QmlDebugPropertyReference &property, bool *success)
-{
- quint32 id = -1;
- *success = false;
- if (state() == QQmlDebugClient::Enabled) {
- id = getId();
- QPacket ds(connection()->currentDataStreamVersion());
- ds << QByteArray("WATCH_PROPERTY") << id << property.objectDebugId
- << property.name.toUtf8();
- sendMessage(ds.data());
- *success = true;
- }
- return id;
-}
-
-quint32 QQmlEngineDebugClient::addWatch(
- const QmlDebugContextReference &, const QString &, bool *success)
-{
- *success = false;
- qWarning("QQmlEngineDebugClient::addWatch(): Not implemented");
- return 0;
-}
-
-quint32 QQmlEngineDebugClient::addWatch(
- const QmlDebugObjectReference &object, const QString &expr,
- bool *success)
-{
- quint32 id = -1;
- *success = false;
- if (state() == QQmlDebugClient::Enabled) {
- id = getId();
- QPacket ds(connection()->currentDataStreamVersion());
- ds << QByteArray("WATCH_EXPR_OBJECT") << id << object.debugId << expr;
- sendMessage(ds.data());
- *success = true;
- }
- return id;
-}
-
-quint32 QQmlEngineDebugClient::addWatch(
- const QmlDebugObjectReference &object, bool *success)
-{
- quint32 id = -1;
- *success = false;
- if (state() == QQmlDebugClient::Enabled) {
- id = getId();
- QPacket ds(connection()->currentDataStreamVersion());
- ds << QByteArray("WATCH_OBJECT") << id << object.debugId;
- sendMessage(ds.data());
- *success = true;
- }
- return id;
-}
-
-quint32 QQmlEngineDebugClient::addWatch(
- const QmlDebugFileReference &, bool *success)
-{
- *success = false;
- qWarning("QQmlEngineDebugClient::addWatch(): Not implemented");
- return 0;
-}
-
-void QQmlEngineDebugClient::removeWatch(quint32 id, bool *success)
-{
- *success = false;
- if (state() == QQmlDebugClient::Enabled) {
- QPacket ds(connection()->currentDataStreamVersion());
- ds << QByteArray("NO_WATCH") << id;
- sendMessage(ds.data());
- *success = true;
- }
-}
-
-quint32 QQmlEngineDebugClient::queryAvailableEngines(bool *success)
-{
- m_engines.clear();
- quint32 id = -1;
- *success = false;
- if (state() == QQmlDebugClient::Enabled) {
- id = getId();
- QPacket ds(connection()->currentDataStreamVersion());
- ds << QByteArray("LIST_ENGINES") << id;
- sendMessage(ds.data());
- *success = true;
- }
- return id;
-}
-
-quint32 QQmlEngineDebugClient::queryRootContexts(
- const QmlDebugEngineReference &engine, bool *success)
-{
- m_rootContext = QmlDebugContextReference();
- quint32 id = -1;
- *success = false;
- if (state() == QQmlDebugClient::Enabled && engine.debugId != -1) {
- id = getId();
- QPacket ds(connection()->currentDataStreamVersion());
- ds << QByteArray("LIST_OBJECTS") << id << engine.debugId;
- sendMessage(ds.data());
- *success = true;
- }
- return id;
-}
-
-quint32 QQmlEngineDebugClient::queryObject(
- const QmlDebugObjectReference &object, bool *success)
-{
- m_object = QmlDebugObjectReference();
- quint32 id = -1;
- *success = false;
- if (state() == QQmlDebugClient::Enabled && object.debugId != -1) {
- id = getId();
- QPacket ds(connection()->currentDataStreamVersion());
- ds << QByteArray("FETCH_OBJECT") << id << object.debugId << false << true;
- sendMessage(ds.data());
- *success = true;
- }
- return id;
-}
-
-quint32 QQmlEngineDebugClient::queryObjectsForLocation(
- const QString &file, int lineNumber, int columnNumber, bool *success)
-{
- m_objects.clear();
- quint32 id = -1;
- *success = false;
- if (state() == QQmlDebugClient::Enabled) {
- id = getId();
- QPacket ds(connection()->currentDataStreamVersion());
- ds << QByteArray("FETCH_OBJECTS_FOR_LOCATION") << id << file << lineNumber
- << columnNumber << false << true;
- sendMessage(ds.data());
- *success = true;
- }
- return id;
-}
-
-quint32 QQmlEngineDebugClient::queryObjectRecursive(
- const QmlDebugObjectReference &object, bool *success)
-{
- m_object = QmlDebugObjectReference();
- quint32 id = -1;
- *success = false;
- if (state() == QQmlDebugClient::Enabled && object.debugId != -1) {
- id = getId();
- QPacket ds(connection()->currentDataStreamVersion());
- ds << QByteArray("FETCH_OBJECT") << id << object.debugId << true << true;
- sendMessage(ds.data());
- *success = true;
- }
- return id;
-}
-
-quint32 QQmlEngineDebugClient::queryObjectsForLocationRecursive(const QString &file,
- int lineNumber, int columnNumber, bool *success)
-{
- m_objects.clear();
- quint32 id = -1;
- *success = false;
- if (state() == QQmlDebugClient::Enabled) {
- id = getId();
- QPacket ds(connection()->currentDataStreamVersion());
- ds << QByteArray("FETCH_OBJECTS_FOR_LOCATION") << id << file << lineNumber
- << columnNumber << true << true;
- sendMessage(ds.data());
- *success = true;
- }
- return id;
-}
-
-quint32 QQmlEngineDebugClient::queryExpressionResult(
- int objectDebugId, const QString &expr, bool *success)
-{
- m_exprResult = QVariant();
- quint32 id = -1;
- *success = false;
- if (state() == QQmlDebugClient::Enabled) {
- id = getId();
- QPacket ds(connection()->currentDataStreamVersion());
- ds << QByteArray("EVAL_EXPRESSION") << id << objectDebugId << expr
- << engines()[0].debugId;
- sendMessage(ds.data());
- *success = true;
- }
- return id;
-}
-
-quint32 QQmlEngineDebugClient::queryExpressionResultBC(
- int objectDebugId, const QString &expr, bool *success)
-{
- m_exprResult = QVariant();
- quint32 id = -1;
- *success = false;
- if (state() == QQmlDebugClient::Enabled) {
- id = getId();
- QPacket ds(connection()->currentDataStreamVersion());
- ds << QByteArray("EVAL_EXPRESSION") << id << objectDebugId << expr;
- sendMessage(ds.data());
- *success = true;
- }
- return id;
-}
-
-quint32 QQmlEngineDebugClient::setBindingForObject(
- int objectDebugId,
- const QString &propertyName,
- const QVariant &bindingExpression,
- bool isLiteralValue,
- QString source, int line,
- bool *success)
-{
- quint32 id = -1;
- *success = false;
- if (state() == QQmlDebugClient::Enabled && objectDebugId != -1) {
- id = getId();
- QPacket ds(connection()->currentDataStreamVersion());
- ds << QByteArray("SET_BINDING") << id << objectDebugId << propertyName
- << bindingExpression << isLiteralValue << source << line;
- sendMessage(ds.data());
- *success = true;
- }
- return id;
-}
-
-quint32 QQmlEngineDebugClient::resetBindingForObject(
- int objectDebugId,
- const QString &propertyName,
- bool *success)
-{
- quint32 id = -1;
- *success = false;
- if (state() == QQmlDebugClient::Enabled && objectDebugId != -1) {
- id = getId();
- QPacket ds(connection()->currentDataStreamVersion());
- ds << QByteArray("RESET_BINDING") << id << objectDebugId << propertyName;
- sendMessage(ds.data());
- *success = true;
- }
- return id;
-}
-
-quint32 QQmlEngineDebugClient::setMethodBody(
- int objectDebugId, const QString &methodName,
- const QString &methodBody, bool *success)
-{
- quint32 id = -1;
- *success = false;
- if (state() == QQmlDebugClient::Enabled && objectDebugId != -1) {
- id = getId();
- QPacket ds(connection()->currentDataStreamVersion());
- ds << QByteArray("SET_METHOD_BODY") << id << objectDebugId
- << methodName << methodBody;
- sendMessage(ds.data());
- *success = true;
- }
- return id;
-}
-
-void QQmlEngineDebugClient::decode(QPacket &ds,
- QmlDebugObjectReference &o,
- bool simple)
-{
- QmlObjectData data;
- ds >> data;
- o.debugId = data.objectId;
- o.className = data.objectType;
- o.idString = data.idString;
- o.name = data.objectName;
- o.source.url = data.url;
- o.source.lineNumber = data.lineNumber;
- o.source.columnNumber = data.columnNumber;
- o.contextDebugId = data.contextId;
-
- if (simple)
- return;
-
- int childCount;
- bool recur;
- ds >> childCount >> recur;
-
- for (int ii = 0; ii < childCount; ++ii) {
- o.children.append(QmlDebugObjectReference());
- decode(ds, o.children.last(), !recur);
- }
-
- int propCount;
- ds >> propCount;
-
- for (int ii = 0; ii < propCount; ++ii) {
- QmlObjectProperty data;
- ds >> data;
- QmlDebugPropertyReference prop;
- prop.objectDebugId = o.debugId;
- prop.name = data.name;
- prop.binding = data.binding;
- prop.hasNotifySignal = data.hasNotifySignal;
- prop.valueTypeName = data.valueTypeName;
- switch (data.type) {
- case QmlObjectProperty::Basic:
- case QmlObjectProperty::List:
- case QmlObjectProperty::SignalProperty:
- {
- prop.value = data.value;
- break;
- }
- case QmlObjectProperty::Object:
- {
- QmlDebugObjectReference obj;
- obj.debugId = prop.value.toInt();
- obj.className = prop.valueTypeName;
- prop.value = qVariantFromValue(obj);
- break;
- }
- case QmlObjectProperty::Unknown:
- break;
- }
- o.properties << prop;
- }
-}
-
-void QQmlEngineDebugClient::decode(QPacket &ds,
- QList<QmlDebugObjectReference> &o,
- bool simple)
-{
- int count;
- ds >> count;
- for (int i = 0; i < count; i++) {
- QmlDebugObjectReference obj;
- decode(ds, obj, simple);
- o << obj;
- }
-}
-
-void QQmlEngineDebugClient::decode(QPacket &ds,
- QmlDebugContextReference &c)
-{
- ds >> c.name >> c.debugId;
-
- int contextCount;
- ds >> contextCount;
-
- for (int ii = 0; ii < contextCount; ++ii) {
- c.contexts.append(QmlDebugContextReference());
- decode(ds, c.contexts.last());
- }
-
- int objectCount;
- ds >> objectCount;
-
- for (int ii = 0; ii < objectCount; ++ii) {
- QmlDebugObjectReference obj;
- decode(ds, obj, true);
-
- obj.contextDebugId = c.debugId;
- c.objects << obj;
- }
-}
-
-void QQmlEngineDebugClient::messageReceived(const QByteArray &data)
-{
- m_valid = false;
- QPacket ds(connection()->currentDataStreamVersion(), data);
-
- int queryId;
- QByteArray type;
- ds >> type >> queryId;
-
- //qDebug() << "QQmlEngineDebugPrivate::message()" << type;
-
- if (type == "LIST_ENGINES_R") {
- int count;
- ds >> count;
-
- m_engines.clear();
- for (int ii = 0; ii < count; ++ii) {
- QmlDebugEngineReference eng;
- ds >> eng.name;
- ds >> eng.debugId;
- m_engines << eng;
- }
- } else if (type == "LIST_OBJECTS_R") {
- if (!ds.atEnd())
- decode(ds, m_rootContext);
-
- } else if (type == "FETCH_OBJECT_R") {
- if (!ds.atEnd())
- decode(ds, m_object, false);
-
- } else if (type == "FETCH_OBJECTS_FOR_LOCATION_R") {
- if (!ds.atEnd())
- decode(ds, m_objects, false);
-
- } else if (type == "EVAL_EXPRESSION_R") {;
- ds >> m_exprResult;
-
- } else if (type == "WATCH_PROPERTY_R") {
- ds >> m_valid;
-
- } else if (type == "WATCH_OBJECT_R") {
- ds >> m_valid;
-
- } else if (type == "WATCH_EXPR_OBJECT_R") {
- ds >> m_valid;
-
- } else if (type == "UPDATE_WATCH") {
- int debugId;
- QByteArray name;
- QVariant value;
- ds >> debugId >> name >> value;
- emit valueChanged(name, value);
- return;
-
- } else if (type == "OBJECT_CREATED") {
- int engineId, objectId, parentId;
- ds >> engineId >> objectId >> parentId;
- emit newObject(objectId);
- return;
- } else if (type == "SET_BINDING_R") {
- ds >> m_valid;
- } else if (type == "RESET_BINDING_R") {
- ds >> m_valid;
- } else if (type == "SET_METHOD_BODY_R") {
- ds >> m_valid;
- } else if (type == "NO_WATCH_R") {
- ds >> m_valid;
- }
- emit result();
-}
-
diff --git a/tests/auto/qml/debugger/shared/qqmlenginedebugclient.h b/tests/auto/qml/debugger/shared/qqmlenginedebugclient.h
deleted file mode 100644
index 5d74f2d43c..0000000000
--- a/tests/auto/qml/debugger/shared/qqmlenginedebugclient.h
+++ /dev/null
@@ -1,233 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQml module 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$
-**
-****************************************************************************/
-
-#ifndef QQMLENGINEDEBUGCLIENT_H
-#define QQMLENGINEDEBUGCLIENT_H
-
-#include <private/qqmldebugclient_p.h>
-#include <private/qpacket_p.h>
-
-#include <QtCore/qurl.h>
-#include <QtCore/qvariant.h>
-
-struct QmlDebugPropertyReference
-{
- QmlDebugPropertyReference()
- : objectDebugId(-1), hasNotifySignal(false)
- {
- }
-
- QmlDebugPropertyReference &operator=(
- const QmlDebugPropertyReference &o)
- {
- objectDebugId = o.objectDebugId; name = o.name; value = o.value;
- valueTypeName = o.valueTypeName; binding = o.binding;
- hasNotifySignal = o.hasNotifySignal;
- return *this;
- }
-
- int objectDebugId;
- QString name;
- QVariant value;
- QString valueTypeName;
- QString binding;
- bool hasNotifySignal;
-};
-
-struct QmlDebugFileReference
-{
- QmlDebugFileReference()
- : lineNumber(-1), columnNumber(-1)
- {
- }
-
- QmlDebugFileReference &operator=(
- const QmlDebugFileReference &o)
- {
- url = o.url; lineNumber = o.lineNumber; columnNumber = o.columnNumber;
- return *this;
- }
-
- QUrl url;
- int lineNumber;
- int columnNumber;
-};
-
-struct QmlDebugObjectReference
-{
- QmlDebugObjectReference()
- : debugId(-1), contextDebugId(-1)
- {
- }
-
- QmlDebugObjectReference(int id)
- : debugId(id), contextDebugId(-1)
- {
- }
-
- QmlDebugObjectReference &operator=(
- const QmlDebugObjectReference &o)
- {
- debugId = o.debugId; className = o.className; idString = o.idString;
- name = o.name; source = o.source; contextDebugId = o.contextDebugId;
- properties = o.properties; children = o.children;
- return *this;
- }
- int debugId;
- QString className;
- QString idString;
- QString name;
- QmlDebugFileReference source;
- int contextDebugId;
- QList<QmlDebugPropertyReference> properties;
- QList<QmlDebugObjectReference> children;
-};
-
-Q_DECLARE_METATYPE(QmlDebugObjectReference)
-
-struct QmlDebugContextReference
-{
- QmlDebugContextReference()
- : debugId(-1)
- {
- }
-
- QmlDebugContextReference &operator=(
- const QmlDebugContextReference &o)
- {
- debugId = o.debugId; name = o.name; objects = o.objects;
- contexts = o.contexts;
- return *this;
- }
-
- int debugId;
- QString name;
- QList<QmlDebugObjectReference> objects;
- QList<QmlDebugContextReference> contexts;
-};
-
-struct QmlDebugEngineReference
-{
- QmlDebugEngineReference()
- : debugId(-1)
- {
- }
-
- QmlDebugEngineReference(int id)
- : debugId(id)
- {
- }
-
- QmlDebugEngineReference &operator=(
- const QmlDebugEngineReference &o)
- {
- debugId = o.debugId; name = o.name;
- return *this;
- }
-
- int debugId;
- QString name;
-};
-
-class QQmlEngineDebugClient : public QQmlDebugClient
-{
- Q_OBJECT
-public:
- explicit QQmlEngineDebugClient(QQmlDebugConnection *conn);
-
- quint32 addWatch(const QmlDebugPropertyReference &,
- bool *success);
- quint32 addWatch(const QmlDebugContextReference &, const QString &,
- bool *success);
- quint32 addWatch(const QmlDebugObjectReference &, const QString &,
- bool *success);
- quint32 addWatch(const QmlDebugObjectReference &,
- bool *success);
- quint32 addWatch(const QmlDebugFileReference &,
- bool *success);
-
- void removeWatch(quint32 watch, bool *success);
-
- quint32 queryAvailableEngines(bool *success);
- quint32 queryRootContexts(const QmlDebugEngineReference &,
- bool *success);
- quint32 queryObject(const QmlDebugObjectReference &,
- bool *success);
- quint32 queryObjectsForLocation(const QString &file,
- int lineNumber, int columnNumber, bool *success);
- quint32 queryObjectRecursive(const QmlDebugObjectReference &,
- bool *success);
- quint32 queryObjectsForLocationRecursive(const QString &file,
- int lineNumber, int columnNumber, bool *success);
- quint32 queryExpressionResult(int objectDebugId,
- const QString &expr,
- bool *success);
- quint32 queryExpressionResultBC(int objectDebugId,
- const QString &expr,
- bool *success);
- quint32 setBindingForObject(int objectDebugId, const QString &propertyName,
- const QVariant &bindingExpression,
- bool isLiteralValue,
- QString source, int line, bool *success);
- quint32 resetBindingForObject(int objectDebugId,
- const QString &propertyName, bool *success);
- quint32 setMethodBody(int objectDebugId, const QString &methodName,
- const QString &methodBody, bool *success);
-
- quint32 getId() { return m_nextId++; }
-
- void decode(QPacket &ds, QmlDebugContextReference &);
- void decode(QPacket &ds, QmlDebugObjectReference &, bool simple);
- void decode(QPacket &ds, QList<QmlDebugObjectReference> &o, bool simple);
-
- QList<QmlDebugEngineReference> engines() { return m_engines; }
- QmlDebugContextReference rootContext() { return m_rootContext; }
- QmlDebugObjectReference object() { return m_object; }
- QList<QmlDebugObjectReference> objects() { return m_objects; }
- QVariant resultExpr() { return m_exprResult; }
- bool valid() { return m_valid; }
-
-signals:
- void newObject(int objectId);
- void valueChanged(QByteArray,QVariant);
- void result();
-
-protected:
- void messageReceived(const QByteArray &);
-
-private:
- quint32 m_nextId;
- bool m_valid;
- QList<QmlDebugEngineReference> m_engines;
- QmlDebugContextReference m_rootContext;
- QmlDebugObjectReference m_object;
- QList<QmlDebugObjectReference> m_objects;
- QVariant m_exprResult;
-};
-
-#endif // QQMLENGINEDEBUGCLIENT_H
diff --git a/tests/auto/qml/debugger/shared/qqmlenginedebugclient.pri b/tests/auto/qml/debugger/shared/qqmlenginedebugclient.pri
deleted file mode 100644
index a969b4f153..0000000000
--- a/tests/auto/qml/debugger/shared/qqmlenginedebugclient.pri
+++ /dev/null
@@ -1,3 +0,0 @@
-HEADERS += $$PWD/qqmlenginedebugclient.h
-
-SOURCES += $$PWD/qqmlenginedebugclient.cpp
diff --git a/tests/auto/qml/debugger/shared/qqmlinspectorclient.cpp b/tests/auto/qml/debugger/shared/qqmlinspectorclient.cpp
deleted file mode 100644
index 20faef177e..0000000000
--- a/tests/auto/qml/debugger/shared/qqmlinspectorclient.cpp
+++ /dev/null
@@ -1,124 +0,0 @@
-/****************************************************************************
-**
-** 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 "qqmlinspectorclient.h"
-
-#include <private/qpacket_p.h>
-#include <private/qqmldebugconnection_p.h>
-#include <QtCore/qdebug.h>
-
-QQmlInspectorClient::QQmlInspectorClient(QQmlDebugConnection *connection) :
- QQmlDebugClient(QLatin1String("QmlInspector"), connection),
- m_lastRequestId(-1)
-{
-}
-
-int QQmlInspectorClient::setInspectToolEnabled(bool enabled)
-{
- QPacket ds(connection()->currentDataStreamVersion());
- ds << QByteArray("request") << ++m_lastRequestId
- << QByteArray(enabled ? "enable" : "disable");
-
- sendMessage(ds.data());
- return m_lastRequestId;
-}
-
-int QQmlInspectorClient::setShowAppOnTop(bool showOnTop)
-{
- QPacket ds(connection()->currentDataStreamVersion());
- ds << QByteArray("request") << ++m_lastRequestId
- << QByteArray("showAppOnTop") << showOnTop;
-
- sendMessage(ds.data());
- return m_lastRequestId;
-}
-
-int QQmlInspectorClient::setAnimationSpeed(qreal speed)
-{
- QPacket ds(connection()->currentDataStreamVersion());
- ds << QByteArray("request") << ++m_lastRequestId
- << QByteArray("setAnimationSpeed") << speed;
-
- sendMessage(ds.data());
- return m_lastRequestId;
-}
-
-int QQmlInspectorClient::select(const QList<int> &objectIds)
-{
- QPacket ds(connection()->currentDataStreamVersion());
- ds << QByteArray("request") << ++m_lastRequestId
- << QByteArray("select") << objectIds;
-
- sendMessage(ds.data());
- return m_lastRequestId;
-}
-
-int QQmlInspectorClient::createObject(const QString &qml, int parentId, const QStringList &imports,
- const QString &filename)
-{
- QPacket ds(connection()->currentDataStreamVersion());
- ds << QByteArray("request") << ++m_lastRequestId
- << QByteArray("createObject") << qml << parentId << imports << filename;
- sendMessage(ds.data());
- return m_lastRequestId;
-}
-
-int QQmlInspectorClient::moveObject(int childId, int newParentId)
-{
- QPacket ds(connection()->currentDataStreamVersion());
- ds << QByteArray("request") << ++m_lastRequestId
- << QByteArray("moveObject") << childId << newParentId;
- sendMessage(ds.data());
- return m_lastRequestId;
-}
-
-int QQmlInspectorClient::destroyObject(int objectId)
-{
- QPacket ds(connection()->currentDataStreamVersion());
- ds << QByteArray("request") << ++m_lastRequestId
- << QByteArray("destroyObject") << objectId;
- sendMessage(ds.data());
- return m_lastRequestId;
-}
-
-void QQmlInspectorClient::messageReceived(const QByteArray &message)
-{
- QPacket ds(connection()->currentDataStreamVersion(), message);
- QByteArray type;
- ds >> type;
-
- if (type != QByteArray("response")) {
- qDebug() << "Unhandled message of type" << type;
- return;
- }
-
- int responseId;
- bool result;
- ds >> responseId >> result;
- emit responseReceived(responseId, result);
-}
diff --git a/tests/auto/qml/debugger/shared/qqmlinspectorclient.h b/tests/auto/qml/debugger/shared/qqmlinspectorclient.h
deleted file mode 100644
index bfb489c8f7..0000000000
--- a/tests/auto/qml/debugger/shared/qqmlinspectorclient.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/****************************************************************************
-**
-** 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$
-**
-****************************************************************************/
-#ifndef QQMLINSPECTORCLIENT_H
-#define QQMLINSPECTORCLIENT_H
-
-#include <private/qqmldebugclient_p.h>
-
-class QQmlInspectorClient : public QQmlDebugClient
-{
- Q_OBJECT
-
-public:
- QQmlInspectorClient(QQmlDebugConnection *connection);
-
- int setInspectToolEnabled(bool enabled);
- int setShowAppOnTop(bool showOnTop);
- int setAnimationSpeed(qreal speed);
- int select(const QList<int> &objectIds);
- int createObject(const QString &qml, int parentId, const QStringList &imports,
- const QString &filename);
- int moveObject(int childId, int newParentId);
- int destroyObject(int objectId);
-
-signals:
- void responseReceived(int requestId, bool result);
-
-protected:
- void messageReceived(const QByteArray &message);
-
-private:
- int m_lastRequestId;
-};
-
-#endif // QQMLINSPECTORCLIENT_H
diff --git a/tests/auto/qml/debugger/shared/qqmlinspectorclient.pri b/tests/auto/qml/debugger/shared/qqmlinspectorclient.pri
deleted file mode 100644
index c136e1313a..0000000000
--- a/tests/auto/qml/debugger/shared/qqmlinspectorclient.pri
+++ /dev/null
@@ -1,3 +0,0 @@
-HEADERS += $$PWD/qqmlinspectorclient.h
-
-SOURCES += $$PWD/qqmlinspectorclient.cpp