diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2016-12-07 14:24:04 +0100 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2016-12-09 12:51:51 +0000 |
commit | bff7302fc277d18b5bd4ad95d35b9e1bbc2be001 (patch) | |
tree | 8ba4cc517e513b0a519ebdab4b99ba1146960d8c /tests | |
parent | 3dd96630a2823ff9723a399c84303f565abce455 (diff) |
V4 Debugger: Add an option to pass additional context for evaluate
Interpret the "context" option as an ID for a QObject whose QML context
is then injected when evaluating the expression. The QObject needs to
be tracked by some other debug service for this to work, e.g. the QML
debugger or the inspector.
Task-number: QTCREATORBUG-17177
Change-Id: I6a9e8b9ae23e8bb67ed1905a2ef73f7c4faeb990
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'tests')
3 files changed, 85 insertions, 10 deletions
diff --git a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/qqmldebugjs.pro b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/qqmldebugjs.pro index 79e772c1ee..cbaf3b5309 100644 --- a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/qqmldebugjs.pro +++ b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/qqmldebugjs.pro @@ -9,6 +9,7 @@ SOURCES += tst_qqmldebugjs.cpp INCLUDEPATH += ../../shared include(../../../../shared/util.pri) include(../../shared/debugutil.pri) +include(../../shared/qqmlenginedebugclient.pri) TESTDATA = data/* diff --git a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/tst_qqmldebugjs.cpp b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/tst_qqmldebugjs.cpp index d1150be831..31b8d63ec2 100644 --- a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/tst_qqmldebugjs.cpp +++ b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/tst_qqmldebugjs.cpp @@ -27,6 +27,7 @@ ****************************************************************************/ #include "debugutil_p.h" +#include "../../shared/qqmlenginedebugclient.h" #include "../../../../shared/util.h" #include <private/qqmldebugclient_p.h> @@ -52,6 +53,7 @@ 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"; @@ -215,6 +217,8 @@ private slots: void evaluateInLocalScope_data() { targetData(); } void evaluateInLocalScope(); + void evaluateInContext(); + void getScripts_data() { targetData(); } void getScripts(); @@ -257,7 +261,7 @@ public: void interrupt(); void continueDebugging(StepAction stepAction); - void evaluate(QString expr, int frame = -1); + 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); @@ -280,6 +284,7 @@ signals: void connected(); void interruptRequested(); void result(); + void failure(); void stopped(); private: @@ -340,13 +345,14 @@ void QJSDebugClient::continueDebugging(StepAction action) sendMessage(packMessage(V8REQUEST, json.toString().toUtf8())); } -void QJSDebugClient::evaluate(QString expr, int frame) +void QJSDebugClient::evaluate(QString expr, int frame, int context) { // { "seq" : <number>, // "type" : "request", // "command" : "evaluate", // "arguments" : { "expression" : <expression to evaluate>, - // "frame" : <number> + // "frame" : <number>, + // "context" : <object ID> // } // } VARIANTMAPINIT; @@ -358,6 +364,9 @@ void QJSDebugClient::evaluate(QString expr, int frame) 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); } @@ -684,6 +693,7 @@ void QJSDebugClient::messageReceived(const QByteArray &data) if (type == "response") { if (!value.value("success").toBool()) { + emit failure(); qDebug() << "Received success == false response from application"; return; } @@ -1394,6 +1404,58 @@ void tst_QQmlDebugJS::evaluateInLocalScope() 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()); diff --git a/tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp b/tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp index a23b7e37eb..6793596174 100644 --- a/tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp +++ b/tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp @@ -41,6 +41,7 @@ #include <private/qv4isel_moth_p.h> #include <private/qv4string_p.h> #include <private/qqmlbuiltinfunctions_p.h> +#include <private/qqmldebugservice_p.h> using namespace QV4; using namespace QV4::Debugging; @@ -203,8 +204,8 @@ public slots: while (!m_expressionRequests.isEmpty()) { Q_ASSERT(debugger->state() == QV4Debugger::Paused); ExpressionRequest request = m_expressionRequests.takeFirst(); - ExpressionEvalJob job(debugger->engine(), request.frameNr, request.expression, - &collector); + ExpressionEvalJob job(debugger->engine(), request.frameNr, request.context, + request.expression, &collector); debugger->runInEngine(&job); m_expressionResults << job.returnValue(); m_expressionRefs << job.refs(); @@ -276,6 +277,7 @@ public: struct ExpressionRequest { QString expression; int frameNr; + int context; }; QVector<ExpressionRequest> m_expressionRequests; QList<QJsonObject> m_expressionResults; @@ -726,24 +728,34 @@ void tst_qv4debugger::evaluateExpression() TestAgent::ExpressionRequest request; request.expression = "x"; request.frameNr = 0; + request.context = -1; // no extra context m_debuggerAgent->m_expressionRequests << request; request.expression = "x"; request.frameNr = 1; m_debuggerAgent->m_expressionRequests << request; + request.context = 5355; // invalid context object + m_debuggerAgent->m_expressionRequests << request; + + QObject object; // some object without QML context + request.context = QQmlDebugService::idForObject(&object); + m_debuggerAgent->m_expressionRequests << request; + debugger()->addBreakPoint("evaluateExpression", 3); evaluateJavaScript(script, "evaluateExpression"); - QCOMPARE(m_debuggerAgent->m_expressionRefs.count(), 2); + QCOMPARE(m_debuggerAgent->m_expressionRefs.count(), 4); QCOMPARE(m_debuggerAgent->m_expressionRefs[0].size(), 1); QJsonObject result0 = m_debuggerAgent->m_expressionRefs[0].first().toObject(); QCOMPARE(result0.value("type").toString(), QStringLiteral("number")); QCOMPARE(result0.value("value").toInt(), 10); - QCOMPARE(m_debuggerAgent->m_expressionRefs[1].size(), 1); - QJsonObject result1 = m_debuggerAgent->m_expressionRefs[1].first().toObject(); - QCOMPARE(result1.value("type").toString(), QStringLiteral("number")); - QCOMPARE(result1.value("value").toInt(), 20); + for (int i = 1; i < 4; ++i) { + QCOMPARE(m_debuggerAgent->m_expressionRefs[i].size(), 1); + QJsonObject result1 = m_debuggerAgent->m_expressionRefs[1].first().toObject(); + QCOMPARE(result1.value("type").toString(), QStringLiteral("number")); + QCOMPARE(result1.value("value").toInt(), 20); + } } QTEST_MAIN(tst_qv4debugger) |