249416a3b94bb92d0dbf8d3d99a74fa6d8b05293
[qtdeclarative-opensource-src.git] /
1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the test suite of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21 ** included in the packaging of this file. Please review the following
22 ** information to ensure the GNU General Public License requirements will
23 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24 **
25 ** $QT_END_LICENSE$
26 **
27 ****************************************************************************/
28
29 #include "qqmlinspectorclient.h"
30 #include "qqmlenginedebugclient.h"
31 #include "../shared/debugutil_p.h"
32 #include "../../../shared/util.h"
33
34 #include <private/qqmldebugconnection_p.h>
35
36 #include <QtTest/qtest.h>
37 #include <QtTest/qsignalspy.h>
38 #include <QtNetwork/qhostaddress.h>
39 #include <QtCore/qtimer.h>
40 #include <QtCore/qdebug.h>
41 #include <QtCore/qthread.h>
42 #include <QtCore/qlibraryinfo.h>
43
44 class tst_QQmlEngineDebugInspectorIntegration : public QQmlDebugTest
45 {
46     Q_OBJECT
47
48 private:
49     ConnectResult init(bool restrictServices);
50     QList<QQmlDebugClient *> createClients() override;
51
52     QmlDebugObjectReference findRootObject();
53
54     QPointer<QQmlInspectorClient> m_inspectorClient;
55     QPointer<QQmlEngineDebugClient> m_engineDebugClient;
56     QPointer<QQmlInspectorResultRecipient> m_recipient;
57
58 private slots:
59     void connect_data();
60     void connect();
61     void objectLocationLookup();
62     void select();
63     void createObject();
64     void moveObject();
65     void destroyObject();
66 };
67
68 QmlDebugObjectReference tst_QQmlEngineDebugInspectorIntegration::findRootObject()
69 {
70     bool success = false;
71     m_engineDebugClient->queryAvailableEngines(&success);
72
73     if (!QQmlDebugTest::waitForSignal(m_engineDebugClient, SIGNAL(result())))
74         return QmlDebugObjectReference();
75
76     m_engineDebugClient->queryRootContexts(m_engineDebugClient->engines()[0].debugId, &success);
77     if (!QQmlDebugTest::waitForSignal(m_engineDebugClient, SIGNAL(result())))
78         return QmlDebugObjectReference();
79
80     int count = m_engineDebugClient->rootContext().contexts.count();
81     m_engineDebugClient->queryObject(
82                 m_engineDebugClient->rootContext().contexts[count - 1].objects[0], &success);
83     if (!QQmlDebugTest::waitForSignal(m_engineDebugClient, SIGNAL(result())))
84         return QmlDebugObjectReference();
85     return m_engineDebugClient->object();
86 }
87
88 QQmlDebugTest::ConnectResult tst_QQmlEngineDebugInspectorIntegration::init(bool restrictServices)
89 {
90     return QQmlDebugTest::connect(
91                 QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qml",
92                 restrictServices ? QStringLiteral("QmlDebugger,QmlInspector") : QString(),
93                 testFile("qtquick2.qml"), true);
94 }
95
96 QList<QQmlDebugClient *> tst_QQmlEngineDebugInspectorIntegration::createClients()
97 {
98     m_inspectorClient = new QQmlInspectorClient(m_connection);
99     m_engineDebugClient = new QQmlEngineDebugClient(m_connection);
100     m_recipient = new QQmlInspectorResultRecipient(m_inspectorClient);
101     QObject::connect(m_inspectorClient.data(), &QQmlInspectorClient::responseReceived,
102                      m_recipient.data(), &QQmlInspectorResultRecipient::recordResponse);
103     return QList<QQmlDebugClient *>({m_inspectorClient, m_engineDebugClient});
104 }
105
106 void tst_QQmlEngineDebugInspectorIntegration::connect_data()
107 {
108     QTest::addColumn<bool>("restrictMode");
109     QTest::newRow("unrestricted") << false;
110     QTest::newRow("restricted") << true;
111 }
112
113 void tst_QQmlEngineDebugInspectorIntegration::connect()
114 {
115     QFETCH(bool, restrictMode);
116     QCOMPARE(init(restrictMode), ConnectSuccess);
117 }
118
119 void tst_QQmlEngineDebugInspectorIntegration::objectLocationLookup()
120 {
121     QCOMPARE(init(true), ConnectSuccess);
122
123     bool success = false;
124     QmlDebugObjectReference rootObject = findRootObject();
125     QVERIFY(rootObject.debugId != -1);
126     const QString fileName = QFileInfo(rootObject.source.url.toString()).fileName();
127     int lineNumber = rootObject.source.lineNumber;
128     int columnNumber = rootObject.source.columnNumber;
129     m_engineDebugClient->queryObjectsForLocation(fileName, lineNumber,
130                                         columnNumber, &success);
131     QVERIFY(success);
132     QVERIFY(QQmlDebugTest::waitForSignal(m_engineDebugClient, SIGNAL(result())));
133
134     foreach (QmlDebugObjectReference child, rootObject.children) {
135         success = false;
136         lineNumber = child.source.lineNumber;
137         columnNumber = child.source.columnNumber;
138         m_engineDebugClient->queryObjectsForLocation(fileName, lineNumber,
139                                        columnNumber, &success);
140         QVERIFY(success);
141         QVERIFY(QQmlDebugTest::waitForSignal(m_engineDebugClient, SIGNAL(result())));
142     }
143 }
144
145 void tst_QQmlEngineDebugInspectorIntegration::select()
146 {
147     QCOMPARE(init(true), ConnectSuccess);
148
149     QmlDebugObjectReference rootObject = findRootObject();
150     QList<int> childIds;
151     int requestId = 0;
152     foreach (const QmlDebugObjectReference &child, rootObject.children) {
153         requestId = m_inspectorClient->select(QList<int>() << child.debugId);
154         QTRY_COMPARE(m_recipient->lastResponseId, requestId);
155         QVERIFY(m_recipient->lastResult);
156         childIds << child.debugId;
157     }
158     requestId = m_inspectorClient->select(childIds);
159     QTRY_COMPARE(m_recipient->lastResponseId, requestId);
160     QVERIFY(m_recipient->lastResult);
161 }
162
163 void tst_QQmlEngineDebugInspectorIntegration::createObject()
164 {
165     QCOMPARE(init(true), ConnectSuccess);
166
167     QString qml = QLatin1String("Rectangle {\n"
168                                 "  id: xxxyxxx\n"
169                                 "  width: 10\n"
170                                 "  height: 10\n"
171                                 "  color: \"blue\"\n"
172                                 "}");
173
174     QmlDebugObjectReference rootObject = findRootObject();
175     QVERIFY(rootObject.debugId != -1);
176     QCOMPARE(rootObject.children.length(), 2);
177
178     int requestId = m_inspectorClient->createObject(
179                 qml, rootObject.debugId, QStringList() << QLatin1String("import QtQuick 2.0"),
180                 QLatin1String("testcreate.qml"));
181     QTRY_COMPARE(m_recipient->lastResponseId, requestId);
182     QVERIFY(m_recipient->lastResult);
183
184     rootObject = findRootObject();
185     QVERIFY(rootObject.debugId != -1);
186     QCOMPARE(rootObject.children.length(), 3);
187     QCOMPARE(rootObject.children[2].idString, QLatin1String("xxxyxxx"));
188 }
189
190 void tst_QQmlEngineDebugInspectorIntegration::moveObject()
191 {
192     QCOMPARE(init(true), ConnectSuccess);
193
194     QCOMPARE(m_inspectorClient->state(), QQmlDebugClient::Enabled);
195     QmlDebugObjectReference rootObject = findRootObject();
196     QVERIFY(rootObject.debugId != -1);
197     QCOMPARE(rootObject.children.length(), 2);
198
199     int childId = rootObject.children[0].debugId;
200     int requestId = m_inspectorClient->moveObject(childId, rootObject.children[1].debugId);
201     QTRY_COMPARE(m_recipient->lastResponseId, requestId);
202     QVERIFY(m_recipient->lastResult);
203
204     rootObject = findRootObject();
205     QVERIFY(rootObject.debugId != -1);
206     QCOMPARE(rootObject.children.length(), 1);
207     bool success = false;
208     m_engineDebugClient->queryObject(rootObject.children[0], &success);
209     QVERIFY(success);
210     QVERIFY(QQmlDebugTest::waitForSignal(m_engineDebugClient, SIGNAL(result())));
211     QCOMPARE(m_engineDebugClient->object().children.length(), 1);
212     QCOMPARE(m_engineDebugClient->object().children[0].debugId, childId);
213 }
214
215 void tst_QQmlEngineDebugInspectorIntegration::destroyObject()
216 {
217     QCOMPARE(init(true), ConnectSuccess);
218
219     QCOMPARE(m_inspectorClient->state(), QQmlDebugClient::Enabled);
220     QmlDebugObjectReference rootObject = findRootObject();
221     QVERIFY(rootObject.debugId != -1);
222     QCOMPARE(rootObject.children.length(), 2);
223
224     int requestId = m_inspectorClient->destroyObject(rootObject.children[0].debugId);
225     QTRY_COMPARE(m_recipient->lastResponseId, requestId);
226     QVERIFY(m_recipient->lastResult);
227
228     rootObject = findRootObject();
229     QVERIFY(rootObject.debugId != -1);
230     QCOMPARE(rootObject.children.length(), 1);
231     bool success = false;
232     m_engineDebugClient->queryObject(rootObject.children[0], &success);
233     QVERIFY(success);
234     QVERIFY(QQmlDebugTest::waitForSignal(m_engineDebugClient, SIGNAL(result())));
235     QCOMPARE(m_engineDebugClient->object().children.length(), 0);
236 }
237
238 QTEST_MAIN(tst_QQmlEngineDebugInspectorIntegration)
239
240 #include "tst_qqmlenginedebuginspectorintegration.moc"