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 *V8REQUEST = "v8request";
57 const char *V8MESSAGE = "v8message";
58 const char *SEQ = "seq";
59 const char *TYPE = "type";
60 const char *COMMAND = "command";
61 const char *ARGUMENTS = "arguments";
62 const char *STEPACTION = "stepaction";
63 const char *STEPCOUNT = "stepcount";
64 const char *EXPRESSION = "expression";
65 const char *FRAME = "frame";
66 const char *GLOBAL = "global";
67 const char *DISABLEBREAK = "disable_break";
68 const char *HANDLES = "handles";
69 const char *INCLUDESOURCE = "includeSource";
70 const char *FROMFRAME = "fromFrame";
71 const char *TOFRAME = "toFrame";
72 const char *BOTTOM = "bottom";
73 const char *NUMBER = "number";
74 const char *FRAMENUMBER = "frameNumber";
75 const char *TYPES = "types";
76 const char *IDS = "ids";
77 const char *FILTER = "filter";
78 const char *FROMLINE = "fromLine";
79 const char *TOLINE = "toLine";
80 const char *TARGET = "target";
81 const char *LINE = "line";
82 const char *COLUMN = "column";
83 const char *ENABLED = "enabled";
84 const char *CONDITION = "condition";
85 const char *IGNORECOUNT = "ignoreCount";
86 const char *BREAKPOINT = "breakpoint";
87 const char *FLAGS = "flags";
89 const char *CONTINEDEBUGGING = "continue";
90 const char *EVALUATE = "evaluate";
91 const char *LOOKUP = "lookup";
92 const char *BACKTRACE = "backtrace";
93 const char *SCOPE = "scope";
94 const char *SCOPES = "scopes";
95 const char *SCRIPTS = "scripts";
96 const char *SOURCE = "source";
97 const char *SETBREAKPOINT = "setbreakpoint";
98 const char *CHANGEBREAKPOINT = "changebreakpoint";
99 const char *CLEARBREAKPOINT = "clearbreakpoint";
100 const char *SETEXCEPTIONBREAK = "setexceptionbreak";
101 const char *V8FLAGS = "v8flags";
102 const char *VERSION = "version";
103 const char *DISCONNECT = "disconnect";
104 const char *LISTBREAKPOINTS = "listbreakpoints";
105 const char *GARBAGECOLLECTOR = "gc";
106 //const char *PROFILE = "profile";
108 const char *CONNECT = "connect";
109 const char *INTERRUPT = "interrupt";
111 const char *REQUEST = "request";
112 const char *IN = "in";
113 const char *NEXT = "next";
114 const char *OUT = "out";
116 const char *FUNCTION = "function";
117 const char *SCRIPT = "script";
118 const char *SCRIPTREGEXP = "scriptRegExp";
119 const char *EVENT = "event";
121 const char *ALL = "all";
122 const char *UNCAUGHT = "uncaught";
124 //const char *PAUSE = "pause";
125 //const char *RESUME = "resume";
127 const char *BLOCKMODE = "-qmljsdebugger=port:3771,block";
128 const char *NORMALMODE = "-qmljsdebugger=port:3771";
129 const char *TEST_QMLFILE = "test.qml";
130 const char *TEST_JSFILE = "test.js";
131 const char *TIMER_QMLFILE = "timer.qml";
132 const char *LOADJSFILE_QMLFILE = "loadjsfile.qml";
133 const char *EXCEPTION_QMLFILE = "exception.qml";
134 const char *ONCOMPLETED_QMLFILE = "oncompleted.qml";
135 const char *CREATECOMPONENT_QMLFILE = "createComponent.qml";
136 const char *CONDITION_QMLFILE = "condition.qml";
137 const char *CHANGEBREAKPOINT_QMLFILE = "changeBreakpoint.qml";
138 const char *STEPACTION_QMLFILE = "stepAction.qml";
139 const char *BREAKPOINTRELOCATION_QMLFILE = "breakpointRelocation.qml";
141 #define VARIANTMAPINIT \
143 QJSValue jsonVal = parser.call(QJSValue(), QJSValueList() << obj); \
144 jsonVal.setProperty(SEQ,QJSValue(seq++)); \
145 jsonVal.setProperty(TYPE,REQUEST);
149 #define QVERIFY(statement) \
151 if (!QTest::qVerify((statement), #statement, "", __FILE__, __LINE__)) {\
152 if (QTest::currentTestFailed()) \
153 qDebug().nospace() << "\nDEBUGGEE OUTPUT:\n" << process->output();\
159 class QJSDebugClient;
161 class tst_QDeclarativeDebugJS : public QObject
165 bool init(const QString &qmlFile = QString(TEST_QMLFILE), bool blockMode = true);
169 void cleanupTestCase();
176 void getVersionWhenAttaching();
184 void listBreakpoints();
186 void setBreakpointInScriptOnCompleted();
187 void setBreakpointInScriptOnComponentCreated();
188 void setBreakpointInScriptOnTimerCallback();
189 void setBreakpointInScriptInDifferentFile();
190 void setBreakpointInScriptOnComment();
191 void setBreakpointInScriptOnEmptyLine();
192 void setBreakpointInScriptWithCondition();
193 //void setBreakpointInFunction(); //NOT SUPPORTED
194 void setBreakpointOnEvent();
195 void setBreakpointWhenAttaching();
197 void changeBreakpoint();
198 void changeBreakpointOnCondition();
200 void clearBreakpoint();
202 void setExceptionBreak();
205 void stepNextWithCount();
208 void continueDebugging();
212 void getFrameDetails();
214 void getScopeDetails();
216 void evaluateInGlobalScope();
217 void evaluateInLocalScope();
225 // void profile(); //NOT SUPPORTED
227 // void verifyQMLOptimizerDisabled();
230 QDeclarativeDebugProcess *process;
231 QJSDebugClient *client;
232 QDeclarativeDebugConnection *connection;
236 class QJSDebugClient : public QDeclarativeDebugClient
254 // enum ProfileCommand
260 QJSDebugClient(QDeclarativeDebugConnection *connection)
261 : QDeclarativeDebugClient(QLatin1String("V8Debugger"), connection),
264 parser = jsEngine.evaluate(QLatin1String("JSON.parse"));
265 stringify = jsEngine.evaluate(QLatin1String("JSON.stringify"));
271 void continueDebugging(StepAction stepAction, int stepCount = 1);
272 void evaluate(QString expr, bool global = false, bool disableBreak = false, int frame = -1, const QVariantMap &addContext = QVariantMap());
273 void lookup(QList<int> handles, bool includeSource = false);
274 void backtrace(int fromFrame = -1, int toFrame = -1, bool bottom = false);
275 void frame(int number = -1);
276 void scope(int number = -1, int frameNumber = -1);
277 void scopes(int frameNumber = -1);
278 void scripts(int types = 4, QList<int> ids = QList<int>(), bool includeSource = false, QVariant filter = QVariant());
279 void source(int frame = -1, int fromLine = -1, int toLine = -1);
280 void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = true, QString condition = QString(), int ignoreCount = -1);
281 void changeBreakpoint(int breakpoint, bool enabled = true, QString condition = QString(), int ignoreCount = -1);
282 void clearBreakpoint(int breakpoint);
283 void setExceptionBreak(Exception type, bool enabled = false);
284 void v8flags(QString flags);
286 //void profile(ProfileCommand command); //NOT SUPPORTED
289 void listBreakpoints();
292 //inherited from QDeclarativeDebugClient
293 void statusChanged(Status status);
294 void messageReceived(const QByteArray &data);
299 void interruptRequested();
304 void sendMessage(const QByteArray &);
305 void flushSendBuffer();
306 QByteArray packMessage(const QByteArray &type, const QByteArray &message = QByteArray());
312 QList<QByteArray> sendBuffer;
320 void QJSDebugClient::connect()
322 sendMessage(packMessage(CONNECT));
325 void QJSDebugClient::interrupt()
327 sendMessage(packMessage(INTERRUPT));
330 void QJSDebugClient::continueDebugging(StepAction action, int count)
332 // { "seq" : <number>,
333 // "type" : "request",
334 // "command" : "continue",
335 // "arguments" : { "stepaction" : <"in", "next" or "out">,
336 // "stepcount" : <number of steps (default 1)>
340 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(CONTINEDEBUGGING)));
342 if (action != Continue) {
343 QJSValue args = parser.call(QJSValue(), QJSValueList() << obj);
345 case In: args.setProperty(QLatin1String(STEPACTION),QJSValue(QLatin1String(IN)));
347 case Out: args.setProperty(QLatin1String(STEPACTION),QJSValue(QLatin1String(OUT)));
349 case Next: args.setProperty(QLatin1String(STEPACTION),QJSValue(QLatin1String(NEXT)));
353 if (args.isValid()) {
355 args.setProperty(QLatin1String(STEPCOUNT),QJSValue(count));
356 jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
359 QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
360 sendMessage(packMessage(V8REQUEST, json.toString().toUtf8()));
363 void QJSDebugClient::evaluate(QString expr, bool global, bool disableBreak, int frame, const QVariantMap &/*addContext*/)
365 // { "seq" : <number>,
366 // "type" : "request",
367 // "command" : "evaluate",
368 // "arguments" : { "expression" : <expression to evaluate>,
369 // "frame" : <number>,
370 // "global" : <boolean>,
371 // "disable_break" : <boolean>,
372 // "additional_context" : [
373 // { "name" : <name1>, "handle" : <handle1> },
374 // { "name" : <name2>, "handle" : <handle2> },
380 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(EVALUATE)));
382 QJSValue args = parser.call(QJSValue(), QJSValueList() << obj);
383 args.setProperty(QLatin1String(EXPRESSION),QJSValue(expr));
386 args.setProperty(QLatin1String(FRAME),QJSValue(frame));
389 args.setProperty(QLatin1String(GLOBAL),QJSValue(global));
392 args.setProperty(QLatin1String(DISABLEBREAK),QJSValue(disableBreak));
394 if (args.isValid()) {
395 jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
398 QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
399 sendMessage(packMessage(V8REQUEST, json.toString().toUtf8()));
402 void QJSDebugClient::lookup(QList<int> handles, bool includeSource)
404 // { "seq" : <number>,
405 // "type" : "request",
406 // "command" : "lookup",
407 // "arguments" : { "handles" : <array of handles>,
408 // "includeSource" : <boolean indicating whether the source will be included when script objects are returned>,
412 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(LOOKUP)));
414 QJSValue args = parser.call(QJSValue(), QJSValueList() << obj);
417 QJSValue array = parser.call(QJSValue(), QJSValueList() << arr);
419 foreach (int handle, handles) {
420 array.setProperty(index++,QJSValue(handle));
422 args.setProperty(QLatin1String(HANDLES),array);
425 args.setProperty(QLatin1String(INCLUDESOURCE),QJSValue(includeSource));
427 if (args.isValid()) {
428 jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
431 QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
432 sendMessage(packMessage(V8REQUEST, json.toString().toUtf8()));
435 void QJSDebugClient::backtrace(int fromFrame, int toFrame, bool bottom)
437 // { "seq" : <number>,
438 // "type" : "request",
439 // "command" : "backtrace",
440 // "arguments" : { "fromFrame" : <number>
441 // "toFrame" : <number>
442 // "bottom" : <boolean, set to true if the bottom of the stack is requested>
446 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(BACKTRACE)));
448 QJSValue args = parser.call(QJSValue(), QJSValueList() << obj);
451 args.setProperty(QLatin1String(FROMFRAME),QJSValue(fromFrame));
454 args.setProperty(QLatin1String(TOFRAME),QJSValue(toFrame));
457 args.setProperty(QLatin1String(BOTTOM),QJSValue(bottom));
459 if (args.isValid()) {
460 jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
463 QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
464 sendMessage(packMessage(V8REQUEST, json.toString().toUtf8()));
467 void QJSDebugClient::frame(int number)
469 // { "seq" : <number>,
470 // "type" : "request",
471 // "command" : "frame",
472 // "arguments" : { "number" : <frame number>
476 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(FRAME)));
479 QJSValue args = parser.call(QJSValue(), QJSValueList() << obj);
480 args.setProperty(QLatin1String(NUMBER),QJSValue(number));
482 if (args.isValid()) {
483 jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
487 QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
488 sendMessage(packMessage(V8REQUEST, json.toString().toUtf8()));
491 void QJSDebugClient::scope(int number, int frameNumber)
493 // { "seq" : <number>,
494 // "type" : "request",
495 // "command" : "scope",
496 // "arguments" : { "number" : <scope number>
497 // "frameNumber" : <frame number, optional uses selected frame if missing>
501 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(SCOPE)));
504 QJSValue args = parser.call(QJSValue(), QJSValueList() << obj);
505 args.setProperty(QLatin1String(NUMBER),QJSValue(number));
507 if (frameNumber != -1)
508 args.setProperty(QLatin1String(FRAMENUMBER),QJSValue(frameNumber));
510 if (args.isValid()) {
511 jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
515 QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
516 sendMessage(packMessage(V8REQUEST, json.toString().toUtf8()));
519 void QJSDebugClient::scopes(int frameNumber)
521 // { "seq" : <number>,
522 // "type" : "request",
523 // "command" : "scopes",
524 // "arguments" : { "frameNumber" : <frame number, optional uses selected frame if missing>
528 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(SCOPES)));
530 if (frameNumber != -1) {
531 QJSValue args = parser.call(QJSValue(), QJSValueList() << obj);
532 args.setProperty(QLatin1String(FRAMENUMBER),QJSValue(frameNumber));
534 if (args.isValid()) {
535 jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
539 QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
540 sendMessage(packMessage(V8REQUEST, json.toString().toUtf8()));
543 void QJSDebugClient::scripts(int types, QList<int> ids, bool includeSource, QVariant /*filter*/)
545 // { "seq" : <number>,
546 // "type" : "request",
547 // "command" : "scripts",
548 // "arguments" : { "types" : <types of scripts to retrieve
549 // set bit 0 for native scripts
550 // set bit 1 for extension scripts
551 // set bit 2 for normal scripts
552 // (default is 4 for normal scripts)>
553 // "ids" : <array of id's of scripts to return. If this is not specified all scripts are requrned>
554 // "includeSource" : <boolean indicating whether the source code should be included for the scripts returned>
555 // "filter" : <string or number: filter string or script id.
556 // If a number is specified, then only the script with the same number as its script id will be retrieved.
557 // If a string is specified, then only scripts whose names contain the filter string will be retrieved.>
561 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(SCRIPTS)));
563 QJSValue args = parser.call(QJSValue(), QJSValueList() << obj);
564 args.setProperty(QLatin1String(TYPES),QJSValue(types));
568 QJSValue array = parser.call(QJSValue(), QJSValueList() << arr);
570 foreach (int id, ids) {
571 array.setProperty(index++,QJSValue(id));
573 args.setProperty(QLatin1String(IDS),array);
577 args.setProperty(QLatin1String(INCLUDESOURCE),QJSValue(includeSource));
579 if (args.isValid()) {
580 jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
583 QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
584 sendMessage(packMessage(V8REQUEST, json.toString().toUtf8()));
587 void QJSDebugClient::source(int frame, int fromLine, int toLine)
589 // { "seq" : <number>,
590 // "type" : "request",
591 // "command" : "source",
592 // "arguments" : { "frame" : <frame number (default selected frame)>
593 // "fromLine" : <from line within the source default is line 0>
594 // "toLine" : <to line within the source this line is not included in
595 // the result default is the number of lines in the script>
599 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(SOURCE)));
601 QJSValue args = parser.call(QJSValue(), QJSValueList() << obj);
604 args.setProperty(QLatin1String(FRAME),QJSValue(frame));
607 args.setProperty(QLatin1String(FROMLINE),QJSValue(fromLine));
610 args.setProperty(QLatin1String(TOLINE),QJSValue(toLine));
612 if (args.isValid()) {
613 jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
616 QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
617 sendMessage(packMessage(V8REQUEST, json.toString().toUtf8()));
620 void QJSDebugClient::setBreakpoint(QString type, QString target, int line, int column, bool enabled, QString condition, int ignoreCount)
622 // { "seq" : <number>,
623 // "type" : "request",
624 // "command" : "setbreakpoint",
625 // "arguments" : { "type" : <"function" or "script" or "scriptId" or "scriptRegExp">
626 // "target" : <function expression or script identification>
627 // "line" : <line in script or function>
628 // "column" : <character position within the line>
629 // "enabled" : <initial enabled state. True or false, default is true>
630 // "condition" : <string with break point condition>
631 // "ignoreCount" : <number specifying the number of break point hits to ignore, default value is 0>
635 if (type == QLatin1String(EVENT)) {
637 QDataStream rs(&reply, QIODevice::WriteOnly);
638 rs << target.toUtf8() << enabled;
639 sendMessage(packMessage(QByteArray("breakonsignal"), reply));
643 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(SETBREAKPOINT)));
645 QJSValue args = parser.call(QJSValue(), QJSValueList() << obj);
647 args.setProperty(QLatin1String(TYPE),QJSValue(type));
648 args.setProperty(QLatin1String(TARGET),QJSValue(target));
651 args.setProperty(QLatin1String(LINE),QJSValue(line));
654 args.setProperty(QLatin1String(COLUMN),QJSValue(column));
656 args.setProperty(QLatin1String(ENABLED),QJSValue(enabled));
658 if (!condition.isEmpty())
659 args.setProperty(QLatin1String(CONDITION),QJSValue(condition));
661 if (ignoreCount != -1)
662 args.setProperty(QLatin1String(IGNORECOUNT),QJSValue(ignoreCount));
664 if (args.isValid()) {
665 jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
668 QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
669 sendMessage(packMessage(V8REQUEST, json.toString().toUtf8()));
673 void QJSDebugClient::changeBreakpoint(int breakpoint, bool enabled, QString condition, int ignoreCount)
675 // { "seq" : <number>,
676 // "type" : "request",
677 // "command" : "changebreakpoint",
678 // "arguments" : { "breakpoint" : <number of the break point to clear>
679 // "enabled" : <initial enabled state. True or false, default is true>
680 // "condition" : <string with break point condition>
681 // "ignoreCount" : <number specifying the number of break point hits }
684 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(CHANGEBREAKPOINT)));
686 QJSValue args = parser.call(QJSValue(), QJSValueList() << obj);
688 args.setProperty(QLatin1String(BREAKPOINT),QJSValue(breakpoint));
690 args.setProperty(QLatin1String(ENABLED),QJSValue(enabled));
692 if (!condition.isEmpty())
693 args.setProperty(QLatin1String(CONDITION),QJSValue(condition));
695 if (ignoreCount != -1)
696 args.setProperty(QLatin1String(IGNORECOUNT),QJSValue(ignoreCount));
698 if (args.isValid()) {
699 jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
702 QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
703 sendMessage(packMessage(V8REQUEST, json.toString().toUtf8()));
706 void QJSDebugClient::clearBreakpoint(int breakpoint)
708 // { "seq" : <number>,
709 // "type" : "request",
710 // "command" : "clearbreakpoint",
711 // "arguments" : { "breakpoint" : <number of the break point to clear>
715 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(CLEARBREAKPOINT)));
717 QJSValue args = parser.call(QJSValue(), QJSValueList() << obj);
719 args.setProperty(QLatin1String(BREAKPOINT),QJSValue(breakpoint));
721 if (args.isValid()) {
722 jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
725 QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
726 sendMessage(packMessage(V8REQUEST, json.toString().toUtf8()));
729 void QJSDebugClient::setExceptionBreak(Exception type, bool enabled)
731 // { "seq" : <number>,
732 // "type" : "request",
733 // "command" : "setexceptionbreak",
734 // "arguments" : { "type" : <string: "all", or "uncaught">,
735 // "enabled" : <optional bool: enables the break type if true>
739 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(SETEXCEPTIONBREAK)));
741 QJSValue args = parser.call(QJSValue(), QJSValueList() << obj);
744 args.setProperty(QLatin1String(TYPE),QJSValue(QLatin1String(ALL)));
745 else if (type == Uncaught)
746 args.setProperty(QLatin1String(TYPE),QJSValue(QLatin1String(UNCAUGHT)));
749 args.setProperty(QLatin1String(ENABLED),QJSValue(enabled));
751 if (args.isValid()) {
752 jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
755 QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
756 sendMessage(packMessage(V8REQUEST, json.toString().toUtf8()));
759 void QJSDebugClient::v8flags(QString flags)
761 // { "seq" : <number>,
762 // "type" : "request",
763 // "command" : "v8flags",
764 // "arguments" : { "flags" : <string: a sequence of v8 flags just like those used on the command line>
768 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(V8FLAGS)));
770 QJSValue args = parser.call(QJSValue(), QJSValueList() << obj);
772 args.setProperty(QLatin1String(FLAGS),QJSValue(flags));
774 if (args.isValid()) {
775 jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
778 QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
779 sendMessage(packMessage(V8REQUEST, json.toString().toUtf8()));
782 void QJSDebugClient::version()
784 // { "seq" : <number>,
785 // "type" : "request",
786 // "command" : "version",
789 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(VERSION)));
791 QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
792 sendMessage(packMessage(V8REQUEST, json.toString().toUtf8()));
795 //void QJSDebugClient::profile(ProfileCommand command)
797 //// { "seq" : <number>,
798 //// "type" : "request",
799 //// "command" : "profile",
800 //// "arguments" : { "command" : "resume" or "pause" }
803 // jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(PROFILE)));
805 // QJSValue args = parser.call(QJSValue(), QJSValueList() << obj);
807 // if (command == Resume)
808 // args.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(RESUME)));
810 // args.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(PAUSE)));
812 // args.setProperty(QLatin1String("modules"),QJSValue(1));
813 // if (args.isValid()) {
814 // jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
817 // QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
818 // sendMessage(packMessage(V8REQUEST, json.toString().toUtf8()));
821 void QJSDebugClient::disconnect()
823 // { "seq" : <number>,
824 // "type" : "request",
825 // "command" : "disconnect",
828 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(DISCONNECT)));
830 QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
831 sendMessage(packMessage(DISCONNECT, json.toString().toUtf8()));
834 void QJSDebugClient::gc()
836 // { "seq" : <number>,
837 // "type" : "request",
839 // "arguments" : { "type" : <string: "all">,
843 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(GARBAGECOLLECTOR)));
845 QJSValue args = parser.call(QJSValue(), QJSValueList() << obj);
847 args.setProperty(QLatin1String(TYPE),QJSValue(QLatin1String(ALL)));
849 if (args.isValid()) {
850 jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
853 QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
854 sendMessage(packMessage(V8REQUEST, json.toString().toUtf8()));
857 void QJSDebugClient::listBreakpoints()
859 // { "seq" : <number>,
860 // "type" : "request",
861 // "command" : "listbreakpoints",
864 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(LISTBREAKPOINTS)));
866 QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
867 sendMessage(packMessage(V8REQUEST, json.toString().toUtf8()));
870 void QJSDebugClient::statusChanged(Status status)
872 if (status == Enabled) {
878 void QJSDebugClient::messageReceived(const QByteArray &data)
880 QDataStream ds(data);
884 if (command == "V8DEBUG") {
886 ds >> type >> response;
888 if (type == CONNECT) {
891 } else if (type == INTERRUPT) {
892 emit interruptRequested();
894 } else if (type == V8MESSAGE) {
895 QString jsonString(response);
896 QVariantMap value = parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
897 QString type = value.value("type").toString();
899 if (type == "response") {
901 if (!value.value("success").toBool()) {
902 // qDebug() << "Error: The test case will fail since no signal is emitted";
906 QString debugCommand(value.value("command").toString());
907 if (debugCommand == "backtrace" ||
908 debugCommand == "lookup" ||
909 debugCommand == "setbreakpoint" ||
910 debugCommand == "evaluate" ||
911 debugCommand == "listbreakpoints" ||
912 debugCommand == "version" ||
913 debugCommand == "v8flags" ||
914 debugCommand == "disconnect" ||
915 debugCommand == "gc" ||
916 debugCommand == "changebreakpoint" ||
917 debugCommand == "clearbreakpoint" ||
918 debugCommand == "frame" ||
919 debugCommand == "scope" ||
920 debugCommand == "scopes" ||
921 debugCommand == "scripts" ||
922 debugCommand == "source" ||
923 debugCommand == "setexceptionbreak" /*||
924 debugCommand == "profile"*/) {
931 } else if (type == QLatin1String(EVENT)) {
932 QString event(value.value(QLatin1String(EVENT)).toString());
934 if (event == "break" ||
935 event == "exception")
942 void QJSDebugClient::sendMessage(const QByteArray &msg)
944 if (status() == Enabled) {
945 QDeclarativeDebugClient::sendMessage(msg);
947 sendBuffer.append(msg);
951 void QJSDebugClient::flushSendBuffer()
953 foreach (const QByteArray &msg, sendBuffer)
954 QDeclarativeDebugClient::sendMessage(msg);
958 QByteArray QJSDebugClient::packMessage(const QByteArray &type, const QByteArray &message)
961 QDataStream rs(&reply, QIODevice::WriteOnly);
962 QByteArray cmd = "V8DEBUG";
963 rs << cmd << type << message;
967 void tst_QDeclarativeDebugJS::initTestCase()
975 void tst_QDeclarativeDebugJS::cleanupTestCase()
988 // qDebug() << "Time Elapsed:" << t.elapsed();
991 bool tst_QDeclarativeDebugJS::init(const QString &qmlFile, bool blockMode)
993 connection = new QDeclarativeDebugConnection();
994 process = new QDeclarativeDebugProcess(QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene");
995 client = new QJSDebugClient(connection);
997 QStringList systemEnvironment = QProcess::systemEnvironment();
998 systemEnvironment << "QML_DISABLE_OPTIMIZER=1";
999 process->setEnvironment(systemEnvironment);
1001 process->start(QStringList() << QLatin1String(BLOCKMODE) << TESTDATA(qmlFile));
1003 process->start(QStringList() << QLatin1String(NORMALMODE) << TESTDATA(qmlFile));
1005 if (!process->waitForSessionStart()) {
1009 connection->connectToHost("127.0.0.1", 3771);
1010 if (!connection->waitForConnected())
1013 return QDeclarativeDebugTest::waitForSignal(client, SIGNAL(enabled()));
1016 void tst_QDeclarativeDebugJS::cleanup()
1034 void tst_QDeclarativeDebugJS::connect()
1040 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(connected())));
1043 void tst_QDeclarativeDebugJS::interrupt()
1050 client->interrupt();
1051 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(interruptRequested())));
1054 void tst_QDeclarativeDebugJS::getVersion()
1060 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(connected())));
1063 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1066 void tst_QDeclarativeDebugJS::getVersionWhenAttaching()
1070 QVERIFY(init(QLatin1String(TIMER_QMLFILE), false));
1074 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1077 void tst_QDeclarativeDebugJS::applyV8Flags()
1079 //void v8flags(QString flags)
1084 client->v8flags(QString());
1085 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1088 void tst_QDeclarativeDebugJS::disconnect()
1095 client->disconnect();
1096 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1099 void tst_QDeclarativeDebugJS::gc()
1107 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1110 void tst_QDeclarativeDebugJS::listBreakpoints()
1112 //void listBreakpoints()
1114 int sourceLine1 = 47;
1115 int sourceLine2 = 48;
1116 int sourceLine3 = 49;
1121 client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(TEST_QMLFILE), sourceLine1, -1, true);
1122 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1123 client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(TEST_QMLFILE), sourceLine2, -1, true);
1124 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1125 client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(TEST_QMLFILE), sourceLine3, -1, true);
1126 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1127 client->listBreakpoints();
1128 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1130 QString jsonString(client->response);
1131 QVariantMap value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1133 QList<QVariant> breakpoints = value.value("body").toMap().value("breakpoints").toList();
1135 QCOMPARE(breakpoints.count(), 3);
1138 void tst_QDeclarativeDebugJS::setBreakpointInScriptOnCompleted()
1140 //void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1)
1142 int sourceLine = 47;
1143 QVERIFY(init(ONCOMPLETED_QMLFILE));
1145 client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true);
1147 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1149 QString jsonString(client->response);
1150 QVariantMap value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1152 QVariantMap body = value.value("body").toMap();
1154 QCOMPARE(body.value("sourceLine").toInt(), sourceLine);
1155 QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(ONCOMPLETED_QMLFILE));
1158 void tst_QDeclarativeDebugJS::setBreakpointInScriptOnComponentCreated()
1160 //void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1)
1162 int sourceLine = 47;
1163 QVERIFY(init(CREATECOMPONENT_QMLFILE));
1165 client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true);
1167 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1169 QString jsonString(client->response);
1170 QVariantMap value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1172 QVariantMap body = value.value("body").toMap();
1174 QCOMPARE(body.value("sourceLine").toInt(), sourceLine);
1175 QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(ONCOMPLETED_QMLFILE));
1178 void tst_QDeclarativeDebugJS::setBreakpointInScriptOnTimerCallback()
1180 int sourceLine = 48;
1181 QVERIFY(init(TIMER_QMLFILE));
1185 client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(TIMER_QMLFILE), sourceLine, -1, true);
1186 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1188 QString jsonString(client->response);
1189 QVariantMap value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1191 QVariantMap body = value.value("body").toMap();
1193 QCOMPARE(body.value("sourceLine").toInt(), sourceLine);
1194 QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(TIMER_QMLFILE));
1197 void tst_QDeclarativeDebugJS::setBreakpointInScriptInDifferentFile()
1199 //void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1)
1201 int sourceLine = 43;
1202 QVERIFY(init(LOADJSFILE_QMLFILE));
1205 client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(TEST_JSFILE), sourceLine, -1, true);
1206 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1208 QString jsonString(client->response);
1209 QVariantMap value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1211 QVariantMap body = value.value("body").toMap();
1213 QCOMPARE(body.value("sourceLine").toInt(), sourceLine);
1214 QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(TEST_JSFILE));
1217 void tst_QDeclarativeDebugJS::setBreakpointInScriptOnComment()
1219 //void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1)
1221 int sourceLine = 47;
1222 int actualLine = 49;
1223 QVERIFY(init(BREAKPOINTRELOCATION_QMLFILE));
1226 client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(BREAKPOINTRELOCATION_QMLFILE), sourceLine, -1, true);
1227 QEXPECT_FAIL("", "Relocation of breakpoints is disabled right now", Abort);
1228 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped()), 1));
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(BREAKPOINTRELOCATION_QMLFILE));
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 = 48;
1244 int actualLine = 49;
1245 QVERIFY(init(BREAKPOINTRELOCATION_QMLFILE));
1248 client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(BREAKPOINTRELOCATION_QMLFILE), sourceLine, -1, true);
1249 QEXPECT_FAIL("", "Relocation of breakpoints is disabled right now", Abort);
1250 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped()), 1));
1252 QString jsonString(client->response);
1253 QVariantMap value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1255 QVariantMap body = value.value("body").toMap();
1257 QCOMPARE(body.value("sourceLine").toInt(), actualLine);
1258 QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(BREAKPOINTRELOCATION_QMLFILE));
1261 void tst_QDeclarativeDebugJS::setBreakpointInScriptWithCondition()
1263 //void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1)
1266 int sourceLine = 50;
1267 QVERIFY(init(CONDITION_QMLFILE));
1270 client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(CONDITION_QMLFILE), sourceLine, 1, true, QLatin1String("a > 10"));
1271 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1273 //Get the frame index
1274 QString jsonString = client->response;
1275 QVariantMap value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1277 QVariantMap body = value.value("body").toMap();
1279 int frameIndex = body.value("index").toInt();
1281 //Verify the value of 'result'
1282 client->evaluate(QLatin1String("a"),frameIndex);
1284 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1286 jsonString = client->response;
1287 value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1289 body = value.value("body").toMap();
1291 QVERIFY(body.value("value").toInt() > out);
1294 void tst_QDeclarativeDebugJS::setBreakpointWhenAttaching()
1296 int sourceLine = 49;
1297 QVERIFY(init(QLatin1String(TIMER_QMLFILE), false));
1300 client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(TIMER_QMLFILE), sourceLine);
1301 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1304 //void tst_QDeclarativeDebugJS::setBreakpointInFunction()
1306 // //void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1)
1308 // int actualLine = 31;
1310 // client->connect();
1311 // client->setBreakpoint(QLatin1String(FUNCTION), QLatin1String("doSomethingElse"), -1, -1, true);
1313 // QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1315 // QString jsonString(client->response);
1316 // QVariantMap value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1318 // QVariantMap body = value.value("body").toMap();
1320 // QCOMPARE(body.value("sourceLine").toInt(), actualLine);
1321 // QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(QMLFILE));
1324 void tst_QDeclarativeDebugJS::setBreakpointOnEvent()
1326 //void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1)
1328 QVERIFY(init(TIMER_QMLFILE));
1332 client->setBreakpoint(QLatin1String(EVENT), QLatin1String("triggered"), -1, -1, true);
1333 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1335 QString jsonString(client->response);
1336 QVariantMap value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1338 QVariantMap body = value.value("body").toMap();
1340 QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(TIMER_QMLFILE));
1344 void tst_QDeclarativeDebugJS::changeBreakpoint()
1346 //void changeBreakpoint(int breakpoint, bool enabled = false, QString condition = QString(), int ignoreCount = -1)
1348 int sourceLine1 = 50;
1349 int sourceLine2 = 51;
1350 QVERIFY(init(CHANGEBREAKPOINT_QMLFILE));
1353 client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(CHANGEBREAKPOINT_QMLFILE), sourceLine2, -1, true);
1354 client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(CHANGEBREAKPOINT_QMLFILE), sourceLine1, -1, true);
1356 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1358 //Will hit 1st brakpoint, change this breakpoint enable = false
1359 QString jsonString(client->response);
1360 QVariantMap value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1362 QVariantMap body = value.value("body").toMap();
1363 QList<QVariant> breakpointsHit = body.value("breakpoints").toList();
1365 int breakpoint = breakpointsHit.at(0).toInt();
1366 client->changeBreakpoint(breakpoint,false);
1368 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1370 //Continue with debugging
1371 client->continueDebugging(QJSDebugClient::Continue);
1372 //Hit 2nd breakpoint
1373 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1375 //Continue with debugging
1376 client->continueDebugging(QJSDebugClient::Continue);
1377 //Should stop at 2nd breakpoint
1378 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1380 jsonString = client->response;
1381 value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1383 body = value.value("body").toMap();
1385 QCOMPARE(body.value("sourceLine").toInt(), sourceLine2);
1388 void tst_QDeclarativeDebugJS::changeBreakpointOnCondition()
1390 //void changeBreakpoint(int breakpoint, bool enabled = false, QString condition = QString(), int ignoreCount = -1)
1392 int sourceLine1 = 50;
1393 int sourceLine2 = 51;
1395 QVERIFY(init(CHANGEBREAKPOINT_QMLFILE));
1398 client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(CHANGEBREAKPOINT_QMLFILE), sourceLine1, -1, true);
1399 client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(CHANGEBREAKPOINT_QMLFILE), sourceLine2, -1, true);
1401 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1403 //Will hit 1st brakpoint, change this breakpoint enable = false
1404 QString jsonString(client->response);
1405 QVariantMap value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1407 QVariantMap body = value.value("body").toMap();
1408 QList<QVariant> breakpointsHit = body.value("breakpoints").toList();
1410 int breakpoint = breakpointsHit.at(0).toInt();
1411 client->changeBreakpoint(breakpoint, false, QLatin1String("d == 0"));
1413 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1415 //Continue with debugging
1416 client->continueDebugging(QJSDebugClient::Continue);
1417 //Hit 2nd breakpoint
1418 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1420 //Continue with debugging
1421 client->continueDebugging(QJSDebugClient::Continue);
1422 //Should stop at 2nd breakpoint
1423 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1425 jsonString = client->response;
1426 value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1428 body = value.value("body").toMap();
1430 QCOMPARE(body.value("sourceLine").toInt(), sourceLine2);
1434 void tst_QDeclarativeDebugJS::clearBreakpoint()
1436 //void clearBreakpoint(int breakpoint);
1438 int sourceLine1 = 50;
1439 int sourceLine2 = 51;
1440 QVERIFY(init(CHANGEBREAKPOINT_QMLFILE));
1443 client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(CHANGEBREAKPOINT_QMLFILE), sourceLine1, -1, true);
1444 client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(CHANGEBREAKPOINT_QMLFILE), sourceLine2, -1, true);
1446 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1448 //Will hit 1st brakpoint, change this breakpoint enable = false
1449 QString jsonString(client->response);
1450 QVariantMap value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1452 QVariantMap body = value.value("body").toMap();
1453 QList<QVariant> breakpointsHit = body.value("breakpoints").toList();
1455 int breakpoint = breakpointsHit.at(0).toInt();
1456 client->clearBreakpoint(breakpoint);
1458 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1460 //Continue with debugging
1461 client->continueDebugging(QJSDebugClient::Continue);
1462 //Hit 2nd breakpoint
1463 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1465 //Continue with debugging
1466 client->continueDebugging(QJSDebugClient::Continue);
1467 //Should stop at 2nd breakpoint
1468 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1470 jsonString = client->response;
1471 value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1473 body = value.value("body").toMap();
1475 QCOMPARE(body.value("sourceLine").toInt(), sourceLine2);
1478 void tst_QDeclarativeDebugJS::setExceptionBreak()
1480 //void setExceptionBreak(QString type, bool enabled = false);
1482 QVERIFY(init(EXCEPTION_QMLFILE));
1483 client->setExceptionBreak(QJSDebugClient::All,true);
1485 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1488 void tst_QDeclarativeDebugJS::stepNext()
1490 //void continueDebugging(StepAction stepAction, int stepCount = 1);
1492 int sourceLine = 50;
1493 QVERIFY(init(STEPACTION_QMLFILE));
1495 client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(STEPACTION_QMLFILE), sourceLine, -1, true);
1497 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1499 client->continueDebugging(QJSDebugClient::Next);
1500 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1502 QString jsonString(client->response);
1503 QVariantMap value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1505 QVariantMap body = value.value("body").toMap();
1507 QCOMPARE(body.value("sourceLine").toInt(), sourceLine + 1);
1508 QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(STEPACTION_QMLFILE));
1511 void tst_QDeclarativeDebugJS::stepNextWithCount()
1513 //void continueDebugging(StepAction stepAction, int stepCount = 1);
1515 int sourceLine = 50;
1516 QVERIFY(init(STEPACTION_QMLFILE));
1519 client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(STEPACTION_QMLFILE), sourceLine, -1, true);
1520 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1522 client->continueDebugging(QJSDebugClient::Next, 2);
1523 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1525 QString jsonString(client->response);
1526 QVariantMap value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1528 QVariantMap body = value.value("body").toMap();
1530 QCOMPARE(body.value("sourceLine").toInt(), sourceLine + 2);
1531 QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(STEPACTION_QMLFILE));
1534 void tst_QDeclarativeDebugJS::stepIn()
1536 //void continueDebugging(StepAction stepAction, int stepCount = 1);
1538 int sourceLine = 54;
1539 int actualLine = 50;
1540 QVERIFY(init(STEPACTION_QMLFILE));
1543 client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(STEPACTION_QMLFILE), sourceLine, 1, true);
1544 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1546 client->continueDebugging(QJSDebugClient::In);
1547 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1549 QString jsonString(client->response);
1550 QVariantMap value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1552 QVariantMap body = value.value("body").toMap();
1554 QCOMPARE(body.value("sourceLine").toInt(), actualLine);
1555 QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(STEPACTION_QMLFILE));
1558 void tst_QDeclarativeDebugJS::stepOut()
1560 //void continueDebugging(StepAction stepAction, int stepCount = 1);
1562 int sourceLine = 50;
1563 int actualLine = 54;
1564 QVERIFY(init(STEPACTION_QMLFILE));
1567 client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(STEPACTION_QMLFILE), sourceLine, -1, true);
1568 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1570 client->continueDebugging(QJSDebugClient::Out);
1571 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1573 QString jsonString(client->response);
1574 QVariantMap value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1576 QVariantMap body = value.value("body").toMap();
1578 QCOMPARE(body.value("sourceLine").toInt(), actualLine);
1579 QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(STEPACTION_QMLFILE));
1582 void tst_QDeclarativeDebugJS::continueDebugging()
1584 //void continueDebugging(StepAction stepAction, int stepCount = 1);
1586 int sourceLine1 = 54;
1587 int sourceLine2 = 51;
1588 QVERIFY(init(STEPACTION_QMLFILE));
1591 client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(STEPACTION_QMLFILE), sourceLine1, -1, true);
1592 client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(STEPACTION_QMLFILE), sourceLine2, -1, true);
1593 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1595 client->continueDebugging(QJSDebugClient::Continue);
1596 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1598 QString jsonString(client->response);
1599 QVariantMap value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1601 QVariantMap body = value.value("body").toMap();
1603 QCOMPARE(body.value("sourceLine").toInt(), sourceLine2);
1604 QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(STEPACTION_QMLFILE));
1607 void tst_QDeclarativeDebugJS::backtrace()
1609 //void backtrace(int fromFrame = -1, int toFrame = -1, bool bottom = false);
1611 int sourceLine = 47;
1612 QVERIFY(init(ONCOMPLETED_QMLFILE));
1614 client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true);
1616 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1618 client->backtrace();
1619 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1622 void tst_QDeclarativeDebugJS::getFrameDetails()
1624 //void frame(int number = -1);
1626 int sourceLine = 47;
1627 QVERIFY(init(ONCOMPLETED_QMLFILE));
1629 client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true);
1631 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1634 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1637 void tst_QDeclarativeDebugJS::getScopeDetails()
1639 //void scope(int number = -1, int frameNumber = -1);
1641 int sourceLine = 47;
1642 QVERIFY(init(ONCOMPLETED_QMLFILE));
1644 client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true);
1646 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1649 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1652 void tst_QDeclarativeDebugJS::evaluateInGlobalScope()
1654 //void evaluate(QString expr, bool global = false, bool disableBreak = false, int frame = -1, const QVariantMap &addContext = QVariantMap());
1659 client->evaluate(QLatin1String("print('Hello World')"), true);
1660 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1662 //Verify the value of 'print'
1663 QString jsonString(client->response);
1664 QVariantMap value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1666 QVariantMap body = value.value("body").toMap();
1668 QCOMPARE(body.value("text").toString(),QLatin1String("undefined"));
1671 void tst_QDeclarativeDebugJS::evaluateInLocalScope()
1673 //void evaluate(QString expr, bool global = false, bool disableBreak = false, int frame = -1, const QVariantMap &addContext = QVariantMap());
1675 int sourceLine = 47;
1676 QVERIFY(init(ONCOMPLETED_QMLFILE));
1678 client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true);
1680 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1683 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1685 //Get the frame index
1686 QString jsonString(client->response);
1687 QVariantMap value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1689 QVariantMap body = value.value("body").toMap();
1691 int frameIndex = body.value("index").toInt();
1693 client->evaluate(QLatin1String("root.a"), frameIndex);
1694 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1696 //Verify the value of 'timer.interval'
1697 jsonString = client->response;
1698 value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1700 body = value.value("body").toMap();
1702 QCOMPARE(body.value("value").toInt(),10);
1705 void tst_QDeclarativeDebugJS::getScopes()
1707 //void scopes(int frameNumber = -1);
1709 int sourceLine = 47;
1710 QVERIFY(init(ONCOMPLETED_QMLFILE));
1712 client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true);
1714 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1717 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1720 void tst_QDeclarativeDebugJS::getScripts()
1722 //void scripts(int types = -1, QList<int> ids = QList<int>(), bool includeSource = false, QVariant filter = QVariant());
1729 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1730 QString jsonString(client->response);
1731 QVariantMap value = client->parser.call(QJSValue(),
1733 << QJSValue(jsonString)).toVariant().toMap();
1735 QList<QVariant> scripts = value.value("body").toList();
1737 QCOMPARE(scripts.count(), 2);
1740 void tst_QDeclarativeDebugJS::getSource()
1742 //void source(int frame = -1, int fromLine = -1, int toLine = -1);
1744 int sourceLine = 47;
1745 QVERIFY(init(ONCOMPLETED_QMLFILE));
1747 client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true);
1749 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1752 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1755 QTEST_MAIN(tst_QDeclarativeDebugJS)
1757 #include "tst_qdeclarativedebugjs.moc"