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 *TEST_QMLFILE = "test.qml";
126 const char *TEST_JSFILE = "test.js";
127 const char *TIMER_QMLFILE = "timer.qml";
129 #define VARIANTMAPINIT \
131 QJSValue jsonVal = parser.call(QJSValue(), QJSValueList() << obj); \
132 jsonVal.setProperty(SEQ,QJSValue(seq++)); \
133 jsonVal.setProperty(TYPE,REQUEST);
137 #define QVERIFY(statement) \
139 if (!QTest::qVerify((statement), #statement, "", __FILE__, __LINE__)) {\
140 qDebug().nospace() << "\nDEBUGGEE OUTPUT:\n" << process->output();\
146 class QJSDebugClient;
148 class tst_QDeclarativeDebugJS : public QObject
152 bool init(const QString &qmlFile = QString(TEST_QMLFILE), bool blockMode = true);
156 void cleanupTestCase();
161 void getVersionWhenAttaching();
169 void listBreakpoints();
171 void setBreakpointInScriptOnCompleted();
172 void setBreakpointInScriptOnTimerCallback();
173 void setBreakpointInScriptInDifferentFile();
174 void setBreakpointInScriptOnComment();
175 void setBreakpointInScriptOnEmptyLine();
176 void setBreakpointInScriptWithCondition();
177 //void setBreakpointInFunction(); //NOT SUPPORTED
178 void setBreakpointWhenAttaching();
180 void changeBreakpoint();
181 void changeBreakpointOnCondition();
183 void clearBreakpoint();
185 void setExceptionBreak();
188 void stepNextWithCount();
191 void continueDebugging();
195 void getFrameDetails();
197 void getScopeDetails();
199 void evaluateInGlobalScope();
200 void evaluateInLocalScope();
208 // void profile(); //NOT SUPPORTED
210 // void verifyQMLOptimizerDisabled();
213 QDeclarativeDebugProcess *process;
214 QJSDebugClient *client;
215 QDeclarativeDebugConnection *connection;
218 class QJSDebugClient : public QDeclarativeDebugClient
236 // enum ProfileCommand
242 QJSDebugClient(QDeclarativeDebugConnection *connection)
243 : QDeclarativeDebugClient(QLatin1String("V8Debugger"), connection),
246 parser = jsEngine.evaluate(QLatin1String("JSON.parse"));
247 stringify = jsEngine.evaluate(QLatin1String("JSON.stringify"));
250 void startDebugging();
253 void continueDebugging(StepAction stepAction, int stepCount = 1);
254 void evaluate(QString expr, bool global = false, bool disableBreak = false, int frame = -1, const QVariantMap &addContext = QVariantMap());
255 void lookup(QList<int> handles, bool includeSource = false);
256 void backtrace(int fromFrame = -1, int toFrame = -1, bool bottom = false);
257 void frame(int number = -1);
258 void scope(int number = -1, int frameNumber = -1);
259 void scopes(int frameNumber = -1);
260 void scripts(int types = 4, QList<int> ids = QList<int>(), bool includeSource = false, QVariant filter = QVariant());
261 void source(int frame = -1, int fromLine = -1, int toLine = -1);
262 void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = true, QString condition = QString(), int ignoreCount = -1);
263 void changeBreakpoint(int breakpoint, bool enabled = true, QString condition = QString(), int ignoreCount = -1);
264 void clearBreakpoint(int breakpoint);
265 void setExceptionBreak(Exception type, bool enabled = false);
266 void v8flags(QString flags);
268 //void profile(ProfileCommand command); //NOT SUPPORTED
271 void listBreakpoints();
274 //inherited from QDeclarativeDebugClient
275 void statusChanged(Status status);
276 void messageReceived(const QByteArray &data);
280 void breakpointSet();
285 void sendMessage(const QByteArray &);
286 void flushSendBuffer();
287 QByteArray packMessage(QByteArray message);
293 QList<QByteArray> sendBuffer;
302 void QJSDebugClient::startDebugging()
304 // { "seq" : <number>,
305 // "type" : "request",
306 // "command" : "connect",
309 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(CONNECT)));
311 QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
312 sendMessage(packMessage(json.toString().toUtf8()));
315 void QJSDebugClient::interrupt()
317 // { "seq" : <number>,
318 // "type" : "request",
319 // "command" : "interrupt",
322 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(INTERRUPT)));
324 QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
325 sendMessage(packMessage(json.toString().toUtf8()));
328 void QJSDebugClient::continueDebugging(StepAction action, int count)
330 // { "seq" : <number>,
331 // "type" : "request",
332 // "command" : "continue",
333 // "arguments" : { "stepaction" : <"in", "next" or "out">,
334 // "stepcount" : <number of steps (default 1)>
338 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(CONTINEDEBUGGING)));
340 if (action != Continue) {
341 QJSValue args = parser.call(QJSValue(), QJSValueList() << obj);
343 case In: args.setProperty(QLatin1String(STEPACTION),QJSValue(QLatin1String(IN)));
345 case Out: args.setProperty(QLatin1String(STEPACTION),QJSValue(QLatin1String(OUT)));
347 case Next: args.setProperty(QLatin1String(STEPACTION),QJSValue(QLatin1String(NEXT)));
351 if (args.isValid()) {
353 args.setProperty(QLatin1String(STEPCOUNT),QJSValue(count));
354 jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
357 QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
358 sendMessage(packMessage(json.toString().toUtf8()));
361 void QJSDebugClient::evaluate(QString expr, bool global, bool disableBreak, int frame, const QVariantMap &/*addContext*/)
363 // { "seq" : <number>,
364 // "type" : "request",
365 // "command" : "evaluate",
366 // "arguments" : { "expression" : <expression to evaluate>,
367 // "frame" : <number>,
368 // "global" : <boolean>,
369 // "disable_break" : <boolean>,
370 // "additional_context" : [
371 // { "name" : <name1>, "handle" : <handle1> },
372 // { "name" : <name2>, "handle" : <handle2> },
378 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(EVALUATE)));
380 QJSValue args = parser.call(QJSValue(), QJSValueList() << obj);
381 args.setProperty(QLatin1String(EXPRESSION),QJSValue(expr));
384 args.setProperty(QLatin1String(FRAME),QJSValue(frame));
387 args.setProperty(QLatin1String(GLOBAL),QJSValue(global));
390 args.setProperty(QLatin1String(DISABLEBREAK),QJSValue(disableBreak));
392 if (args.isValid()) {
393 jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
396 QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
397 sendMessage(packMessage(json.toString().toUtf8()));
400 void QJSDebugClient::lookup(QList<int> handles, bool includeSource)
402 // { "seq" : <number>,
403 // "type" : "request",
404 // "command" : "lookup",
405 // "arguments" : { "handles" : <array of handles>,
406 // "includeSource" : <boolean indicating whether the source will be included when script objects are returned>,
410 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(LOOKUP)));
412 QJSValue args = parser.call(QJSValue(), QJSValueList() << obj);
415 QJSValue array = parser.call(QJSValue(), QJSValueList() << arr);
417 foreach (int handle, handles) {
418 array.setProperty(index++,QJSValue(handle));
420 args.setProperty(QLatin1String(HANDLES),array);
423 args.setProperty(QLatin1String(INCLUDESOURCE),QJSValue(includeSource));
425 if (args.isValid()) {
426 jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
429 QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
430 sendMessage(packMessage(json.toString().toUtf8()));
433 void QJSDebugClient::backtrace(int fromFrame, int toFrame, bool bottom)
435 // { "seq" : <number>,
436 // "type" : "request",
437 // "command" : "backtrace",
438 // "arguments" : { "fromFrame" : <number>
439 // "toFrame" : <number>
440 // "bottom" : <boolean, set to true if the bottom of the stack is requested>
444 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(BACKTRACE)));
446 QJSValue args = parser.call(QJSValue(), QJSValueList() << obj);
449 args.setProperty(QLatin1String(FROMFRAME),QJSValue(fromFrame));
452 args.setProperty(QLatin1String(TOFRAME),QJSValue(toFrame));
455 args.setProperty(QLatin1String(BOTTOM),QJSValue(bottom));
457 if (args.isValid()) {
458 jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
461 QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
462 sendMessage(packMessage(json.toString().toUtf8()));
465 void QJSDebugClient::frame(int number)
467 // { "seq" : <number>,
468 // "type" : "request",
469 // "command" : "frame",
470 // "arguments" : { "number" : <frame number>
474 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(FRAME)));
477 QJSValue args = parser.call(QJSValue(), QJSValueList() << obj);
478 args.setProperty(QLatin1String(NUMBER),QJSValue(number));
480 if (args.isValid()) {
481 jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
485 QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
486 sendMessage(packMessage(json.toString().toUtf8()));
489 void QJSDebugClient::scope(int number, int frameNumber)
491 // { "seq" : <number>,
492 // "type" : "request",
493 // "command" : "scope",
494 // "arguments" : { "number" : <scope number>
495 // "frameNumber" : <frame number, optional uses selected frame if missing>
499 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(SCOPE)));
502 QJSValue args = parser.call(QJSValue(), QJSValueList() << obj);
503 args.setProperty(QLatin1String(NUMBER),QJSValue(number));
505 if (frameNumber != -1)
506 args.setProperty(QLatin1String(FRAMENUMBER),QJSValue(frameNumber));
508 if (args.isValid()) {
509 jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
513 QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
514 sendMessage(packMessage(json.toString().toUtf8()));
517 void QJSDebugClient::scopes(int frameNumber)
519 // { "seq" : <number>,
520 // "type" : "request",
521 // "command" : "scopes",
522 // "arguments" : { "frameNumber" : <frame number, optional uses selected frame if missing>
526 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(SCOPES)));
528 if (frameNumber != -1) {
529 QJSValue args = parser.call(QJSValue(), QJSValueList() << obj);
530 args.setProperty(QLatin1String(FRAMENUMBER),QJSValue(frameNumber));
532 if (args.isValid()) {
533 jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
537 QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
538 sendMessage(packMessage(json.toString().toUtf8()));
541 void QJSDebugClient::scripts(int types, QList<int> ids, bool includeSource, QVariant /*filter*/)
543 // { "seq" : <number>,
544 // "type" : "request",
545 // "command" : "scripts",
546 // "arguments" : { "types" : <types of scripts to retrieve
547 // set bit 0 for native scripts
548 // set bit 1 for extension scripts
549 // set bit 2 for normal scripts
550 // (default is 4 for normal scripts)>
551 // "ids" : <array of id's of scripts to return. If this is not specified all scripts are requrned>
552 // "includeSource" : <boolean indicating whether the source code should be included for the scripts returned>
553 // "filter" : <string or number: filter string or script id.
554 // If a number is specified, then only the script with the same number as its script id will be retrieved.
555 // If a string is specified, then only scripts whose names contain the filter string will be retrieved.>
559 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(SCRIPTS)));
561 QJSValue args = parser.call(QJSValue(), QJSValueList() << obj);
562 args.setProperty(QLatin1String(TYPES),QJSValue(types));
566 QJSValue array = parser.call(QJSValue(), QJSValueList() << arr);
568 foreach (int id, ids) {
569 array.setProperty(index++,QJSValue(id));
571 args.setProperty(QLatin1String(IDS),array);
575 args.setProperty(QLatin1String(INCLUDESOURCE),QJSValue(includeSource));
577 if (args.isValid()) {
578 jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
581 QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
582 sendMessage(packMessage(json.toString().toUtf8()));
585 void QJSDebugClient::source(int frame, int fromLine, int toLine)
587 // { "seq" : <number>,
588 // "type" : "request",
589 // "command" : "source",
590 // "arguments" : { "frame" : <frame number (default selected frame)>
591 // "fromLine" : <from line within the source default is line 0>
592 // "toLine" : <to line within the source this line is not included in
593 // the result default is the number of lines in the script>
597 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(SOURCE)));
599 QJSValue args = parser.call(QJSValue(), QJSValueList() << obj);
602 args.setProperty(QLatin1String(FRAME),QJSValue(frame));
605 args.setProperty(QLatin1String(FROMLINE),QJSValue(fromLine));
608 args.setProperty(QLatin1String(TOLINE),QJSValue(toLine));
610 if (args.isValid()) {
611 jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
614 QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
615 sendMessage(packMessage(json.toString().toUtf8()));
618 void QJSDebugClient::setBreakpoint(QString type, QString target, int line, int column, bool enabled, QString condition, int ignoreCount)
620 // { "seq" : <number>,
621 // "type" : "request",
622 // "command" : "setbreakpoint",
623 // "arguments" : { "type" : <"function" or "script" or "scriptId" or "scriptRegExp">
624 // "target" : <function expression or script identification>
625 // "line" : <line in script or function>
626 // "column" : <character position within the line>
627 // "enabled" : <initial enabled state. True or false, default is true>
628 // "condition" : <string with break point condition>
629 // "ignoreCount" : <number specifying the number of break point hits to ignore, default value is 0>
633 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(SETBREAKPOINT)));
635 QJSValue args = parser.call(QJSValue(), QJSValueList() << obj);
637 args.setProperty(QLatin1String(TYPE),QJSValue(type));
638 args.setProperty(QLatin1String(TARGET),QJSValue(target));
641 args.setProperty(QLatin1String(LINE),QJSValue(line));
644 args.setProperty(QLatin1String(COLUMN),QJSValue(column));
646 args.setProperty(QLatin1String(ENABLED),QJSValue(enabled));
648 if (!condition.isEmpty())
649 args.setProperty(QLatin1String(CONDITION),QJSValue(condition));
651 if (ignoreCount != -1)
652 args.setProperty(QLatin1String(IGNORECOUNT),QJSValue(ignoreCount));
654 if (args.isValid()) {
655 jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
658 QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
659 sendMessage(packMessage(json.toString().toUtf8()));
662 void QJSDebugClient::changeBreakpoint(int breakpoint, bool enabled, QString condition, int ignoreCount)
664 // { "seq" : <number>,
665 // "type" : "request",
666 // "command" : "changebreakpoint",
667 // "arguments" : { "breakpoint" : <number of the break point to clear>
668 // "enabled" : <initial enabled state. True or false, default is true>
669 // "condition" : <string with break point condition>
670 // "ignoreCount" : <number specifying the number of break point hits }
673 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(CHANGEBREAKPOINT)));
675 QJSValue args = parser.call(QJSValue(), QJSValueList() << obj);
677 args.setProperty(QLatin1String(BREAKPOINT),QJSValue(breakpoint));
679 args.setProperty(QLatin1String(ENABLED),QJSValue(enabled));
681 if (!condition.isEmpty())
682 args.setProperty(QLatin1String(CONDITION),QJSValue(condition));
684 if (ignoreCount != -1)
685 args.setProperty(QLatin1String(IGNORECOUNT),QJSValue(ignoreCount));
687 if (args.isValid()) {
688 jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
691 QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
692 sendMessage(packMessage(json.toString().toUtf8()));
695 void QJSDebugClient::clearBreakpoint(int breakpoint)
697 // { "seq" : <number>,
698 // "type" : "request",
699 // "command" : "clearbreakpoint",
700 // "arguments" : { "breakpoint" : <number of the break point to clear>
704 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(CLEARBREAKPOINT)));
706 QJSValue args = parser.call(QJSValue(), QJSValueList() << obj);
708 args.setProperty(QLatin1String(BREAKPOINT),QJSValue(breakpoint));
710 if (args.isValid()) {
711 jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
714 QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
715 sendMessage(packMessage(json.toString().toUtf8()));
718 void QJSDebugClient::setExceptionBreak(Exception type, bool enabled)
720 // { "seq" : <number>,
721 // "type" : "request",
722 // "command" : "setexceptionbreak",
723 // "arguments" : { "type" : <string: "all", or "uncaught">,
724 // "enabled" : <optional bool: enables the break type if true>
728 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(SETEXCEPTIONBREAK)));
730 QJSValue args = parser.call(QJSValue(), QJSValueList() << obj);
733 args.setProperty(QLatin1String(TYPE),QJSValue(QLatin1String(ALL)));
734 else if (type == Uncaught)
735 args.setProperty(QLatin1String(TYPE),QJSValue(QLatin1String(UNCAUGHT)));
738 args.setProperty(QLatin1String(ENABLED),QJSValue(enabled));
740 if (args.isValid()) {
741 jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
744 QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
745 sendMessage(packMessage(json.toString().toUtf8()));
748 void QJSDebugClient::v8flags(QString flags)
750 // { "seq" : <number>,
751 // "type" : "request",
752 // "command" : "v8flags",
753 // "arguments" : { "flags" : <string: a sequence of v8 flags just like those used on the command line>
757 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(V8FLAGS)));
759 QJSValue args = parser.call(QJSValue(), QJSValueList() << obj);
761 args.setProperty(QLatin1String(FLAGS),QJSValue(flags));
763 if (args.isValid()) {
764 jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
767 QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
768 sendMessage(packMessage(json.toString().toUtf8()));
771 void QJSDebugClient::version()
773 // { "seq" : <number>,
774 // "type" : "request",
775 // "command" : "version",
778 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(VERSION)));
780 QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
781 sendMessage(packMessage(json.toString().toUtf8()));
784 //void QJSDebugClient::profile(ProfileCommand command)
786 //// { "seq" : <number>,
787 //// "type" : "request",
788 //// "command" : "profile",
789 //// "arguments" : { "command" : "resume" or "pause" }
792 // jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(PROFILE)));
794 // QJSValue args = parser.call(QJSValue(), QJSValueList() << obj);
796 // if (command == Resume)
797 // args.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(RESUME)));
799 // args.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(PAUSE)));
801 // args.setProperty(QLatin1String("modules"),QJSValue(1));
802 // if (args.isValid()) {
803 // jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
806 // QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
807 // sendMessage(packMessage(json.toString().toUtf8()));
810 void QJSDebugClient::disconnect()
812 // { "seq" : <number>,
813 // "type" : "request",
814 // "command" : "disconnect",
817 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(DISCONNECT)));
819 QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
820 sendMessage(packMessage(json.toString().toUtf8()));
823 void QJSDebugClient::gc()
825 // { "seq" : <number>,
826 // "type" : "request",
828 // "arguments" : { "type" : <string: "all">,
832 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(GARBAGECOLLECTOR)));
834 QJSValue args = parser.call(QJSValue(), QJSValueList() << obj);
836 args.setProperty(QLatin1String(TYPE),QJSValue(QLatin1String(ALL)));
838 if (args.isValid()) {
839 jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
842 QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
843 sendMessage(packMessage(json.toString().toUtf8()));
846 void QJSDebugClient::listBreakpoints()
848 // { "seq" : <number>,
849 // "type" : "request",
850 // "command" : "listbreakpoints",
853 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(LISTBREAKPOINTS)));
855 QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
856 sendMessage(packMessage(json.toString().toUtf8()));
859 void QJSDebugClient::statusChanged(Status status)
861 if (status == Enabled) {
867 void QJSDebugClient::messageReceived(const QByteArray &data)
869 QDataStream ds(data);
873 if (command == "V8DEBUG") {
875 QString jsonString(response);
876 QVariantMap value = parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
877 QString type = value.value("type").toString();
879 if (type == "response") {
881 if (!value.value("success").toBool()) {
882 // qDebug() << "Error: The test case will fail since no signal is emitted";
886 QString debugCommand(value.value("command").toString());
887 if (debugCommand == "backtrace" ||
888 debugCommand == "lookup" ||
889 debugCommand == "setbreakpoint" ||
890 debugCommand == "evaluate" ||
891 debugCommand == "listbreakpoints" ||
892 debugCommand == "version" ||
893 debugCommand == "v8flags" ||
894 debugCommand == "disconnect" ||
895 debugCommand == "gc" ||
896 debugCommand == "changebreakpoint" ||
897 debugCommand == "clearbreakpoint" ||
898 debugCommand == "frame" ||
899 debugCommand == "scope" ||
900 debugCommand == "scopes" ||
901 debugCommand == "scripts" ||
902 debugCommand == "source" ||
903 debugCommand == "setexceptionbreak" /*||
904 debugCommand == "profile"*/) {
911 } else if (type == "event") {
912 QString event(value.value("event").toString());
914 if (event == "break" ||
915 event == "exception") {
922 void QJSDebugClient::sendMessage(const QByteArray &msg)
924 if (status() == Enabled) {
925 QDeclarativeDebugClient::sendMessage(msg);
927 sendBuffer.append(msg);
931 void QJSDebugClient::flushSendBuffer()
933 foreach (const QByteArray &msg, sendBuffer)
934 QDeclarativeDebugClient::sendMessage(msg);
938 QByteArray QJSDebugClient::packMessage(QByteArray message)
941 QDataStream rs(&reply, QIODevice::WriteOnly);
942 QByteArray cmd = "V8DEBUG";
943 rs << cmd << message;
947 void tst_QDeclarativeDebugJS::initTestCase()
954 void tst_QDeclarativeDebugJS::cleanupTestCase()
968 bool tst_QDeclarativeDebugJS::init(const QString &qmlFile, bool blockMode)
970 connection = new QDeclarativeDebugConnection();
971 process = new QDeclarativeDebugProcess(QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene");
972 client = new QJSDebugClient(connection);
975 process->start(QStringList() << QLatin1String(BLOCKMODE) << TESTDATA(qmlFile));
977 process->start(QStringList() << QLatin1String(NORMALMODE) << TESTDATA(qmlFile));
979 if (!process->waitForSessionStart()) {
983 connection->connectToHost("127.0.0.1", 3771);
984 if (!connection->waitForConnected())
987 return QDeclarativeDebugTest::waitForSignal(client, SIGNAL(enabled()));
990 void tst_QDeclarativeDebugJS::cleanup()
1008 void tst_QDeclarativeDebugJS::getVersion()
1013 client->interrupt();
1014 client->startDebugging();
1015 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1018 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1021 void tst_QDeclarativeDebugJS::getVersionWhenAttaching()
1025 QVERIFY(init(QLatin1String(TIMER_QMLFILE), false));
1026 client->interrupt();
1027 client->startDebugging();
1028 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1031 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1034 void tst_QDeclarativeDebugJS::applyV8Flags()
1036 //void v8flags(QString flags)
1039 client->interrupt();
1040 client->startDebugging();
1041 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1043 client->v8flags(QString());
1044 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1047 void tst_QDeclarativeDebugJS::disconnect()
1052 client->interrupt();
1053 client->startDebugging();
1054 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1056 client->disconnect();
1057 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1060 void tst_QDeclarativeDebugJS::gc()
1065 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(TEST_JSFILE), 43, -1, true);
1066 client->startDebugging();
1067 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1070 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1073 void tst_QDeclarativeDebugJS::listBreakpoints()
1075 //void listBreakpoints()
1077 int sourceLine1 = 57;
1078 int sourceLine2 = 60;
1079 int sourceLine3 = 67;
1082 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(TEST_QMLFILE), sourceLine1, -1, true);
1083 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(TEST_QMLFILE), sourceLine2, -1, true);
1084 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(TEST_JSFILE), sourceLine3, -1, true);
1085 client->startDebugging();
1086 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1088 client->listBreakpoints();
1089 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1091 QString jsonString(client->response);
1092 QVariantMap value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1094 QList<QVariant> breakpoints = value.value("body").toMap().value("breakpoints").toList();
1096 QCOMPARE(breakpoints.count(), 3);
1099 void tst_QDeclarativeDebugJS::setBreakpointInScriptOnCompleted()
1101 //void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1)
1103 int sourceLine = 49;
1106 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(TEST_QMLFILE), sourceLine, -1, true);
1107 client->startDebugging();
1108 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1110 QString jsonString(client->response);
1111 QVariantMap value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1113 QVariantMap body = value.value("body").toMap();
1115 QCOMPARE(body.value("sourceLine").toInt(), sourceLine);
1116 QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(TEST_QMLFILE));
1119 void tst_QDeclarativeDebugJS::setBreakpointInScriptOnTimerCallback()
1121 int sourceLine = 49;
1124 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(TEST_QMLFILE), sourceLine, -1, true);
1125 //void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1)
1127 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(TEST_QMLFILE), sourceLine, -1, true);
1128 client->startDebugging();
1129 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1131 client->evaluate("timer.running = true");
1132 client->continueDebugging(QJSDebugClient::Continue);
1134 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1136 QString jsonString(client->response);
1137 QVariantMap value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1139 QVariantMap body = value.value("body").toMap();
1141 QCOMPARE(body.value("sourceLine").toInt(), sourceLine);
1142 QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(TEST_QMLFILE));
1145 void tst_QDeclarativeDebugJS::setBreakpointInScriptInDifferentFile()
1147 //void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1)
1149 int sourceLine = 43;
1152 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(TEST_JSFILE), sourceLine, -1, true);
1153 client->startDebugging();
1154 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1156 QString jsonString(client->response);
1157 QVariantMap value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1159 QVariantMap body = value.value("body").toMap();
1161 QCOMPARE(body.value("sourceLine").toInt(), sourceLine);
1162 QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(TEST_JSFILE));
1165 void tst_QDeclarativeDebugJS::setBreakpointInScriptOnComment()
1167 //void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1)
1169 int sourceLine = 48;
1170 int actualLine = 50;
1173 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(TEST_JSFILE), sourceLine, -1, true);
1174 client->startDebugging();
1175 QEXPECT_FAIL("", "Relocation of breakpoints is disabled right now", Abort);
1176 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1178 QString jsonString(client->response);
1179 QVariantMap value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1181 QVariantMap body = value.value("body").toMap();
1183 QCOMPARE(body.value("sourceLine").toInt(), actualLine);
1184 QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(TEST_JSFILE));
1187 void tst_QDeclarativeDebugJS::setBreakpointInScriptOnEmptyLine()
1189 //void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1)
1191 int sourceLine = 49;
1192 int actualLine = 50;
1195 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(TEST_JSFILE), sourceLine, -1, true);
1196 client->startDebugging();
1197 QEXPECT_FAIL("", "Relocation of breakpoints is disabled right now", Abort);
1198 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1200 QString jsonString(client->response);
1201 QVariantMap value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1203 QVariantMap body = value.value("body").toMap();
1205 QCOMPARE(body.value("sourceLine").toInt(), actualLine);
1206 QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(TEST_JSFILE));
1209 void tst_QDeclarativeDebugJS::setBreakpointInScriptWithCondition()
1211 //void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1)
1214 int sourceLine = 51;
1217 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(TEST_JSFILE), sourceLine, -1, true, QLatin1String("out > 10"));
1218 client->startDebugging();
1219 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1221 //Get the frame index
1222 QString jsonString = client->response;
1223 QVariantMap value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1225 QVariantMap body = value.value("body").toMap();
1227 int frameIndex = body.value("index").toInt();
1229 //Verify the value of 'result'
1230 client->evaluate(QLatin1String("out"),frameIndex);
1232 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1234 jsonString = client->response;
1235 value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1237 body = value.value("body").toMap();
1239 QVERIFY(body.value("value").toInt() > out);
1242 void tst_QDeclarativeDebugJS::setBreakpointWhenAttaching()
1244 int sourceLine = 49;
1245 QVERIFY(init(QLatin1String(TIMER_QMLFILE), false));
1247 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(TIMER_QMLFILE), sourceLine);
1248 client->startDebugging();
1249 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1252 //void tst_QDeclarativeDebugJS::setBreakpointInFunction()
1254 // //void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1)
1256 // int actualLine = 31;
1258 // client->startDebugging();
1259 // client->setBreakpoint(QLatin1String(FUNCTION), QLatin1String("doSomethingElse"), -1, -1, true);
1261 // QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1263 // QString jsonString(client->response);
1264 // QVariantMap value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1266 // QVariantMap body = value.value("body").toMap();
1268 // QCOMPARE(body.value("sourceLine").toInt(), actualLine);
1269 // QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(QMLFILE));
1272 void tst_QDeclarativeDebugJS::changeBreakpoint()
1274 //void changeBreakpoint(int breakpoint, bool enabled = false, QString condition = QString(), int ignoreCount = -1)
1276 int sourceLine1 = 78;
1277 int sourceLine2 = 79;
1280 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(TEST_QMLFILE), sourceLine1, -1, true);
1281 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(TEST_QMLFILE), sourceLine2, -1, true);
1282 client->startDebugging();
1283 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1285 //Will hit 1st brakpoint, change this breakpoint enable = false
1286 QString jsonString(client->response);
1287 QVariantMap value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1289 QVariantMap body = value.value("body").toMap();
1290 QList<QVariant> breakpointsHit = body.value("breakpoints").toList();
1292 int breakpoint = breakpointsHit.at(0).toInt();
1293 client->changeBreakpoint(breakpoint,false);
1295 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1297 //Continue with debugging
1298 client->continueDebugging(QJSDebugClient::Continue);
1299 //Hit 2nd breakpoint
1300 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1303 client->evaluate("timer.running = true");
1305 //Continue with debugging
1306 client->continueDebugging(QJSDebugClient::Continue);
1307 //Should stop at 2nd breakpoint
1308 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1310 jsonString = client->response;
1311 value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1313 body = value.value("body").toMap();
1315 QCOMPARE(body.value("sourceLine").toInt(), sourceLine2);
1318 void tst_QDeclarativeDebugJS::changeBreakpointOnCondition()
1320 //void changeBreakpoint(int breakpoint, bool enabled = false, QString condition = QString(), int ignoreCount = -1)
1322 int sourceLine1 = 56;
1323 int sourceLine2 = 60;
1327 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(TEST_QMLFILE), sourceLine1, -1, true);
1328 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(TEST_QMLFILE), sourceLine2, -1, true);
1329 client->startDebugging();
1330 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1332 //Will hit 1st brakpoint, change this breakpoint enable = false
1333 QString jsonString(client->response);
1334 QVariantMap value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1336 QVariantMap body = value.value("body").toMap();
1337 QList<QVariant> breakpointsHit = body.value("breakpoints").toList();
1339 int breakpoint = breakpointsHit.at(0).toInt();
1340 client->changeBreakpoint(breakpoint,false,QLatin1String("a = 0"));
1342 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1344 //Continue with debugging
1345 client->continueDebugging(QJSDebugClient::Continue);
1346 //Hit 2nd breakpoint
1347 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1349 client->evaluate("timer.running = true");
1350 //Continue with debugging
1351 client->continueDebugging(QJSDebugClient::Continue);
1352 //Should stop at 2nd breakpoint
1353 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1355 jsonString = client->response;
1356 value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1358 body = value.value("body").toMap();
1360 QCOMPARE(body.value("sourceLine").toInt(), sourceLine2);
1363 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1365 //Get the frame index
1366 jsonString = client->response;
1367 value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1369 body = value.value("body").toMap();
1371 int frameIndex = body.value("index").toInt();
1373 //Verify the value of 'result'
1374 client->evaluate(QLatin1String("root.result"),frameIndex);
1376 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1378 jsonString = client->response;
1379 value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1381 body = value.value("body").toMap();
1383 QVERIFY(body.value("value").toInt() > result);
1386 void tst_QDeclarativeDebugJS::clearBreakpoint()
1388 //void clearBreakpoint(int breakpoint);
1390 int sourceLine1 = 78;
1391 int sourceLine2 = 79;
1394 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(TEST_QMLFILE), sourceLine1, -1, true);
1395 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(TEST_QMLFILE), sourceLine2, -1, true);
1396 client->startDebugging();
1397 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1399 //Will hit 1st brakpoint, change this breakpoint enable = false
1400 QString jsonString(client->response);
1401 QVariantMap value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1403 QVariantMap body = value.value("body").toMap();
1404 QList<QVariant> breakpointsHit = body.value("breakpoints").toList();
1406 int breakpoint = breakpointsHit.at(0).toInt();
1407 client->changeBreakpoint(breakpoint,false,QLatin1String("result > 5"));
1409 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1411 //Continue with debugging
1412 client->continueDebugging(QJSDebugClient::Continue);
1413 //Hit 2nd breakpoint
1414 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1416 client->evaluate("timer.running = true");
1417 //Continue with debugging
1418 client->continueDebugging(QJSDebugClient::Continue);
1419 //Should stop at 2nd breakpoint
1420 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1422 jsonString = client->response;
1423 value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1425 body = value.value("body").toMap();
1427 QCOMPARE(body.value("sourceLine").toInt(), sourceLine2);
1430 void tst_QDeclarativeDebugJS::setExceptionBreak()
1432 //void setExceptionBreak(QString type, bool enabled = false);
1434 int sourceLine = 49;
1437 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(TEST_QMLFILE), sourceLine, -1, true);
1438 client->setExceptionBreak(QJSDebugClient::All,true);
1439 client->startDebugging();
1440 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1441 client->evaluate("root.raiseException = true");
1442 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1443 client->continueDebugging(QJSDebugClient::Continue);
1444 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped()), 10000));
1447 void tst_QDeclarativeDebugJS::stepNext()
1449 //void continueDebugging(StepAction stepAction, int stepCount = 1);
1451 int sourceLine = 57;
1454 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(TEST_QMLFILE), sourceLine, -1, true);
1455 client->startDebugging();
1456 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1458 client->continueDebugging(QJSDebugClient::Next);
1459 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped()), 10000));
1461 QString jsonString(client->response);
1462 QVariantMap value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1464 QVariantMap body = value.value("body").toMap();
1466 QCOMPARE(body.value("sourceLine").toInt(), sourceLine + 1);
1467 QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(TEST_QMLFILE));
1470 void tst_QDeclarativeDebugJS::stepNextWithCount()
1472 //void continueDebugging(StepAction stepAction, int stepCount = 1);
1474 int sourceLine = 59;
1477 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(TEST_QMLFILE), sourceLine, -1, true);
1478 client->startDebugging();
1479 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1481 client->continueDebugging(QJSDebugClient::Next,2);
1482 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped()), 10000));
1484 QString jsonString(client->response);
1485 QVariantMap value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1487 QVariantMap body = value.value("body").toMap();
1489 QCOMPARE(body.value("sourceLine").toInt(), sourceLine + 2);
1490 QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(TEST_QMLFILE));
1493 void tst_QDeclarativeDebugJS::stepIn()
1495 //void continueDebugging(StepAction stepAction, int stepCount = 1);
1497 int sourceLine = 61;
1498 int actualLine = 78;
1501 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(TEST_QMLFILE), sourceLine, -1, true);
1502 client->startDebugging();
1503 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1505 client->continueDebugging(QJSDebugClient::In);
1506 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped()), 10000));
1508 QString jsonString(client->response);
1509 QVariantMap value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1511 QVariantMap body = value.value("body").toMap();
1513 QCOMPARE(body.value("sourceLine").toInt(), actualLine);
1514 QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(TEST_QMLFILE));
1517 void tst_QDeclarativeDebugJS::stepOut()
1519 //void continueDebugging(StepAction stepAction, int stepCount = 1);
1521 int sourceLine = 56;
1522 int actualLine = 49;
1525 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(TEST_QMLFILE), sourceLine, -1, true);
1526 client->startDebugging();
1527 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1529 client->continueDebugging(QJSDebugClient::Out);
1530 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped()), 10000));
1532 QString jsonString(client->response);
1533 QVariantMap value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1535 QVariantMap body = value.value("body").toMap();
1537 QCOMPARE(body.value("sourceLine").toInt(), actualLine);
1538 QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(TEST_QMLFILE));
1541 void tst_QDeclarativeDebugJS::continueDebugging()
1543 //void continueDebugging(StepAction stepAction, int stepCount = 1);
1545 int sourceLine1 = 56;
1546 int sourceLine2 = 60;
1549 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(TEST_QMLFILE), sourceLine1, -1, true);
1550 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(TEST_QMLFILE), sourceLine2, -1, true);
1551 client->startDebugging();
1552 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1554 client->continueDebugging(QJSDebugClient::Continue);
1555 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped()), 10000));
1557 QString jsonString(client->response);
1558 QVariantMap value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1560 QVariantMap body = value.value("body").toMap();
1562 QCOMPARE(body.value("sourceLine").toInt(), sourceLine2);
1563 QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(TEST_QMLFILE));
1566 void tst_QDeclarativeDebugJS::backtrace()
1568 //void backtrace(int fromFrame = -1, int toFrame = -1, bool bottom = false);
1570 int sourceLine = 60;
1573 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(TEST_QMLFILE), sourceLine, -1, true);
1574 client->startDebugging();
1575 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1577 client->backtrace();
1578 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1581 void tst_QDeclarativeDebugJS::getFrameDetails()
1583 //void frame(int number = -1);
1585 int sourceLine = 60;
1588 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(TEST_QMLFILE), sourceLine, -1, true);
1589 client->startDebugging();
1590 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1593 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1596 void tst_QDeclarativeDebugJS::getScopeDetails()
1598 //void scope(int number = -1, int frameNumber = -1);
1600 int sourceLine = 60;
1603 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(TEST_QMLFILE), sourceLine, -1, true);
1604 client->startDebugging();
1605 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1608 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1611 void tst_QDeclarativeDebugJS::evaluateInGlobalScope()
1613 //void evaluate(QString expr, bool global = false, bool disableBreak = false, int frame = -1, const QVariantMap &addContext = QVariantMap());
1615 int sourceLine = 49;
1618 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(TEST_QMLFILE), sourceLine, -1, true);
1619 client->startDebugging();
1620 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1622 client->evaluate(QLatin1String("print('Hello World')"),true);
1623 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1625 //Verify the value of 'print'
1626 QString jsonString(client->response);
1627 QVariantMap value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1629 QVariantMap body = value.value("body").toMap();
1631 QCOMPARE(body.value("text").toString(),QLatin1String("undefined"));
1634 void tst_QDeclarativeDebugJS::evaluateInLocalScope()
1636 //void evaluate(QString expr, bool global = false, bool disableBreak = false, int frame = -1, const QVariantMap &addContext = QVariantMap());
1638 int sourceLine = 60;
1641 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(TEST_QMLFILE), sourceLine, -1, true);
1642 client->startDebugging();
1643 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1646 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1648 //Get the frame index
1649 QString jsonString(client->response);
1650 QVariantMap value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1652 QVariantMap body = value.value("body").toMap();
1654 int frameIndex = body.value("index").toInt();
1656 client->evaluate(QLatin1String("root.someValue"),frameIndex);
1657 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1659 //Verify the value of 'root.someValue'
1660 jsonString = client->response;
1661 value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1663 body = value.value("body").toMap();
1665 QCOMPARE(body.value("value").toInt(),10);
1668 void tst_QDeclarativeDebugJS::getScopes()
1670 //void scopes(int frameNumber = -1);
1674 client->interrupt();
1675 client->startDebugging();
1676 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1679 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1682 void tst_QDeclarativeDebugJS::getScripts()
1684 //void scripts(int types = -1, QList<int> ids = QList<int>(), bool includeSource = false, QVariant filter = QVariant());
1686 QVERIFY(init(QLatin1String(TIMER_QMLFILE), true));
1688 client->interrupt();
1689 client->startDebugging();
1690 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1693 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1694 QString jsonString(client->response);
1695 QVariantMap value = client->parser.call(QJSValue(),
1697 << QJSValue(jsonString)).toVariant().toMap();
1699 QList<QVariant> scripts = value.value("body").toList();
1701 QCOMPARE(scripts.count(), 2);
1704 void tst_QDeclarativeDebugJS::getSource()
1706 //void source(int frame = -1, int fromLine = -1, int toLine = -1);
1710 client->interrupt();
1711 client->startDebugging();
1712 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1715 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1718 QTEST_MAIN(tst_QDeclarativeDebugJS)
1720 #include "tst_qdeclarativedebugjs.moc"