1 /****************************************************************************
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the test suite of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
43 #include <QtCore/QProcess>
44 #include <QtCore/QTimer>
45 #include <QtCore/QFileInfo>
46 #include <QtCore/QDir>
47 #include <QtCore/QMutex>
48 #include <QtCore/QLibraryInfo>
49 #include <QtDeclarative/private/qdeclarativedebugclient_p.h>
50 #include <QtDeclarative/QJSEngine>
52 //QDeclarativeDebugTest
53 #include "../shared/debugutil_p.h"
54 #include "../../shared/util.h"
56 const char *SEQ = "seq";
57 const char *TYPE = "type";
58 const char *COMMAND = "command";
59 const char *ARGUMENTS = "arguments";
60 const char *STEPACTION = "stepaction";
61 const char *STEPCOUNT = "stepcount";
62 const char *EXPRESSION = "expression";
63 const char *FRAME = "frame";
64 const char *GLOBAL = "global";
65 const char *DISABLEBREAK = "disable_break";
66 const char *HANDLES = "handles";
67 const char *INCLUDESOURCE = "includeSource";
68 const char *FROMFRAME = "fromFrame";
69 const char *TOFRAME = "toFrame";
70 const char *BOTTOM = "bottom";
71 const char *NUMBER = "number";
72 const char *FRAMENUMBER = "frameNumber";
73 const char *TYPES = "types";
74 const char *IDS = "ids";
75 const char *FILTER = "filter";
76 const char *FROMLINE = "fromLine";
77 const char *TOLINE = "toLine";
78 const char *TARGET = "target";
79 const char *LINE = "line";
80 const char *COLUMN = "column";
81 const char *ENABLED = "enabled";
82 const char *CONDITION = "condition";
83 const char *IGNORECOUNT = "ignoreCount";
84 const char *BREAKPOINT = "breakpoint";
85 const char *FLAGS = "flags";
87 const char *CONTINEDEBUGGING = "continue";
88 const char *EVALUATE = "evaluate";
89 const char *LOOKUP = "lookup";
90 const char *BACKTRACE = "backtrace";
91 const char *SCOPE = "scope";
92 const char *SCOPES = "scopes";
93 const char *SCRIPTS = "scripts";
94 const char *SOURCE = "source";
95 const char *SETBREAKPOINT = "setbreakpoint";
96 const char *CHANGEBREAKPOINT = "changebreakpoint";
97 const char *CLEARBREAKPOINT = "clearbreakpoint";
98 const char *SETEXCEPTIONBREAK = "setexceptionbreak";
99 const char *V8FLAGS = "v8flags";
100 const char *VERSION = "version";
101 const char *DISCONNECT = "disconnect";
102 const char *LISTBREAKPOINTS = "listbreakpoints";
103 const char *GARBAGECOLLECTOR = "gc";
104 //const char *PROFILE = "profile";
106 const char *CONNECT = "connect";
107 const char *INTERRUPT = "interrupt";
109 const char *REQUEST = "request";
110 const char *IN = "in";
111 const char *NEXT = "next";
112 const char *OUT = "out";
114 const char *FUNCTION = "function";
115 const char *SCRIPT = "script";
117 const char *ALL = "all";
118 const char *UNCAUGHT = "uncaught";
120 //const char *PAUSE = "pause";
121 //const char *RESUME = "resume";
123 const char *BLOCKMODE = "-qmljsdebugger=port:3771,block";
124 const char *NORMALMODE = "-qmljsdebugger=port:3771";
125 const char *QMLFILE = "test.qml";
126 const char *JSFILE = "test.js";
128 #define VARIANTMAPINIT \
130 QJSValue jsonVal = parser.call(QJSValue(), QJSValueList() << obj); \
131 jsonVal.setProperty(SEQ,QJSValue(seq++)); \
132 jsonVal.setProperty(TYPE,REQUEST);
134 class QJSDebugProcess;
135 class QJSDebugClient;
137 class tst_QDeclarativeDebugJS : public QObject
144 void cleanupTestCase();
157 void listBreakpoints();
159 void setBreakpointInScriptOnCompleted();
160 void setBreakpointInScriptOnTimerCallback();
161 void setBreakpointInScriptInDifferentFile();
162 void setBreakpointInScriptOnComment();
163 void setBreakpointInScriptOnEmptyLine();
164 void setBreakpointInScriptWithCondition();
165 //void setBreakpointInFunction(); //NOT SUPPORTED
167 void changeBreakpoint();
168 void changeBreakpointOnCondition();
170 void clearBreakpoint();
172 void setExceptionBreak();
175 void stepNextWithCount();
178 void continueDebugging();
182 void getFrameDetails();
184 void getScopeDetails();
186 void evaluateInGlobalScope();
187 void evaluateInLocalScope();
195 // void profile(); //NOT SUPPORTED
197 // void verifyQMLOptimizerDisabled();
200 QJSDebugProcess *process;
201 QJSDebugClient *client;
202 QDeclarativeDebugConnection *connection;
205 class QJSDebugProcess : public QObject
212 void start(const QStringList &arguments);
213 bool waitForSessionStart();
216 void processAppOutput();
224 QEventLoop m_eventLoop;
229 QJSDebugProcess::QJSDebugProcess()
232 m_process.setProcessChannelMode(QProcess::MergedChannels);
233 m_timer.setSingleShot(true);
234 m_timer.setInterval(5000);
235 connect(&m_process, SIGNAL(readyReadStandardOutput()), this, SLOT(processAppOutput()));
236 connect(&m_timer, SIGNAL(timeout()), &m_eventLoop, SLOT(quit()));
238 // QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
239 // env.insert("QML_DISABLE_OPTIMIZER", "1"); // Add an environment variable
240 // m_process.setProcessEnvironment(env);
244 QJSDebugProcess::~QJSDebugProcess()
249 void QJSDebugProcess::start(const QStringList &arguments)
252 m_process.start(QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene", arguments);
253 m_process.waitForStarted();
258 void QJSDebugProcess::stop()
260 if (m_process.state() != QProcess::NotRunning) {
261 m_process.terminate();
262 m_process.waitForFinished(5000);
266 bool QJSDebugProcess::waitForSessionStart()
268 m_eventLoop.exec(QEventLoop::ExcludeUserInputEvents);
273 void QJSDebugProcess::processAppOutput()
276 const QString appOutput = m_process.readAll();
277 static QRegExp newline("[\n\r]{1,2}");
278 QStringList lines = appOutput.split(newline);
279 foreach (const QString &line, lines) {
282 if (line.startsWith("Qml debugging is enabled")) // ignore
284 if (line.startsWith("QDeclarativeDebugServer:")) {
285 if (line.contains("Waiting for connection ")) {
290 if (line.contains("Connection established")) {
294 if (line.startsWith("QDeclarativeDebugServer: Unable to listen on port")) {
295 QFAIL("Application cannot open port 3771: Port is blocked?");
298 // qWarning() << line;
303 class QJSDebugClient : public QDeclarativeDebugClient
321 // enum ProfileCommand
327 QJSDebugClient(QDeclarativeDebugConnection *connection)
328 : QDeclarativeDebugClient(QLatin1String("V8Debugger"), connection),
331 parser = jsEngine.evaluate(QLatin1String("JSON.parse"));
332 stringify = jsEngine.evaluate(QLatin1String("JSON.stringify"));
335 void startDebugging();
338 void continueDebugging(StepAction stepAction, int stepCount = 1);
339 void evaluate(QString expr, bool global = false, bool disableBreak = false, int frame = -1, const QVariantMap &addContext = QVariantMap());
340 void lookup(QList<int> handles, bool includeSource = false);
341 void backtrace(int fromFrame = -1, int toFrame = -1, bool bottom = false);
342 void frame(int number = -1);
343 void scope(int number = -1, int frameNumber = -1);
344 void scopes(int frameNumber = -1);
345 void scripts(int types = 4, QList<int> ids = QList<int>(), bool includeSource = false, QVariant filter = QVariant());
346 void source(int frame = -1, int fromLine = -1, int toLine = -1);
347 void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = true, QString condition = QString(), int ignoreCount = -1);
348 void changeBreakpoint(int breakpoint, bool enabled = true, QString condition = QString(), int ignoreCount = -1);
349 void clearBreakpoint(int breakpoint);
350 void setExceptionBreak(Exception type, bool enabled = false);
351 void v8flags(QString flags);
353 //void profile(ProfileCommand command); //NOT SUPPORTED
356 void listBreakpoints();
359 //inherited from QDeclarativeDebugClient
360 void statusChanged(Status status);
361 void messageReceived(const QByteArray &data);
365 void breakpointSet();
370 void sendMessage(const QByteArray &);
371 void flushSendBuffer();
372 QByteArray packMessage(QByteArray message);
378 QList<QByteArray> sendBuffer;
387 void QJSDebugClient::startDebugging()
389 // { "seq" : <number>,
390 // "type" : "request",
391 // "command" : "connect",
394 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(CONNECT)));
396 QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
397 sendMessage(packMessage(json.toString().toUtf8()));
400 void QJSDebugClient::interrupt()
402 // { "seq" : <number>,
403 // "type" : "request",
404 // "command" : "interrupt",
407 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(INTERRUPT)));
409 QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
410 sendMessage(packMessage(json.toString().toUtf8()));
413 void QJSDebugClient::continueDebugging(StepAction action, int count)
415 // { "seq" : <number>,
416 // "type" : "request",
417 // "command" : "continue",
418 // "arguments" : { "stepaction" : <"in", "next" or "out">,
419 // "stepcount" : <number of steps (default 1)>
423 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(CONTINEDEBUGGING)));
425 if (action != Continue) {
426 QJSValue args = parser.call(QJSValue(), QJSValueList() << obj);
428 case In: args.setProperty(QLatin1String(STEPACTION),QJSValue(QLatin1String(IN)));
430 case Out: args.setProperty(QLatin1String(STEPACTION),QJSValue(QLatin1String(OUT)));
432 case Next: args.setProperty(QLatin1String(STEPACTION),QJSValue(QLatin1String(NEXT)));
436 if (args.isValid()) {
438 args.setProperty(QLatin1String(STEPCOUNT),QJSValue(count));
439 jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
442 QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
443 sendMessage(packMessage(json.toString().toUtf8()));
446 void QJSDebugClient::evaluate(QString expr, bool global, bool disableBreak, int frame, const QVariantMap &/*addContext*/)
448 // { "seq" : <number>,
449 // "type" : "request",
450 // "command" : "evaluate",
451 // "arguments" : { "expression" : <expression to evaluate>,
452 // "frame" : <number>,
453 // "global" : <boolean>,
454 // "disable_break" : <boolean>,
455 // "additional_context" : [
456 // { "name" : <name1>, "handle" : <handle1> },
457 // { "name" : <name2>, "handle" : <handle2> },
463 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(EVALUATE)));
465 QJSValue args = parser.call(QJSValue(), QJSValueList() << obj);
466 args.setProperty(QLatin1String(EXPRESSION),QJSValue(expr));
469 args.setProperty(QLatin1String(FRAME),QJSValue(frame));
472 args.setProperty(QLatin1String(GLOBAL),QJSValue(global));
475 args.setProperty(QLatin1String(DISABLEBREAK),QJSValue(disableBreak));
477 if (args.isValid()) {
478 jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
481 QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
482 sendMessage(packMessage(json.toString().toUtf8()));
485 void QJSDebugClient::lookup(QList<int> handles, bool includeSource)
487 // { "seq" : <number>,
488 // "type" : "request",
489 // "command" : "lookup",
490 // "arguments" : { "handles" : <array of handles>,
491 // "includeSource" : <boolean indicating whether the source will be included when script objects are returned>,
495 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(LOOKUP)));
497 QJSValue args = parser.call(QJSValue(), QJSValueList() << obj);
500 QJSValue array = parser.call(QJSValue(), QJSValueList() << arr);
502 foreach (int handle, handles) {
503 array.setProperty(index++,QJSValue(handle));
505 args.setProperty(QLatin1String(HANDLES),array);
508 args.setProperty(QLatin1String(INCLUDESOURCE),QJSValue(includeSource));
510 if (args.isValid()) {
511 jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
514 QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
515 sendMessage(packMessage(json.toString().toUtf8()));
518 void QJSDebugClient::backtrace(int fromFrame, int toFrame, bool bottom)
520 // { "seq" : <number>,
521 // "type" : "request",
522 // "command" : "backtrace",
523 // "arguments" : { "fromFrame" : <number>
524 // "toFrame" : <number>
525 // "bottom" : <boolean, set to true if the bottom of the stack is requested>
529 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(BACKTRACE)));
531 QJSValue args = parser.call(QJSValue(), QJSValueList() << obj);
534 args.setProperty(QLatin1String(FROMFRAME),QJSValue(fromFrame));
537 args.setProperty(QLatin1String(TOFRAME),QJSValue(toFrame));
540 args.setProperty(QLatin1String(BOTTOM),QJSValue(bottom));
542 if (args.isValid()) {
543 jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
546 QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
547 sendMessage(packMessage(json.toString().toUtf8()));
550 void QJSDebugClient::frame(int number)
552 // { "seq" : <number>,
553 // "type" : "request",
554 // "command" : "frame",
555 // "arguments" : { "number" : <frame number>
559 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(FRAME)));
562 QJSValue args = parser.call(QJSValue(), QJSValueList() << obj);
563 args.setProperty(QLatin1String(NUMBER),QJSValue(number));
565 if (args.isValid()) {
566 jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
570 QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
571 sendMessage(packMessage(json.toString().toUtf8()));
574 void QJSDebugClient::scope(int number, int frameNumber)
576 // { "seq" : <number>,
577 // "type" : "request",
578 // "command" : "scope",
579 // "arguments" : { "number" : <scope number>
580 // "frameNumber" : <frame number, optional uses selected frame if missing>
584 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(SCOPE)));
587 QJSValue args = parser.call(QJSValue(), QJSValueList() << obj);
588 args.setProperty(QLatin1String(NUMBER),QJSValue(number));
590 if (frameNumber != -1)
591 args.setProperty(QLatin1String(FRAMENUMBER),QJSValue(frameNumber));
593 if (args.isValid()) {
594 jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
598 QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
599 sendMessage(packMessage(json.toString().toUtf8()));
602 void QJSDebugClient::scopes(int frameNumber)
604 // { "seq" : <number>,
605 // "type" : "request",
606 // "command" : "scopes",
607 // "arguments" : { "frameNumber" : <frame number, optional uses selected frame if missing>
611 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(SCOPES)));
613 if (frameNumber != -1) {
614 QJSValue args = parser.call(QJSValue(), QJSValueList() << obj);
615 args.setProperty(QLatin1String(FRAMENUMBER),QJSValue(frameNumber));
617 if (args.isValid()) {
618 jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
622 QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
623 sendMessage(packMessage(json.toString().toUtf8()));
626 void QJSDebugClient::scripts(int types, QList<int> ids, bool includeSource, QVariant /*filter*/)
628 // { "seq" : <number>,
629 // "type" : "request",
630 // "command" : "scripts",
631 // "arguments" : { "types" : <types of scripts to retrieve
632 // set bit 0 for native scripts
633 // set bit 1 for extension scripts
634 // set bit 2 for normal scripts
635 // (default is 4 for normal scripts)>
636 // "ids" : <array of id's of scripts to return. If this is not specified all scripts are requrned>
637 // "includeSource" : <boolean indicating whether the source code should be included for the scripts returned>
638 // "filter" : <string or number: filter string or script id.
639 // If a number is specified, then only the script with the same number as its script id will be retrieved.
640 // If a string is specified, then only scripts whose names contain the filter string will be retrieved.>
644 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(SCRIPTS)));
646 QJSValue args = parser.call(QJSValue(), QJSValueList() << obj);
647 args.setProperty(QLatin1String(TYPES),QJSValue(types));
651 QJSValue array = parser.call(QJSValue(), QJSValueList() << arr);
653 foreach (int id, ids) {
654 array.setProperty(index++,QJSValue(id));
656 args.setProperty(QLatin1String(IDS),array);
660 args.setProperty(QLatin1String(INCLUDESOURCE),QJSValue(includeSource));
662 if (args.isValid()) {
663 jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
666 QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
667 sendMessage(packMessage(json.toString().toUtf8()));
670 void QJSDebugClient::source(int frame, int fromLine, int toLine)
672 // { "seq" : <number>,
673 // "type" : "request",
674 // "command" : "source",
675 // "arguments" : { "frame" : <frame number (default selected frame)>
676 // "fromLine" : <from line within the source default is line 0>
677 // "toLine" : <to line within the source this line is not included in
678 // the result default is the number of lines in the script>
682 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(SOURCE)));
684 QJSValue args = parser.call(QJSValue(), QJSValueList() << obj);
687 args.setProperty(QLatin1String(FRAME),QJSValue(frame));
690 args.setProperty(QLatin1String(FROMLINE),QJSValue(fromLine));
693 args.setProperty(QLatin1String(TOLINE),QJSValue(toLine));
695 if (args.isValid()) {
696 jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
699 QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
700 sendMessage(packMessage(json.toString().toUtf8()));
703 void QJSDebugClient::setBreakpoint(QString type, QString target, int line, int column, bool enabled, QString condition, int ignoreCount)
705 // { "seq" : <number>,
706 // "type" : "request",
707 // "command" : "setbreakpoint",
708 // "arguments" : { "type" : <"function" or "script" or "scriptId" or "scriptRegExp">
709 // "target" : <function expression or script identification>
710 // "line" : <line in script or function>
711 // "column" : <character position within the line>
712 // "enabled" : <initial enabled state. True or false, default is true>
713 // "condition" : <string with break point condition>
714 // "ignoreCount" : <number specifying the number of break point hits to ignore, default value is 0>
718 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(SETBREAKPOINT)));
720 QJSValue args = parser.call(QJSValue(), QJSValueList() << obj);
722 args.setProperty(QLatin1String(TYPE),QJSValue(type));
723 args.setProperty(QLatin1String(TARGET),QJSValue(target));
726 args.setProperty(QLatin1String(LINE),QJSValue(line));
729 args.setProperty(QLatin1String(COLUMN),QJSValue(column));
731 args.setProperty(QLatin1String(ENABLED),QJSValue(enabled));
733 if (!condition.isEmpty())
734 args.setProperty(QLatin1String(CONDITION),QJSValue(condition));
736 if (ignoreCount != -1)
737 args.setProperty(QLatin1String(IGNORECOUNT),QJSValue(ignoreCount));
739 if (args.isValid()) {
740 jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
743 QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
744 sendMessage(packMessage(json.toString().toUtf8()));
747 void QJSDebugClient::changeBreakpoint(int breakpoint, bool enabled, QString condition, int ignoreCount)
749 // { "seq" : <number>,
750 // "type" : "request",
751 // "command" : "changebreakpoint",
752 // "arguments" : { "breakpoint" : <number of the break point to clear>
753 // "enabled" : <initial enabled state. True or false, default is true>
754 // "condition" : <string with break point condition>
755 // "ignoreCount" : <number specifying the number of break point hits }
758 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(CHANGEBREAKPOINT)));
760 QJSValue args = parser.call(QJSValue(), QJSValueList() << obj);
762 args.setProperty(QLatin1String(BREAKPOINT),QJSValue(breakpoint));
764 args.setProperty(QLatin1String(ENABLED),QJSValue(enabled));
766 if (!condition.isEmpty())
767 args.setProperty(QLatin1String(CONDITION),QJSValue(condition));
769 if (ignoreCount != -1)
770 args.setProperty(QLatin1String(IGNORECOUNT),QJSValue(ignoreCount));
772 if (args.isValid()) {
773 jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
776 QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
777 sendMessage(packMessage(json.toString().toUtf8()));
780 void QJSDebugClient::clearBreakpoint(int breakpoint)
782 // { "seq" : <number>,
783 // "type" : "request",
784 // "command" : "clearbreakpoint",
785 // "arguments" : { "breakpoint" : <number of the break point to clear>
789 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(CLEARBREAKPOINT)));
791 QJSValue args = parser.call(QJSValue(), QJSValueList() << obj);
793 args.setProperty(QLatin1String(BREAKPOINT),QJSValue(breakpoint));
795 if (args.isValid()) {
796 jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
799 QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
800 sendMessage(packMessage(json.toString().toUtf8()));
803 void QJSDebugClient::setExceptionBreak(Exception type, bool enabled)
805 // { "seq" : <number>,
806 // "type" : "request",
807 // "command" : "setexceptionbreak",
808 // "arguments" : { "type" : <string: "all", or "uncaught">,
809 // "enabled" : <optional bool: enables the break type if true>
813 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(SETEXCEPTIONBREAK)));
815 QJSValue args = parser.call(QJSValue(), QJSValueList() << obj);
818 args.setProperty(QLatin1String(TYPE),QJSValue(QLatin1String(ALL)));
819 else if (type == Uncaught)
820 args.setProperty(QLatin1String(TYPE),QJSValue(QLatin1String(UNCAUGHT)));
823 args.setProperty(QLatin1String(ENABLED),QJSValue(enabled));
825 if (args.isValid()) {
826 jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
829 QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
830 sendMessage(packMessage(json.toString().toUtf8()));
833 void QJSDebugClient::v8flags(QString flags)
835 // { "seq" : <number>,
836 // "type" : "request",
837 // "command" : "v8flags",
838 // "arguments" : { "flags" : <string: a sequence of v8 flags just like those used on the command line>
842 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(V8FLAGS)));
844 QJSValue args = parser.call(QJSValue(), QJSValueList() << obj);
846 args.setProperty(QLatin1String(FLAGS),QJSValue(flags));
848 if (args.isValid()) {
849 jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
852 QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
853 sendMessage(packMessage(json.toString().toUtf8()));
856 void QJSDebugClient::version()
858 // { "seq" : <number>,
859 // "type" : "request",
860 // "command" : "version",
863 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(VERSION)));
865 QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
866 sendMessage(packMessage(json.toString().toUtf8()));
869 //void QJSDebugClient::profile(ProfileCommand command)
871 //// { "seq" : <number>,
872 //// "type" : "request",
873 //// "command" : "profile",
874 //// "arguments" : { "command" : "resume" or "pause" }
877 // jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(PROFILE)));
879 // QJSValue args = parser.call(QJSValue(), QJSValueList() << obj);
881 // if (command == Resume)
882 // args.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(RESUME)));
884 // args.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(PAUSE)));
886 // args.setProperty(QLatin1String("modules"),QJSValue(1));
887 // if (args.isValid()) {
888 // jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
891 // QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
892 // sendMessage(packMessage(json.toString().toUtf8()));
895 void QJSDebugClient::disconnect()
897 // { "seq" : <number>,
898 // "type" : "request",
899 // "command" : "disconnect",
902 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(DISCONNECT)));
904 QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
905 sendMessage(packMessage(json.toString().toUtf8()));
908 void QJSDebugClient::gc()
910 // { "seq" : <number>,
911 // "type" : "request",
913 // "arguments" : { "type" : <string: "all">,
917 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(GARBAGECOLLECTOR)));
919 QJSValue args = parser.call(QJSValue(), QJSValueList() << obj);
921 args.setProperty(QLatin1String(FLAGS),QJSValue(QLatin1String(ALL)));
923 if (args.isValid()) {
924 jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
927 QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
928 sendMessage(packMessage(json.toString().toUtf8()));
931 void QJSDebugClient::listBreakpoints()
933 // { "seq" : <number>,
934 // "type" : "request",
935 // "command" : "listbreakpoints",
938 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(LISTBREAKPOINTS)));
940 QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
941 sendMessage(packMessage(json.toString().toUtf8()));
944 void QJSDebugClient::statusChanged(Status status)
946 if (status == Enabled) {
952 void QJSDebugClient::messageReceived(const QByteArray &data)
954 QDataStream ds(data);
958 if (command == "V8DEBUG") {
960 QString jsonString(response);
961 QVariantMap value = parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
962 QString type = value.value("type").toString();
964 if (type == "response") {
966 if (!value.value("success").toBool()) {
967 // qDebug() << "Error: The test case will fail since no signal is emitted";
971 QString debugCommand(value.value("command").toString());
972 if (debugCommand == "backtrace" ||
973 debugCommand == "lookup" ||
974 debugCommand == "setbreakpoint" ||
975 debugCommand == "evaluate" ||
976 debugCommand == "listbreakpoints" ||
977 debugCommand == "version" ||
978 debugCommand == "v8flags" ||
979 debugCommand == "disconnect" ||
980 debugCommand == "gc" ||
981 debugCommand == "changebreakpoint" ||
982 debugCommand == "clearbreakpoint" ||
983 debugCommand == "frame" ||
984 debugCommand == "scope" ||
985 debugCommand == "scopes" ||
986 debugCommand == "scripts" ||
987 debugCommand == "source" ||
988 debugCommand == "setexceptionbreak" /*||
989 debugCommand == "profile"*/) {
996 } else if (type == "event") {
997 QString event(value.value("event").toString());
999 if (event == "break" ||
1000 event == "exception") {
1007 void QJSDebugClient::sendMessage(const QByteArray &msg)
1009 if (status() == Enabled) {
1010 QDeclarativeDebugClient::sendMessage(msg);
1012 sendBuffer.append(msg);
1016 void QJSDebugClient::flushSendBuffer()
1018 foreach (const QByteArray &msg, sendBuffer)
1019 QDeclarativeDebugClient::sendMessage(msg);
1023 QByteArray QJSDebugClient::packMessage(QByteArray message)
1026 QDataStream rs(&reply, QIODevice::WriteOnly);
1027 QByteArray cmd = "V8DEBUG";
1028 rs << cmd << message;
1032 void tst_QDeclarativeDebugJS::initTestCase()
1039 void tst_QDeclarativeDebugJS::cleanupTestCase()
1051 void tst_QDeclarativeDebugJS::init()
1053 connection = new QDeclarativeDebugConnection();
1054 process = new QJSDebugProcess();
1055 client = new QJSDebugClient(connection);
1057 process->start(QStringList() << QLatin1String(BLOCKMODE) << TESTDATA(QLatin1String(QMLFILE)));
1058 QVERIFY(process->waitForSessionStart());
1060 connection->connectToHost("127.0.0.1", 3771);
1061 QVERIFY(connection->waitForConnected());
1063 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(enabled())));
1066 void tst_QDeclarativeDebugJS::cleanup()
1082 void tst_QDeclarativeDebugJS::getVersion()
1086 client->interrupt();
1087 client->startDebugging();
1088 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1091 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1094 void tst_QDeclarativeDebugJS::applyV8Flags()
1096 //void v8flags(QString flags)
1098 client->interrupt();
1099 client->startDebugging();
1100 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1102 client->v8flags(QString());
1103 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1106 void tst_QDeclarativeDebugJS::disconnect()
1110 client->interrupt();
1111 client->startDebugging();
1112 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1114 client->disconnect();
1115 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1118 void tst_QDeclarativeDebugJS::gc()
1122 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(JSFILE), 2, -1, true);
1123 client->startDebugging();
1124 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1127 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1130 void tst_QDeclarativeDebugJS::listBreakpoints()
1132 //void listBreakpoints()
1134 int sourceLine1 = 57;
1135 int sourceLine2 = 60;
1136 int sourceLine3 = 67;
1138 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(QMLFILE), sourceLine1, -1, true);
1139 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(QMLFILE), sourceLine2, -1, true);
1140 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(JSFILE), sourceLine3, -1, true);
1141 client->startDebugging();
1142 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1144 client->listBreakpoints();
1145 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1147 QString jsonString(client->response);
1148 QVariantMap value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1150 QList<QVariant> breakpoints = value.value("body").toMap().value("breakpoints").toList();
1152 QCOMPARE(breakpoints.count(), 3);
1155 void tst_QDeclarativeDebugJS::setBreakpointInScriptOnCompleted()
1157 //void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1)
1159 int sourceLine = 49;
1161 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(QMLFILE), sourceLine, -1, true);
1162 client->startDebugging();
1163 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1165 QString jsonString(client->response);
1166 QVariantMap value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1168 QVariantMap body = value.value("body").toMap();
1170 QCOMPARE(body.value("sourceLine").toInt(), sourceLine);
1171 QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(QMLFILE));
1174 void tst_QDeclarativeDebugJS::setBreakpointInScriptOnTimerCallback()
1176 int sourceLine = 49;
1177 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(QMLFILE), sourceLine, -1, true);
1178 client->startDebugging();
1179 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1181 client->evaluate("timer.running = true");
1182 client->continueDebugging(QJSDebugClient::Continue);
1184 //void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1)
1188 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(QMLFILE), sourceLine, -1, true);
1189 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1191 QString jsonString(client->response);
1192 QVariantMap value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1194 QVariantMap body = value.value("body").toMap();
1196 QCOMPARE(body.value("sourceLine").toInt(), sourceLine);
1197 QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(QMLFILE));
1200 void tst_QDeclarativeDebugJS::setBreakpointInScriptInDifferentFile()
1202 //void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1)
1204 int sourceLine = 43;
1206 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(JSFILE), sourceLine, -1, true);
1207 client->startDebugging();
1208 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1210 QString jsonString(client->response);
1211 QVariantMap value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1213 QVariantMap body = value.value("body").toMap();
1215 QCOMPARE(body.value("sourceLine").toInt(), sourceLine);
1216 QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(JSFILE));
1219 void tst_QDeclarativeDebugJS::setBreakpointInScriptOnComment()
1221 //void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1)
1223 int sourceLine = 48;
1224 int actualLine = 50;
1226 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(JSFILE), sourceLine, -1, true);
1227 client->startDebugging();
1228 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1230 QString jsonString(client->response);
1231 QVariantMap value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1233 QVariantMap body = value.value("body").toMap();
1235 QCOMPARE(body.value("sourceLine").toInt(), actualLine);
1236 QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(JSFILE));
1239 void tst_QDeclarativeDebugJS::setBreakpointInScriptOnEmptyLine()
1241 //void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1)
1243 int sourceLine = 49;
1244 int actualLine = 50;
1246 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(JSFILE), sourceLine, -1, true);
1247 client->startDebugging();
1248 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1250 QString jsonString(client->response);
1251 QVariantMap value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1253 QVariantMap body = value.value("body").toMap();
1255 QCOMPARE(body.value("sourceLine").toInt(), actualLine);
1256 QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(JSFILE));
1259 void tst_QDeclarativeDebugJS::setBreakpointInScriptWithCondition()
1261 //void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1)
1264 int sourceLine = 51;
1266 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(JSFILE), sourceLine, -1, true, QLatin1String("out > 10"));
1267 client->startDebugging();
1268 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1270 //Get the frame index
1271 QString jsonString = client->response;
1272 QVariantMap value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1274 QVariantMap body = value.value("body").toMap();
1276 int frameIndex = body.value("index").toInt();
1278 //Verify the value of 'result'
1279 client->evaluate(QLatin1String("out"),frameIndex);
1281 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1283 jsonString = client->response;
1284 value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1286 body = value.value("body").toMap();
1288 QVERIFY(body.value("value").toInt() > out);
1291 //void tst_QDeclarativeDebugJS::setBreakpointInFunction()
1293 // //void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1)
1295 // int actualLine = 31;
1297 // client->startDebugging();
1298 // client->setBreakpoint(QLatin1String(FUNCTION), QLatin1String("doSomethingElse"), -1, -1, true);
1300 // QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1302 // QString jsonString(client->response);
1303 // QVariantMap value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1305 // QVariantMap body = value.value("body").toMap();
1307 // QCOMPARE(body.value("sourceLine").toInt(), actualLine);
1308 // QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(QMLFILE));
1311 void tst_QDeclarativeDebugJS::changeBreakpoint()
1313 //void changeBreakpoint(int breakpoint, bool enabled = false, QString condition = QString(), int ignoreCount = -1)
1315 int sourceLine1 = 77;
1316 int sourceLine2 = 78;
1318 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(QMLFILE), sourceLine1, -1, true);
1319 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(QMLFILE), sourceLine2, -1, true);
1320 client->startDebugging();
1321 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1323 //Will hit 1st brakpoint, change this breakpoint enable = false
1324 QString jsonString(client->response);
1325 QVariantMap value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1327 QVariantMap body = value.value("body").toMap();
1328 QList<QVariant> breakpointsHit = body.value("breakpoints").toList();
1330 int breakpoint = breakpointsHit.at(0).toInt();
1331 client->changeBreakpoint(breakpoint,false);
1333 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1335 //Continue with debugging
1336 client->continueDebugging(QJSDebugClient::Continue);
1337 //Hit 2nd breakpoint
1338 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1341 client->evaluate("timer.running = true");
1343 //Continue with debugging
1344 client->continueDebugging(QJSDebugClient::Continue);
1345 //Should stop at 2nd breakpoint
1346 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1348 jsonString = client->response;
1349 value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1351 body = value.value("body").toMap();
1353 QCOMPARE(body.value("sourceLine").toInt(), sourceLine2);
1356 void tst_QDeclarativeDebugJS::changeBreakpointOnCondition()
1358 //void changeBreakpoint(int breakpoint, bool enabled = false, QString condition = QString(), int ignoreCount = -1)
1360 int sourceLine1 = 56;
1361 int sourceLine2 = 60;
1364 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(QMLFILE), sourceLine1, -1, true);
1365 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(QMLFILE), sourceLine2, -1, true);
1366 client->startDebugging();
1367 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1369 //Will hit 1st brakpoint, change this breakpoint enable = false
1370 QString jsonString(client->response);
1371 QVariantMap value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1373 QVariantMap body = value.value("body").toMap();
1374 QList<QVariant> breakpointsHit = body.value("breakpoints").toList();
1376 int breakpoint = breakpointsHit.at(0).toInt();
1377 client->changeBreakpoint(breakpoint,false,QLatin1String("a = 0"));
1379 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1381 //Continue with debugging
1382 client->continueDebugging(QJSDebugClient::Continue);
1383 //Hit 2nd breakpoint
1384 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1386 client->evaluate("timer.running = true");
1387 //Continue with debugging
1388 client->continueDebugging(QJSDebugClient::Continue);
1389 //Should stop at 2nd breakpoint
1390 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1392 jsonString = client->response;
1393 value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1395 body = value.value("body").toMap();
1397 QCOMPARE(body.value("sourceLine").toInt(), sourceLine2);
1400 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1402 //Get the frame index
1403 jsonString = client->response;
1404 value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1406 body = value.value("body").toMap();
1408 int frameIndex = body.value("index").toInt();
1410 //Verify the value of 'result'
1411 client->evaluate(QLatin1String("root.result"),frameIndex);
1413 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1415 jsonString = client->response;
1416 value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1418 body = value.value("body").toMap();
1420 QVERIFY(body.value("value").toInt() > result);
1423 void tst_QDeclarativeDebugJS::clearBreakpoint()
1425 //void clearBreakpoint(int breakpoint);
1427 int sourceLine1 = 77;
1428 int sourceLine2 = 78;
1430 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(QMLFILE), sourceLine1, -1, true);
1431 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(QMLFILE), sourceLine2, -1, true);
1432 client->startDebugging();
1433 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1435 //Will hit 1st brakpoint, change this breakpoint enable = false
1436 QString jsonString(client->response);
1437 QVariantMap value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1439 QVariantMap body = value.value("body").toMap();
1440 QList<QVariant> breakpointsHit = body.value("breakpoints").toList();
1442 int breakpoint = breakpointsHit.at(0).toInt();
1443 client->changeBreakpoint(breakpoint,false,QLatin1String("result > 5"));
1445 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1447 //Continue with debugging
1448 client->continueDebugging(QJSDebugClient::Continue);
1449 //Hit 2nd breakpoint
1450 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1452 client->evaluate("timer.running = true");
1453 //Continue with debugging
1454 client->continueDebugging(QJSDebugClient::Continue);
1455 //Should stop at 2nd breakpoint
1456 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1458 jsonString = client->response;
1459 value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1461 body = value.value("body").toMap();
1463 QCOMPARE(body.value("sourceLine").toInt(), sourceLine2);
1466 void tst_QDeclarativeDebugJS::setExceptionBreak()
1468 //void setExceptionBreak(QString type, bool enabled = false);
1470 int sourceLine = 49;
1471 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(QMLFILE), sourceLine, -1, true);
1472 client->setExceptionBreak(QJSDebugClient::All,true);
1473 client->startDebugging();
1474 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1475 client->evaluate("root.raiseException = true");
1476 client->continueDebugging(QJSDebugClient::Continue);
1477 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped()), 10000));
1480 void tst_QDeclarativeDebugJS::stepNext()
1482 //void continueDebugging(StepAction stepAction, int stepCount = 1);
1484 int sourceLine = 57;
1486 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(QMLFILE), sourceLine, -1, true);
1487 client->startDebugging();
1488 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1490 client->continueDebugging(QJSDebugClient::Next);
1491 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped()), 10000));
1493 QString jsonString(client->response);
1494 QVariantMap value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1496 QVariantMap body = value.value("body").toMap();
1498 QCOMPARE(body.value("sourceLine").toInt(), sourceLine + 1);
1499 QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(QMLFILE));
1502 void tst_QDeclarativeDebugJS::stepNextWithCount()
1504 //void continueDebugging(StepAction stepAction, int stepCount = 1);
1506 int sourceLine = 59;
1508 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(QMLFILE), sourceLine, -1, true);
1509 client->startDebugging();
1510 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1512 client->continueDebugging(QJSDebugClient::Next,2);
1513 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped()), 10000));
1515 QString jsonString(client->response);
1516 QVariantMap value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1518 QVariantMap body = value.value("body").toMap();
1520 QCOMPARE(body.value("sourceLine").toInt(), sourceLine + 2);
1521 QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(QMLFILE));
1524 void tst_QDeclarativeDebugJS::stepIn()
1526 //void continueDebugging(StepAction stepAction, int stepCount = 1);
1528 int sourceLine = 61;
1529 int actualLine = 78;
1531 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(QMLFILE), sourceLine, -1, true);
1532 client->startDebugging();
1533 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1535 client->continueDebugging(QJSDebugClient::In);
1536 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped()), 10000));
1538 QString jsonString(client->response);
1539 QVariantMap value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1541 QVariantMap body = value.value("body").toMap();
1543 QCOMPARE(body.value("sourceLine").toInt(), actualLine);
1544 QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(QMLFILE));
1547 void tst_QDeclarativeDebugJS::stepOut()
1549 //void continueDebugging(StepAction stepAction, int stepCount = 1);
1551 int sourceLine = 56;
1552 int actualLine = 49;
1554 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(QMLFILE), sourceLine, -1, true);
1555 client->startDebugging();
1556 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1558 client->continueDebugging(QJSDebugClient::Out);
1559 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped()), 10000));
1561 QString jsonString(client->response);
1562 QVariantMap value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1564 QVariantMap body = value.value("body").toMap();
1566 QCOMPARE(body.value("sourceLine").toInt(), actualLine);
1567 QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(QMLFILE));
1570 void tst_QDeclarativeDebugJS::continueDebugging()
1572 //void continueDebugging(StepAction stepAction, int stepCount = 1);
1574 int sourceLine1 = 56;
1575 int sourceLine2 = 60;
1577 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(QMLFILE), sourceLine1, -1, true);
1578 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(QMLFILE), sourceLine2, -1, true);
1579 client->startDebugging();
1580 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1582 client->continueDebugging(QJSDebugClient::Continue);
1583 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped()), 10000));
1585 QString jsonString(client->response);
1586 QVariantMap value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1588 QVariantMap body = value.value("body").toMap();
1590 QCOMPARE(body.value("sourceLine").toInt(), sourceLine2);
1591 QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(QMLFILE));
1594 void tst_QDeclarativeDebugJS::backtrace()
1596 //void backtrace(int fromFrame = -1, int toFrame = -1, bool bottom = false);
1598 int sourceLine = 60;
1599 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(QMLFILE), sourceLine, -1, true);
1600 client->startDebugging();
1601 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1603 client->backtrace();
1604 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1607 void tst_QDeclarativeDebugJS::getFrameDetails()
1609 //void frame(int number = -1);
1611 int sourceLine = 60;
1612 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(QMLFILE), sourceLine, -1, true);
1613 client->startDebugging();
1614 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1617 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1620 void tst_QDeclarativeDebugJS::getScopeDetails()
1622 //void scope(int number = -1, int frameNumber = -1);
1624 int sourceLine = 60;
1625 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(QMLFILE), sourceLine, -1, true);
1626 client->startDebugging();
1627 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1630 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1633 void tst_QDeclarativeDebugJS::evaluateInGlobalScope()
1635 //void evaluate(QString expr, bool global = false, bool disableBreak = false, int frame = -1, const QVariantMap &addContext = QVariantMap());
1637 int sourceLine = 49;
1638 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(QMLFILE), sourceLine, -1, true);
1639 client->startDebugging();
1640 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1642 client->evaluate(QLatin1String("print('Hello World')"),true);
1643 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1645 //Verify the value of 'print'
1646 QString jsonString(client->response);
1647 QVariantMap value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1649 QVariantMap body = value.value("body").toMap();
1651 QCOMPARE(body.value("text").toString(),QLatin1String("undefined"));
1654 void tst_QDeclarativeDebugJS::evaluateInLocalScope()
1656 //void evaluate(QString expr, bool global = false, bool disableBreak = false, int frame = -1, const QVariantMap &addContext = QVariantMap());
1658 int sourceLine = 60;
1659 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(QMLFILE), sourceLine, -1, true);
1660 client->startDebugging();
1661 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1664 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1666 //Get the frame index
1667 QString jsonString(client->response);
1668 QVariantMap value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1670 QVariantMap body = value.value("body").toMap();
1672 int frameIndex = body.value("index").toInt();
1674 client->evaluate(QLatin1String("root.someValue"),frameIndex);
1675 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1677 //Verify the value of 'root.someValue'
1678 jsonString = client->response;
1679 value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1681 body = value.value("body").toMap();
1683 QCOMPARE(body.value("value").toInt(),10);
1686 void tst_QDeclarativeDebugJS::getScopes()
1688 //void scopes(int frameNumber = -1);
1690 client->interrupt();
1691 client->startDebugging();
1692 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1695 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1698 void tst_QDeclarativeDebugJS::getScripts()
1700 //void scripts(int types = -1, QList<int> ids = QList<int>(), bool includeSource = false, QVariant filter = QVariant());
1702 client->interrupt();
1703 client->startDebugging();
1704 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1707 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1710 void tst_QDeclarativeDebugJS::getSource()
1712 //void source(int frame = -1, int fromLine = -1, int toLine = -1);
1714 client->interrupt();
1715 client->startDebugging();
1716 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1719 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1722 QTEST_MAIN(tst_QDeclarativeDebugJS)
1724 #include "tst_qdeclarativedebugjs.moc"