Support multiple QML engines in V4 debugger

Whenever the debugger is paused, there is exactly one engine that
caused the debuggerPaused() slot to be called. We can only interact
with that engine in any meaningful way.

Of course you can shoot yourself in the foot with this tool. You can,
for example, set a breakpoint that will be hit by multiple engines and
then get confused about which engine just hit the breakpoint. Similar
things are also possible with other kinds of debuggers, though. If this
becomes a problem we can add an engine ID to the responses.

Also, this does not fix the other debug services. So you might still
not see the "correct" locals and expressions from the
QQmlEngineDebugService while the debugger is not paused.

Task-number: QTBUG-49615
Change-Id: Ie044f0aedb51481c4cf851635d7c12839251cbd0
Reviewed-by: Erik Verbruggen <erik.verbruggen@theqtcompany.com>
This commit is contained in:
Ulf Hermann 2015-11-24 16:17:27 +01:00
parent ec5a886d4b
commit c3f03bbff1
22 changed files with 238 additions and 72 deletions

View File

@ -189,6 +189,12 @@ void QV4Debugger::setBreakOnThrow(bool onoff)
m_breakOnThrow = onoff;
}
void QV4Debugger::clearPauseRequest()
{
QMutexLocker locker(&m_lock);
m_pauseRequested = false;
}
QV4Debugger::ExecutionState QV4Debugger::currentExecutionState() const
{
ExecutionState state;

View File

@ -124,6 +124,8 @@ public:
void setBreakOnThrow(bool onoff);
void clearPauseRequest();
// used for testing
struct ExecutionState
{

View File

@ -44,22 +44,19 @@ QV4DebuggerAgent::QV4DebuggerAgent(QV4DebugServiceImpl *debugService)
: m_breakOnThrow(false), m_debugService(debugService)
{}
QV4Debugger *QV4DebuggerAgent::firstDebugger() const
QV4Debugger *QV4DebuggerAgent::pausedDebugger() const
{
// Currently only 1 single engine is supported, so:
if (m_debuggers.isEmpty())
return 0;
else
return m_debuggers.first();
foreach (QV4Debugger *debugger, m_debuggers) {
if (debugger->state() == QV4Debugger::Paused)
return debugger;
}
return 0;
}
bool QV4DebuggerAgent::isRunning() const
{
// Currently only 1 single engine is supported, so:
if (QV4Debugger *debugger = firstDebugger())
return debugger->state() == QV4Debugger::Running;
else
return false;
// "running" means none of the engines are paused.
return pausedDebugger() == 0;
}
void QV4DebuggerAgent::debuggerPaused(QV4Debugger *debugger, QV4Debugger::PauseReason reason)
@ -221,4 +218,10 @@ void QV4DebuggerAgent::setBreakOnThrow(bool onoff)
}
}
void QV4DebuggerAgent::clearAllPauseRequests()
{
foreach (QV4Debugger *debugger, m_debuggers)
debugger->clearPauseRequest();
}
QT_END_NAMESPACE

View File

@ -46,7 +46,7 @@ class QV4DebuggerAgent : public QObject
public:
QV4DebuggerAgent(QV4DebugServiceImpl *m_debugService);
QV4Debugger *firstDebugger() const;
QV4Debugger *pausedDebugger() const;
bool isRunning() const;
void addDebugger(QV4Debugger *debugger);
@ -64,6 +64,7 @@ public:
bool breakOnThrow() const { return m_breakOnThrow; }
void setBreakOnThrow(bool onoff);
void clearAllPauseRequests();
public slots:
void debuggerPaused(QV4Debugger *debugger, QV4Debugger::PauseReason reason);

View File

@ -271,7 +271,11 @@ public:
int toFrame = arguments.value(QStringLiteral("toFrame")).toInt(fromFrame + 10);
// no idea what the bottom property is for, so we'll ignore it.
QV4Debugger *debugger = debugService->debuggerAgent.firstDebugger();
QV4Debugger *debugger = debugService->debuggerAgent.pausedDebugger();
if (!debugger) {
createErrorResponse(QStringLiteral("Debugger has to be paused to retrieve backtraces."));
return;
}
QJsonArray frameArray;
QVector<QV4::StackFrame> frames = debugger->stackTrace(toFrame);
@ -308,7 +312,12 @@ public:
const int frameNr = arguments.value(QStringLiteral("number")).toInt(
debugService->selectedFrame());
QV4Debugger *debugger = debugService->debuggerAgent.firstDebugger();
QV4Debugger *debugger = debugService->debuggerAgent.pausedDebugger();
if (!debugger) {
createErrorResponse(QStringLiteral("Debugger has to be paused to retrieve frames."));
return;
}
QVector<QV4::StackFrame> frames = debugger->stackTrace(frameNr + 1);
if (frameNr < 0 || frameNr >= frames.size()) {
createErrorResponse(QStringLiteral("frame command has invalid frame number"));
@ -341,7 +350,12 @@ public:
debugService->selectedFrame());
const int scopeNr = arguments.value(QStringLiteral("number")).toInt(0);
QV4Debugger *debugger = debugService->debuggerAgent.firstDebugger();
QV4Debugger *debugger = debugService->debuggerAgent.pausedDebugger();
if (!debugger) {
createErrorResponse(QStringLiteral("Debugger has to be paused to retrieve scope."));
return;
}
QVector<QV4::StackFrame> frames = debugger->stackTrace(frameNr + 1);
if (frameNr < 0 || frameNr >= frames.size()) {
createErrorResponse(QStringLiteral("scope command has invalid frame number"));
@ -399,7 +413,12 @@ public:
// decypher the payload:
QJsonObject arguments = req.value(QStringLiteral("arguments")).toObject();
QV4Debugger *debugger = debugService->debuggerAgent.firstDebugger();
QV4Debugger *debugger = debugService->debuggerAgent.pausedDebugger();
if (!debugger) {
createErrorResponse(QStringLiteral("Debugger has to be paused in order to continue."));
return;
}
debugService->debuggerAgent.clearAllPauseRequests();
if (arguments.empty()) {
debugger->resume(QV4Debugger::FullThrottle);
@ -507,7 +526,12 @@ public:
}
// do it:
QV4Debugger *debugger = debugService->debuggerAgent.firstDebugger();
QV4Debugger *debugger = debugService->debuggerAgent.pausedDebugger();
if (!debugger) {
createErrorResponse(QStringLiteral("Debugger has to be paused to retrieve scripts."));
return;
}
GatherSourcesJob job(debugger->engine());
debugger->runInEngine(&job);
@ -562,8 +586,8 @@ public:
virtual void handleRequest()
{
QV4Debugger *debugger = debugService->debuggerAgent.firstDebugger();
if (debugger->state() == QV4Debugger::Paused) {
QV4Debugger *debugger = debugService->debuggerAgent.pausedDebugger();
if (debugger) {
QJsonObject arguments = req.value(QStringLiteral("arguments")).toObject();
QString expression = arguments.value(QStringLiteral("expression")).toString();
const int frame = arguments.value(QStringLiteral("frame")).toInt(0);

View File

@ -1,23 +1,4 @@
CONFIG += testcase
TARGET = tst_qqmldebugjs
QT += qml testlib gui-private core-private
osx:CONFIG -= app_bundle
TEMPLATE = subdirs
SUBDIRS = qqmldebugjs qqmldebugjsserver
SOURCES += tst_qqmldebugjs.cpp
INCLUDEPATH += ../shared
include(../../../shared/util.pri)
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
qqmldebugjs.depends = qqmldebugjsserver

View File

@ -0,0 +1,24 @@
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)
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

View File

@ -33,7 +33,7 @@
//QQmlDebugTest
#include "debugutil_p.h"
#include "../../../shared/util.h"
#include "../../../../shared/util.h"
#include <private/qqmldebugclient_p.h>
#include <private/qqmldebugconnection_p.h>
@ -162,7 +162,7 @@ class tst_QQmlDebugJS : public QQmlDataTest
{
Q_OBJECT
void init(const QString &qmlFile = QString(TEST_QMLFILE), bool blockMode = true,
void init(bool qmlscene, const QString &qmlFile = QString(TEST_QMLFILE), bool blockMode = true,
bool restrictServices = false);
private slots:
@ -173,43 +173,65 @@ private slots:
void connect_data();
void connect();
void interrupt_data() { targetData(); }
void interrupt();
void getVersion_data() { targetData(); }
void getVersion();
// 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 setBreakpointInFunction(); //NOT SUPPORTED
// void setBreakpointOnEvent();
// 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(); // Not supported yet.
// void evaluateInLocalScope(); // Not supported yet.
void getScripts_data() { targetData(); }
void getScripts();
// void profile(); //NOT SUPPORTED
@ -217,6 +239,8 @@ private slots:
// void verifyQMLOptimizerDisabled();
private:
void targetData();
QQmlDebugProcess *process;
QJSDebugClient *client;
QQmlDebugConnection *connection;
@ -826,10 +850,16 @@ void tst_QQmlDebugJS::cleanupTestCase()
// qDebug() << "Time Elapsed:" << t.elapsed();
}
void tst_QQmlDebugJS::init(const QString &qmlFile, bool blockMode, bool restrictServices)
void tst_QQmlDebugJS::init(bool qmlscene, const QString &qmlFile, bool blockMode,
bool restrictServices)
{
connection = new QQmlDebugConnection();
process = new QQmlDebugProcess(QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene", this);
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);
@ -884,17 +914,23 @@ void tst_QQmlDebugJS::connect_data()
{
QTest::addColumn<bool>("blockMode");
QTest::addColumn<bool>("restrictMode");
QTest::newRow("normal/unrestricted") << false << false;
QTest::newRow("block/unrestricted") << true << false;
QTest::newRow("normal/restricted") << false << true;
QTest::newRow("block/restricted") << true << true;
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);
init(QString(TEST_QMLFILE), blockMode, restrictMode);
QFETCH(bool, qmlscene);
init(qmlscene, QString(TEST_QMLFILE), blockMode, restrictMode);
client->connect();
QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(connected())));
}
@ -903,7 +939,8 @@ void tst_QQmlDebugJS::interrupt()
{
//void connect()
init();
QFETCH(bool, qmlscene);
init(qmlscene);
client->connect();
client->interrupt();
@ -914,7 +951,8 @@ void tst_QQmlDebugJS::getVersion()
{
//void version()
init();
QFETCH(bool, qmlscene);
init(qmlscene);
client->connect();
QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(connected())));
@ -939,7 +977,8 @@ void tst_QQmlDebugJS::disconnect()
{
//void disconnect()
init();
QFETCH(bool, qmlscene);
init(qmlscene);
client->connect();
client->disconnect();
@ -949,9 +988,10 @@ void tst_QQmlDebugJS::disconnect()
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 = 39;
init(ONCOMPLETED_QMLFILE);
init(qmlscene, ONCOMPLETED_QMLFILE);
client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true);
client->connect();
@ -969,9 +1009,10 @@ void tst_QQmlDebugJS::setBreakpointInScriptOnCompleted()
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 = 39;
init(CREATECOMPONENT_QMLFILE);
init(qmlscene, CREATECOMPONENT_QMLFILE);
client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true);
client->connect();
@ -988,8 +1029,9 @@ void tst_QQmlDebugJS::setBreakpointInScriptOnComponentCreated()
void tst_QQmlDebugJS::setBreakpointInScriptOnTimerCallback()
{
QFETCH(bool, qmlscene);
int sourceLine = 40;
init(TIMER_QMLFILE);
init(qmlscene, TIMER_QMLFILE);
client->connect();
//We can set the breakpoint after connect() here because the timer is repeating and if we miss
@ -1009,9 +1051,10 @@ void tst_QQmlDebugJS::setBreakpointInScriptOnTimerCallback()
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 = 35;
init(LOADJSFILE_QMLFILE);
init(qmlscene, LOADJSFILE_QMLFILE);
client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(TEST_JSFILE), sourceLine, -1, true);
client->connect();
@ -1029,10 +1072,11 @@ void tst_QQmlDebugJS::setBreakpointInScriptInDifferentFile()
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 = 39;
int actualLine = 41;
init(BREAKPOINTRELOCATION_QMLFILE);
init(qmlscene, BREAKPOINTRELOCATION_QMLFILE);
client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(BREAKPOINTRELOCATION_QMLFILE), sourceLine, -1, true);
client->connect();
@ -1051,10 +1095,11 @@ void tst_QQmlDebugJS::setBreakpointInScriptOnComment()
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 = 40;
int actualLine = 41;
init(BREAKPOINTRELOCATION_QMLFILE);
init(qmlscene, BREAKPOINTRELOCATION_QMLFILE);
client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(BREAKPOINTRELOCATION_QMLFILE), sourceLine, -1, true);
client->connect();
@ -1073,9 +1118,10 @@ void tst_QQmlDebugJS::setBreakpointInScriptOnEmptyLine()
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 = 44;
init(BREAKPOINTRELOCATION_QMLFILE);
init(qmlscene, BREAKPOINTRELOCATION_QMLFILE);
client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(BREAKPOINTRELOCATION_QMLFILE), sourceLine, -1, true);
client->connect();
@ -1092,9 +1138,10 @@ void tst_QQmlDebugJS::setBreakpointInScriptOnOptimizedBinding()
void tst_QQmlDebugJS::setBreakpointInScriptWithCondition()
{
QFETCH(bool, qmlscene);
int out = 10;
int sourceLine = 42;
init(CONDITION_QMLFILE);
init(qmlscene, CONDITION_QMLFILE);
client->connect();
//The breakpoint is in a timer loop so we can set it after connect().
@ -1128,7 +1175,8 @@ void tst_QQmlDebugJS::setBreakpointInScriptWithCondition()
void tst_QQmlDebugJS::setBreakpointInScriptThatQuits()
{
init(QUIT_QMLFILE);
QFETCH(bool, qmlscene);
init(qmlscene, QUIT_QMLFILE);
int sourceLine = 41;
@ -1187,10 +1235,11 @@ void tst_QQmlDebugJS::setBreakpointOnEvent()
void tst_QQmlDebugJS::clearBreakpoint()
{
//void clearBreakpoint(int breakpoint);
QFETCH(bool, qmlscene);
int sourceLine1 = 42;
int sourceLine2 = 43;
init(CHANGEBREAKPOINT_QMLFILE);
init(qmlscene, CHANGEBREAKPOINT_QMLFILE);
client->connect();
//The breakpoints are in a timer loop so we can set them after connect().
@ -1234,8 +1283,9 @@ void tst_QQmlDebugJS::clearBreakpoint()
void tst_QQmlDebugJS::setExceptionBreak()
{
//void setExceptionBreak(QString type, bool enabled = false);
QFETCH(bool, qmlscene);
init(EXCEPTION_QMLFILE);
init(qmlscene, EXCEPTION_QMLFILE);
client->setExceptionBreak(QJSDebugClient::All,true);
client->connect();
QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
@ -1244,9 +1294,10 @@ void tst_QQmlDebugJS::setExceptionBreak()
void tst_QQmlDebugJS::stepNext()
{
//void continueDebugging(StepAction stepAction, int stepCount = 1);
QFETCH(bool, qmlscene);
int sourceLine = 42;
init(STEPACTION_QMLFILE);
init(qmlscene, STEPACTION_QMLFILE);
client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(STEPACTION_QMLFILE), sourceLine, -1, true);
client->connect();
@ -1267,10 +1318,11 @@ void tst_QQmlDebugJS::stepNext()
void tst_QQmlDebugJS::stepIn()
{
//void continueDebugging(StepAction stepAction, int stepCount = 1);
QFETCH(bool, qmlscene);
int sourceLine = 46;
int actualLine = 42;
init(STEPACTION_QMLFILE);
init(qmlscene, STEPACTION_QMLFILE);
client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(STEPACTION_QMLFILE), sourceLine, 1, true);
client->connect();
@ -1291,10 +1343,11 @@ void tst_QQmlDebugJS::stepIn()
void tst_QQmlDebugJS::stepOut()
{
//void continueDebugging(StepAction stepAction, int stepCount = 1);
QFETCH(bool, qmlscene);
int sourceLine = 42;
int actualLine = 46;
init(STEPACTION_QMLFILE);
init(qmlscene, STEPACTION_QMLFILE);
client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(STEPACTION_QMLFILE), sourceLine, -1, true);
client->connect();
@ -1315,10 +1368,11 @@ void tst_QQmlDebugJS::stepOut()
void tst_QQmlDebugJS::continueDebugging()
{
//void continueDebugging(StepAction stepAction, int stepCount = 1);
QFETCH(bool, qmlscene);
int sourceLine1 = 46;
int sourceLine2 = 43;
init(STEPACTION_QMLFILE);
init(qmlscene, STEPACTION_QMLFILE);
client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(STEPACTION_QMLFILE), sourceLine1, -1, true);
client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(STEPACTION_QMLFILE), sourceLine2, -1, true);
@ -1340,9 +1394,10 @@ void tst_QQmlDebugJS::continueDebugging()
void tst_QQmlDebugJS::backtrace()
{
//void backtrace(int fromFrame = -1, int toFrame = -1, bool bottom = false);
QFETCH(bool, qmlscene);
int sourceLine = 39;
init(ONCOMPLETED_QMLFILE);
init(qmlscene, ONCOMPLETED_QMLFILE);
client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true);
client->connect();
@ -1355,9 +1410,10 @@ void tst_QQmlDebugJS::backtrace()
void tst_QQmlDebugJS::getFrameDetails()
{
//void frame(int number = -1);
QFETCH(bool, qmlscene);
int sourceLine = 39;
init(ONCOMPLETED_QMLFILE);
init(qmlscene, ONCOMPLETED_QMLFILE);
client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true);
client->connect();
@ -1370,9 +1426,10 @@ void tst_QQmlDebugJS::getFrameDetails()
void tst_QQmlDebugJS::getScopeDetails()
{
//void scope(int number = -1, int frameNumber = -1);
QFETCH(bool, qmlscene);
int sourceLine = 39;
init(ONCOMPLETED_QMLFILE);
init(qmlscene, ONCOMPLETED_QMLFILE);
client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true);
client->connect();
@ -1443,7 +1500,8 @@ void tst_QQmlDebugJS::getScripts()
{
//void scripts(int types = -1, QList<int> ids = QList<int>(), bool includeSource = false, QVariant filter = QVariant());
init();
QFETCH(bool, qmlscene);
init(qmlscene);
client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QString(TEST_QMLFILE), 40, -1, true);
client->connect();
@ -1461,6 +1519,13 @@ void tst_QQmlDebugJS::getScripts()
QVERIFY(scripts.first().toMap()[QStringLiteral("name")].toString().endsWith(QStringLiteral("data/test.qml")));
}
void tst_QQmlDebugJS::targetData()
{
QTest::addColumn<bool>("qmlscene");
QTest::newRow("custom") << false;
QTest::newRow("qmlscene") << true;
}
QTEST_MAIN(tst_QQmlDebugJS)
#include "tst_qqmldebugjs.moc"

View File

@ -0,0 +1,48 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL21$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** As a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QtGui/qguiapplication.h>
#include <QtQml/qqmlengine.h>
#include <QtQml/qqmlapplicationengine.h>
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQmlEngine someWeirdEngine; // add another engine to cause some trouble
QQmlApplicationEngine engine;
engine.load(QUrl::fromLocalFile(QLatin1String(argv[argc - 1])));
return app.exec();
}

View File

@ -0,0 +1,12 @@
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