1 /****************************************************************************
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the test suite of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
43 #include <QtCore/QProcess>
44 #include <QtCore/QTimer>
45 #include <QtCore/QFileInfo>
46 #include <QtCore/QDir>
47 #include <QtCore/QMutex>
48 #include <QtCore/QLibraryInfo>
49 #include <QtDeclarative/private/qdeclarativedebugclient_p.h>
50 #include <QtDeclarative/QJSEngine>
52 //QDeclarativeDebugTest
53 #include "../shared/debugutil_p.h"
54 #include "../../shared/util.h"
56 const char *SEQ = "seq";
57 const char *TYPE = "type";
58 const char *COMMAND = "command";
59 const char *ARGUMENTS = "arguments";
60 const char *STEPACTION = "stepaction";
61 const char *STEPCOUNT = "stepcount";
62 const char *EXPRESSION = "expression";
63 const char *FRAME = "frame";
64 const char *GLOBAL = "global";
65 const char *DISABLEBREAK = "disable_break";
66 const char *HANDLES = "handles";
67 const char *INCLUDESOURCE = "includeSource";
68 const char *FROMFRAME = "fromFrame";
69 const char *TOFRAME = "toFrame";
70 const char *BOTTOM = "bottom";
71 const char *NUMBER = "number";
72 const char *FRAMENUMBER = "frameNumber";
73 const char *TYPES = "types";
74 const char *IDS = "ids";
75 const char *FILTER = "filter";
76 const char *FROMLINE = "fromLine";
77 const char *TOLINE = "toLine";
78 const char *TARGET = "target";
79 const char *LINE = "line";
80 const char *COLUMN = "column";
81 const char *ENABLED = "enabled";
82 const char *CONDITION = "condition";
83 const char *IGNORECOUNT = "ignoreCount";
84 const char *BREAKPOINT = "breakpoint";
85 const char *FLAGS = "flags";
87 const char *CONTINEDEBUGGING = "continue";
88 const char *EVALUATE = "evaluate";
89 const char *LOOKUP = "lookup";
90 const char *BACKTRACE = "backtrace";
91 const char *SCOPE = "scope";
92 const char *SCOPES = "scopes";
93 const char *SCRIPTS = "scripts";
94 const char *SOURCE = "source";
95 const char *SETBREAKPOINT = "setbreakpoint";
96 const char *CHANGEBREAKPOINT = "changebreakpoint";
97 const char *CLEARBREAKPOINT = "clearbreakpoint";
98 const char *SETEXCEPTIONBREAK = "setexceptionbreak";
99 const char *V8FLAGS = "v8flags";
100 const char *VERSION = "version";
101 const char *DISCONNECT = "disconnect";
102 const char *LISTBREAKPOINTS = "listbreakpoints";
103 const char *GARBAGECOLLECTOR = "gc";
104 //const char *PROFILE = "profile";
106 const char *CONNECT = "connect";
107 const char *INTERRUPT = "interrupt";
109 const char *REQUEST = "request";
110 const char *IN = "in";
111 const char *NEXT = "next";
112 const char *OUT = "out";
114 const char *FUNCTION = "function";
115 const char *SCRIPT = "script";
117 const char *ALL = "all";
118 const char *UNCAUGHT = "uncaught";
120 //const char *PAUSE = "pause";
121 //const char *RESUME = "resume";
123 const char *BLOCKMODE = "-qmljsdebugger=port:3771,block";
124 const char *NORMALMODE = "-qmljsdebugger=port:3771";
125 const char *QMLFILE = "test.qml";
126 const char *JSFILE = "test.js";
128 #define VARIANTMAPINIT \
130 QJSValue jsonVal = parser.call(QJSValue(), QJSValueList() << obj); \
131 jsonVal.setProperty(SEQ,QJSValue(seq++)); \
132 jsonVal.setProperty(TYPE,REQUEST);
136 #define QVERIFY(statement) \
138 if (!QTest::qVerify((statement), #statement, "", __FILE__, __LINE__)) {\
139 qDebug().nospace() << "\nDEBUGGEE OUTPUT:\n" << process->output();\
145 class QJSDebugClient;
147 class tst_QDeclarativeDebugJS : public QObject
154 void cleanupTestCase();
167 void listBreakpoints();
169 void setBreakpointInScriptOnCompleted();
170 void setBreakpointInScriptOnTimerCallback();
171 void setBreakpointInScriptInDifferentFile();
172 void setBreakpointInScriptOnComment();
173 void setBreakpointInScriptOnEmptyLine();
174 void setBreakpointInScriptWithCondition();
175 //void setBreakpointInFunction(); //NOT SUPPORTED
177 void changeBreakpoint();
178 void changeBreakpointOnCondition();
180 void clearBreakpoint();
182 void setExceptionBreak();
185 void stepNextWithCount();
188 void continueDebugging();
192 void getFrameDetails();
194 void getScopeDetails();
196 void evaluateInGlobalScope();
197 void evaluateInLocalScope();
205 // void profile(); //NOT SUPPORTED
207 // void verifyQMLOptimizerDisabled();
210 QDeclarativeDebugProcess *process;
211 QJSDebugClient *client;
212 QDeclarativeDebugConnection *connection;
215 class QJSDebugClient : public QDeclarativeDebugClient
233 // enum ProfileCommand
239 QJSDebugClient(QDeclarativeDebugConnection *connection)
240 : QDeclarativeDebugClient(QLatin1String("V8Debugger"), connection),
243 parser = jsEngine.evaluate(QLatin1String("JSON.parse"));
244 stringify = jsEngine.evaluate(QLatin1String("JSON.stringify"));
247 void startDebugging();
250 void continueDebugging(StepAction stepAction, int stepCount = 1);
251 void evaluate(QString expr, bool global = false, bool disableBreak = false, int frame = -1, const QVariantMap &addContext = QVariantMap());
252 void lookup(QList<int> handles, bool includeSource = false);
253 void backtrace(int fromFrame = -1, int toFrame = -1, bool bottom = false);
254 void frame(int number = -1);
255 void scope(int number = -1, int frameNumber = -1);
256 void scopes(int frameNumber = -1);
257 void scripts(int types = 4, QList<int> ids = QList<int>(), bool includeSource = false, QVariant filter = QVariant());
258 void source(int frame = -1, int fromLine = -1, int toLine = -1);
259 void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = true, QString condition = QString(), int ignoreCount = -1);
260 void changeBreakpoint(int breakpoint, bool enabled = true, QString condition = QString(), int ignoreCount = -1);
261 void clearBreakpoint(int breakpoint);
262 void setExceptionBreak(Exception type, bool enabled = false);
263 void v8flags(QString flags);
265 //void profile(ProfileCommand command); //NOT SUPPORTED
268 void listBreakpoints();
271 //inherited from QDeclarativeDebugClient
272 void statusChanged(Status status);
273 void messageReceived(const QByteArray &data);
277 void breakpointSet();
282 void sendMessage(const QByteArray &);
283 void flushSendBuffer();
284 QByteArray packMessage(QByteArray message);
290 QList<QByteArray> sendBuffer;
299 void QJSDebugClient::startDebugging()
301 // { "seq" : <number>,
302 // "type" : "request",
303 // "command" : "connect",
306 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(CONNECT)));
308 QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
309 sendMessage(packMessage(json.toString().toUtf8()));
312 void QJSDebugClient::interrupt()
314 // { "seq" : <number>,
315 // "type" : "request",
316 // "command" : "interrupt",
319 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(INTERRUPT)));
321 QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
322 sendMessage(packMessage(json.toString().toUtf8()));
325 void QJSDebugClient::continueDebugging(StepAction action, int count)
327 // { "seq" : <number>,
328 // "type" : "request",
329 // "command" : "continue",
330 // "arguments" : { "stepaction" : <"in", "next" or "out">,
331 // "stepcount" : <number of steps (default 1)>
335 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(CONTINEDEBUGGING)));
337 if (action != Continue) {
338 QJSValue args = parser.call(QJSValue(), QJSValueList() << obj);
340 case In: args.setProperty(QLatin1String(STEPACTION),QJSValue(QLatin1String(IN)));
342 case Out: args.setProperty(QLatin1String(STEPACTION),QJSValue(QLatin1String(OUT)));
344 case Next: args.setProperty(QLatin1String(STEPACTION),QJSValue(QLatin1String(NEXT)));
348 if (args.isValid()) {
350 args.setProperty(QLatin1String(STEPCOUNT),QJSValue(count));
351 jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
354 QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
355 sendMessage(packMessage(json.toString().toUtf8()));
358 void QJSDebugClient::evaluate(QString expr, bool global, bool disableBreak, int frame, const QVariantMap &/*addContext*/)
360 // { "seq" : <number>,
361 // "type" : "request",
362 // "command" : "evaluate",
363 // "arguments" : { "expression" : <expression to evaluate>,
364 // "frame" : <number>,
365 // "global" : <boolean>,
366 // "disable_break" : <boolean>,
367 // "additional_context" : [
368 // { "name" : <name1>, "handle" : <handle1> },
369 // { "name" : <name2>, "handle" : <handle2> },
375 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(EVALUATE)));
377 QJSValue args = parser.call(QJSValue(), QJSValueList() << obj);
378 args.setProperty(QLatin1String(EXPRESSION),QJSValue(expr));
381 args.setProperty(QLatin1String(FRAME),QJSValue(frame));
384 args.setProperty(QLatin1String(GLOBAL),QJSValue(global));
387 args.setProperty(QLatin1String(DISABLEBREAK),QJSValue(disableBreak));
389 if (args.isValid()) {
390 jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
393 QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
394 sendMessage(packMessage(json.toString().toUtf8()));
397 void QJSDebugClient::lookup(QList<int> handles, bool includeSource)
399 // { "seq" : <number>,
400 // "type" : "request",
401 // "command" : "lookup",
402 // "arguments" : { "handles" : <array of handles>,
403 // "includeSource" : <boolean indicating whether the source will be included when script objects are returned>,
407 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(LOOKUP)));
409 QJSValue args = parser.call(QJSValue(), QJSValueList() << obj);
412 QJSValue array = parser.call(QJSValue(), QJSValueList() << arr);
414 foreach (int handle, handles) {
415 array.setProperty(index++,QJSValue(handle));
417 args.setProperty(QLatin1String(HANDLES),array);
420 args.setProperty(QLatin1String(INCLUDESOURCE),QJSValue(includeSource));
422 if (args.isValid()) {
423 jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
426 QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
427 sendMessage(packMessage(json.toString().toUtf8()));
430 void QJSDebugClient::backtrace(int fromFrame, int toFrame, bool bottom)
432 // { "seq" : <number>,
433 // "type" : "request",
434 // "command" : "backtrace",
435 // "arguments" : { "fromFrame" : <number>
436 // "toFrame" : <number>
437 // "bottom" : <boolean, set to true if the bottom of the stack is requested>
441 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(BACKTRACE)));
443 QJSValue args = parser.call(QJSValue(), QJSValueList() << obj);
446 args.setProperty(QLatin1String(FROMFRAME),QJSValue(fromFrame));
449 args.setProperty(QLatin1String(TOFRAME),QJSValue(toFrame));
452 args.setProperty(QLatin1String(BOTTOM),QJSValue(bottom));
454 if (args.isValid()) {
455 jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
458 QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
459 sendMessage(packMessage(json.toString().toUtf8()));
462 void QJSDebugClient::frame(int number)
464 // { "seq" : <number>,
465 // "type" : "request",
466 // "command" : "frame",
467 // "arguments" : { "number" : <frame number>
471 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(FRAME)));
474 QJSValue args = parser.call(QJSValue(), QJSValueList() << obj);
475 args.setProperty(QLatin1String(NUMBER),QJSValue(number));
477 if (args.isValid()) {
478 jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
482 QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
483 sendMessage(packMessage(json.toString().toUtf8()));
486 void QJSDebugClient::scope(int number, int frameNumber)
488 // { "seq" : <number>,
489 // "type" : "request",
490 // "command" : "scope",
491 // "arguments" : { "number" : <scope number>
492 // "frameNumber" : <frame number, optional uses selected frame if missing>
496 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(SCOPE)));
499 QJSValue args = parser.call(QJSValue(), QJSValueList() << obj);
500 args.setProperty(QLatin1String(NUMBER),QJSValue(number));
502 if (frameNumber != -1)
503 args.setProperty(QLatin1String(FRAMENUMBER),QJSValue(frameNumber));
505 if (args.isValid()) {
506 jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
510 QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
511 sendMessage(packMessage(json.toString().toUtf8()));
514 void QJSDebugClient::scopes(int frameNumber)
516 // { "seq" : <number>,
517 // "type" : "request",
518 // "command" : "scopes",
519 // "arguments" : { "frameNumber" : <frame number, optional uses selected frame if missing>
523 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(SCOPES)));
525 if (frameNumber != -1) {
526 QJSValue args = parser.call(QJSValue(), QJSValueList() << obj);
527 args.setProperty(QLatin1String(FRAMENUMBER),QJSValue(frameNumber));
529 if (args.isValid()) {
530 jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
534 QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
535 sendMessage(packMessage(json.toString().toUtf8()));
538 void QJSDebugClient::scripts(int types, QList<int> ids, bool includeSource, QVariant /*filter*/)
540 // { "seq" : <number>,
541 // "type" : "request",
542 // "command" : "scripts",
543 // "arguments" : { "types" : <types of scripts to retrieve
544 // set bit 0 for native scripts
545 // set bit 1 for extension scripts
546 // set bit 2 for normal scripts
547 // (default is 4 for normal scripts)>
548 // "ids" : <array of id's of scripts to return. If this is not specified all scripts are requrned>
549 // "includeSource" : <boolean indicating whether the source code should be included for the scripts returned>
550 // "filter" : <string or number: filter string or script id.
551 // If a number is specified, then only the script with the same number as its script id will be retrieved.
552 // If a string is specified, then only scripts whose names contain the filter string will be retrieved.>
556 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(SCRIPTS)));
558 QJSValue args = parser.call(QJSValue(), QJSValueList() << obj);
559 args.setProperty(QLatin1String(TYPES),QJSValue(types));
563 QJSValue array = parser.call(QJSValue(), QJSValueList() << arr);
565 foreach (int id, ids) {
566 array.setProperty(index++,QJSValue(id));
568 args.setProperty(QLatin1String(IDS),array);
572 args.setProperty(QLatin1String(INCLUDESOURCE),QJSValue(includeSource));
574 if (args.isValid()) {
575 jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
578 QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
579 sendMessage(packMessage(json.toString().toUtf8()));
582 void QJSDebugClient::source(int frame, int fromLine, int toLine)
584 // { "seq" : <number>,
585 // "type" : "request",
586 // "command" : "source",
587 // "arguments" : { "frame" : <frame number (default selected frame)>
588 // "fromLine" : <from line within the source default is line 0>
589 // "toLine" : <to line within the source this line is not included in
590 // the result default is the number of lines in the script>
594 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(SOURCE)));
596 QJSValue args = parser.call(QJSValue(), QJSValueList() << obj);
599 args.setProperty(QLatin1String(FRAME),QJSValue(frame));
602 args.setProperty(QLatin1String(FROMLINE),QJSValue(fromLine));
605 args.setProperty(QLatin1String(TOLINE),QJSValue(toLine));
607 if (args.isValid()) {
608 jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
611 QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
612 sendMessage(packMessage(json.toString().toUtf8()));
615 void QJSDebugClient::setBreakpoint(QString type, QString target, int line, int column, bool enabled, QString condition, int ignoreCount)
617 // { "seq" : <number>,
618 // "type" : "request",
619 // "command" : "setbreakpoint",
620 // "arguments" : { "type" : <"function" or "script" or "scriptId" or "scriptRegExp">
621 // "target" : <function expression or script identification>
622 // "line" : <line in script or function>
623 // "column" : <character position within the line>
624 // "enabled" : <initial enabled state. True or false, default is true>
625 // "condition" : <string with break point condition>
626 // "ignoreCount" : <number specifying the number of break point hits to ignore, default value is 0>
630 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(SETBREAKPOINT)));
632 QJSValue args = parser.call(QJSValue(), QJSValueList() << obj);
634 args.setProperty(QLatin1String(TYPE),QJSValue(type));
635 args.setProperty(QLatin1String(TARGET),QJSValue(target));
638 args.setProperty(QLatin1String(LINE),QJSValue(line));
641 args.setProperty(QLatin1String(COLUMN),QJSValue(column));
643 args.setProperty(QLatin1String(ENABLED),QJSValue(enabled));
645 if (!condition.isEmpty())
646 args.setProperty(QLatin1String(CONDITION),QJSValue(condition));
648 if (ignoreCount != -1)
649 args.setProperty(QLatin1String(IGNORECOUNT),QJSValue(ignoreCount));
651 if (args.isValid()) {
652 jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
655 QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
656 sendMessage(packMessage(json.toString().toUtf8()));
659 void QJSDebugClient::changeBreakpoint(int breakpoint, bool enabled, QString condition, int ignoreCount)
661 // { "seq" : <number>,
662 // "type" : "request",
663 // "command" : "changebreakpoint",
664 // "arguments" : { "breakpoint" : <number of the break point to clear>
665 // "enabled" : <initial enabled state. True or false, default is true>
666 // "condition" : <string with break point condition>
667 // "ignoreCount" : <number specifying the number of break point hits }
670 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(CHANGEBREAKPOINT)));
672 QJSValue args = parser.call(QJSValue(), QJSValueList() << obj);
674 args.setProperty(QLatin1String(BREAKPOINT),QJSValue(breakpoint));
676 args.setProperty(QLatin1String(ENABLED),QJSValue(enabled));
678 if (!condition.isEmpty())
679 args.setProperty(QLatin1String(CONDITION),QJSValue(condition));
681 if (ignoreCount != -1)
682 args.setProperty(QLatin1String(IGNORECOUNT),QJSValue(ignoreCount));
684 if (args.isValid()) {
685 jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
688 QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
689 sendMessage(packMessage(json.toString().toUtf8()));
692 void QJSDebugClient::clearBreakpoint(int breakpoint)
694 // { "seq" : <number>,
695 // "type" : "request",
696 // "command" : "clearbreakpoint",
697 // "arguments" : { "breakpoint" : <number of the break point to clear>
701 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(CLEARBREAKPOINT)));
703 QJSValue args = parser.call(QJSValue(), QJSValueList() << obj);
705 args.setProperty(QLatin1String(BREAKPOINT),QJSValue(breakpoint));
707 if (args.isValid()) {
708 jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
711 QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
712 sendMessage(packMessage(json.toString().toUtf8()));
715 void QJSDebugClient::setExceptionBreak(Exception type, bool enabled)
717 // { "seq" : <number>,
718 // "type" : "request",
719 // "command" : "setexceptionbreak",
720 // "arguments" : { "type" : <string: "all", or "uncaught">,
721 // "enabled" : <optional bool: enables the break type if true>
725 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(SETEXCEPTIONBREAK)));
727 QJSValue args = parser.call(QJSValue(), QJSValueList() << obj);
730 args.setProperty(QLatin1String(TYPE),QJSValue(QLatin1String(ALL)));
731 else if (type == Uncaught)
732 args.setProperty(QLatin1String(TYPE),QJSValue(QLatin1String(UNCAUGHT)));
735 args.setProperty(QLatin1String(ENABLED),QJSValue(enabled));
737 if (args.isValid()) {
738 jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
741 QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
742 sendMessage(packMessage(json.toString().toUtf8()));
745 void QJSDebugClient::v8flags(QString flags)
747 // { "seq" : <number>,
748 // "type" : "request",
749 // "command" : "v8flags",
750 // "arguments" : { "flags" : <string: a sequence of v8 flags just like those used on the command line>
754 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(V8FLAGS)));
756 QJSValue args = parser.call(QJSValue(), QJSValueList() << obj);
758 args.setProperty(QLatin1String(FLAGS),QJSValue(flags));
760 if (args.isValid()) {
761 jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
764 QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
765 sendMessage(packMessage(json.toString().toUtf8()));
768 void QJSDebugClient::version()
770 // { "seq" : <number>,
771 // "type" : "request",
772 // "command" : "version",
775 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(VERSION)));
777 QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
778 sendMessage(packMessage(json.toString().toUtf8()));
781 //void QJSDebugClient::profile(ProfileCommand command)
783 //// { "seq" : <number>,
784 //// "type" : "request",
785 //// "command" : "profile",
786 //// "arguments" : { "command" : "resume" or "pause" }
789 // jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(PROFILE)));
791 // QJSValue args = parser.call(QJSValue(), QJSValueList() << obj);
793 // if (command == Resume)
794 // args.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(RESUME)));
796 // args.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(PAUSE)));
798 // args.setProperty(QLatin1String("modules"),QJSValue(1));
799 // if (args.isValid()) {
800 // jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
803 // QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
804 // sendMessage(packMessage(json.toString().toUtf8()));
807 void QJSDebugClient::disconnect()
809 // { "seq" : <number>,
810 // "type" : "request",
811 // "command" : "disconnect",
814 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(DISCONNECT)));
816 QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
817 sendMessage(packMessage(json.toString().toUtf8()));
820 void QJSDebugClient::gc()
822 // { "seq" : <number>,
823 // "type" : "request",
825 // "arguments" : { "type" : <string: "all">,
829 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(GARBAGECOLLECTOR)));
831 QJSValue args = parser.call(QJSValue(), QJSValueList() << obj);
833 args.setProperty(QLatin1String(TYPE),QJSValue(QLatin1String(ALL)));
835 if (args.isValid()) {
836 jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
839 QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
840 sendMessage(packMessage(json.toString().toUtf8()));
843 void QJSDebugClient::listBreakpoints()
845 // { "seq" : <number>,
846 // "type" : "request",
847 // "command" : "listbreakpoints",
850 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(LISTBREAKPOINTS)));
852 QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
853 sendMessage(packMessage(json.toString().toUtf8()));
856 void QJSDebugClient::statusChanged(Status status)
858 if (status == Enabled) {
864 void QJSDebugClient::messageReceived(const QByteArray &data)
866 QDataStream ds(data);
870 if (command == "V8DEBUG") {
872 QString jsonString(response);
873 QVariantMap value = parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
874 QString type = value.value("type").toString();
876 if (type == "response") {
878 if (!value.value("success").toBool()) {
879 // qDebug() << "Error: The test case will fail since no signal is emitted";
883 QString debugCommand(value.value("command").toString());
884 if (debugCommand == "backtrace" ||
885 debugCommand == "lookup" ||
886 debugCommand == "setbreakpoint" ||
887 debugCommand == "evaluate" ||
888 debugCommand == "listbreakpoints" ||
889 debugCommand == "version" ||
890 debugCommand == "v8flags" ||
891 debugCommand == "disconnect" ||
892 debugCommand == "gc" ||
893 debugCommand == "changebreakpoint" ||
894 debugCommand == "clearbreakpoint" ||
895 debugCommand == "frame" ||
896 debugCommand == "scope" ||
897 debugCommand == "scopes" ||
898 debugCommand == "scripts" ||
899 debugCommand == "source" ||
900 debugCommand == "setexceptionbreak" /*||
901 debugCommand == "profile"*/) {
908 } else if (type == "event") {
909 QString event(value.value("event").toString());
911 if (event == "break" ||
912 event == "exception") {
919 void QJSDebugClient::sendMessage(const QByteArray &msg)
921 if (status() == Enabled) {
922 QDeclarativeDebugClient::sendMessage(msg);
924 sendBuffer.append(msg);
928 void QJSDebugClient::flushSendBuffer()
930 foreach (const QByteArray &msg, sendBuffer)
931 QDeclarativeDebugClient::sendMessage(msg);
935 QByteArray QJSDebugClient::packMessage(QByteArray message)
938 QDataStream rs(&reply, QIODevice::WriteOnly);
939 QByteArray cmd = "V8DEBUG";
940 rs << cmd << message;
944 void tst_QDeclarativeDebugJS::initTestCase()
951 void tst_QDeclarativeDebugJS::cleanupTestCase()
965 void tst_QDeclarativeDebugJS::init()
967 connection = new QDeclarativeDebugConnection();
968 process = new QDeclarativeDebugProcess(QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene");
969 client = new QJSDebugClient(connection);
971 process->start(QStringList() << QLatin1String(BLOCKMODE) << TESTDATA(QLatin1String(QMLFILE)));
972 if (!process->waitForSessionStart()) {
973 QFAIL(QString("Could not launch app. Application output: \n%1").arg(process->output()).toAscii());
976 connection->connectToHost("127.0.0.1", 3771);
977 QVERIFY(connection->waitForConnected());
979 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(enabled())));
982 void tst_QDeclarativeDebugJS::cleanup()
1000 void tst_QDeclarativeDebugJS::getVersion()
1004 client->interrupt();
1005 client->startDebugging();
1006 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1009 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1012 void tst_QDeclarativeDebugJS::applyV8Flags()
1014 //void v8flags(QString flags)
1016 client->interrupt();
1017 client->startDebugging();
1018 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1020 client->v8flags(QString());
1021 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1024 void tst_QDeclarativeDebugJS::disconnect()
1028 client->interrupt();
1029 client->startDebugging();
1030 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1032 client->disconnect();
1033 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1036 void tst_QDeclarativeDebugJS::gc()
1040 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(JSFILE), 2, -1, true);
1041 client->startDebugging();
1042 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1045 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1048 void tst_QDeclarativeDebugJS::listBreakpoints()
1050 //void listBreakpoints()
1052 int sourceLine1 = 57;
1053 int sourceLine2 = 60;
1054 int sourceLine3 = 67;
1056 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(QMLFILE), sourceLine1, -1, true);
1057 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(QMLFILE), sourceLine2, -1, true);
1058 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(JSFILE), sourceLine3, -1, true);
1059 client->startDebugging();
1060 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1062 client->listBreakpoints();
1063 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1065 QString jsonString(client->response);
1066 QVariantMap value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1068 QList<QVariant> breakpoints = value.value("body").toMap().value("breakpoints").toList();
1070 QCOMPARE(breakpoints.count(), 3);
1073 void tst_QDeclarativeDebugJS::setBreakpointInScriptOnCompleted()
1075 //void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1)
1077 int sourceLine = 49;
1079 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(QMLFILE), sourceLine, -1, true);
1080 client->startDebugging();
1081 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1083 QString jsonString(client->response);
1084 QVariantMap value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1086 QVariantMap body = value.value("body").toMap();
1088 QCOMPARE(body.value("sourceLine").toInt(), sourceLine);
1089 QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(QMLFILE));
1092 void tst_QDeclarativeDebugJS::setBreakpointInScriptOnTimerCallback()
1094 int sourceLine = 49;
1095 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(QMLFILE), sourceLine, -1, true);
1096 //void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1)
1098 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(QMLFILE), sourceLine, -1, true);
1099 client->startDebugging();
1100 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1102 client->evaluate("timer.running = true");
1103 client->continueDebugging(QJSDebugClient::Continue);
1105 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1107 QString jsonString(client->response);
1108 QVariantMap value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1110 QVariantMap body = value.value("body").toMap();
1112 QCOMPARE(body.value("sourceLine").toInt(), sourceLine);
1113 QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(QMLFILE));
1116 void tst_QDeclarativeDebugJS::setBreakpointInScriptInDifferentFile()
1118 //void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1)
1120 int sourceLine = 43;
1122 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(JSFILE), sourceLine, -1, true);
1123 client->startDebugging();
1124 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1126 QString jsonString(client->response);
1127 QVariantMap value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1129 QVariantMap body = value.value("body").toMap();
1131 QCOMPARE(body.value("sourceLine").toInt(), sourceLine);
1132 QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(JSFILE));
1135 void tst_QDeclarativeDebugJS::setBreakpointInScriptOnComment()
1137 //void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1)
1139 int sourceLine = 48;
1140 int actualLine = 50;
1142 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(JSFILE), sourceLine, -1, true);
1143 client->startDebugging();
1144 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1146 QString jsonString(client->response);
1147 QVariantMap value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1149 QVariantMap body = value.value("body").toMap();
1151 QCOMPARE(body.value("sourceLine").toInt(), actualLine);
1152 QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(JSFILE));
1155 void tst_QDeclarativeDebugJS::setBreakpointInScriptOnEmptyLine()
1157 //void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1)
1159 int sourceLine = 49;
1160 int actualLine = 50;
1162 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(JSFILE), sourceLine, -1, true);
1163 client->startDebugging();
1164 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1166 QString jsonString(client->response);
1167 QVariantMap value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1169 QVariantMap body = value.value("body").toMap();
1171 QCOMPARE(body.value("sourceLine").toInt(), actualLine);
1172 QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(JSFILE));
1175 void tst_QDeclarativeDebugJS::setBreakpointInScriptWithCondition()
1177 //void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1)
1180 int sourceLine = 51;
1182 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(JSFILE), sourceLine, -1, true, QLatin1String("out > 10"));
1183 client->startDebugging();
1184 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1186 //Get the frame index
1187 QString jsonString = client->response;
1188 QVariantMap value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1190 QVariantMap body = value.value("body").toMap();
1192 int frameIndex = body.value("index").toInt();
1194 //Verify the value of 'result'
1195 client->evaluate(QLatin1String("out"),frameIndex);
1197 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1199 jsonString = client->response;
1200 value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1202 body = value.value("body").toMap();
1204 QVERIFY(body.value("value").toInt() > out);
1207 //void tst_QDeclarativeDebugJS::setBreakpointInFunction()
1209 // //void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1)
1211 // int actualLine = 31;
1213 // client->startDebugging();
1214 // client->setBreakpoint(QLatin1String(FUNCTION), QLatin1String("doSomethingElse"), -1, -1, true);
1216 // QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1218 // QString jsonString(client->response);
1219 // QVariantMap value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1221 // QVariantMap body = value.value("body").toMap();
1223 // QCOMPARE(body.value("sourceLine").toInt(), actualLine);
1224 // QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(QMLFILE));
1227 void tst_QDeclarativeDebugJS::changeBreakpoint()
1229 //void changeBreakpoint(int breakpoint, bool enabled = false, QString condition = QString(), int ignoreCount = -1)
1231 int sourceLine1 = 77;
1232 int sourceLine2 = 78;
1234 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(QMLFILE), sourceLine1, -1, true);
1235 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(QMLFILE), sourceLine2, -1, true);
1236 client->startDebugging();
1237 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1239 //Will hit 1st brakpoint, change this breakpoint enable = false
1240 QString jsonString(client->response);
1241 QVariantMap value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1243 QVariantMap body = value.value("body").toMap();
1244 QList<QVariant> breakpointsHit = body.value("breakpoints").toList();
1246 int breakpoint = breakpointsHit.at(0).toInt();
1247 client->changeBreakpoint(breakpoint,false);
1249 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1251 //Continue with debugging
1252 client->continueDebugging(QJSDebugClient::Continue);
1253 //Hit 2nd breakpoint
1254 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1257 client->evaluate("timer.running = true");
1259 //Continue with debugging
1260 client->continueDebugging(QJSDebugClient::Continue);
1261 //Should stop at 2nd breakpoint
1262 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1264 jsonString = client->response;
1265 value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1267 body = value.value("body").toMap();
1269 QCOMPARE(body.value("sourceLine").toInt(), sourceLine2);
1272 void tst_QDeclarativeDebugJS::changeBreakpointOnCondition()
1274 //void changeBreakpoint(int breakpoint, bool enabled = false, QString condition = QString(), int ignoreCount = -1)
1276 int sourceLine1 = 56;
1277 int sourceLine2 = 60;
1280 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(QMLFILE), sourceLine1, -1, true);
1281 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(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,QLatin1String("a = 0"));
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())));
1302 client->evaluate("timer.running = true");
1303 //Continue with debugging
1304 client->continueDebugging(QJSDebugClient::Continue);
1305 //Should stop at 2nd breakpoint
1306 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1308 jsonString = client->response;
1309 value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1311 body = value.value("body").toMap();
1313 QCOMPARE(body.value("sourceLine").toInt(), sourceLine2);
1316 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1318 //Get the frame index
1319 jsonString = client->response;
1320 value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1322 body = value.value("body").toMap();
1324 int frameIndex = body.value("index").toInt();
1326 //Verify the value of 'result'
1327 client->evaluate(QLatin1String("root.result"),frameIndex);
1329 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1331 jsonString = client->response;
1332 value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1334 body = value.value("body").toMap();
1336 QVERIFY(body.value("value").toInt() > result);
1339 void tst_QDeclarativeDebugJS::clearBreakpoint()
1341 //void clearBreakpoint(int breakpoint);
1343 int sourceLine1 = 77;
1344 int sourceLine2 = 78;
1346 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(QMLFILE), sourceLine1, -1, true);
1347 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(QMLFILE), sourceLine2, -1, true);
1348 client->startDebugging();
1349 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1351 //Will hit 1st brakpoint, change this breakpoint enable = false
1352 QString jsonString(client->response);
1353 QVariantMap value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1355 QVariantMap body = value.value("body").toMap();
1356 QList<QVariant> breakpointsHit = body.value("breakpoints").toList();
1358 int breakpoint = breakpointsHit.at(0).toInt();
1359 client->changeBreakpoint(breakpoint,false,QLatin1String("result > 5"));
1361 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1363 //Continue with debugging
1364 client->continueDebugging(QJSDebugClient::Continue);
1365 //Hit 2nd breakpoint
1366 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1368 client->evaluate("timer.running = true");
1369 //Continue with debugging
1370 client->continueDebugging(QJSDebugClient::Continue);
1371 //Should stop at 2nd breakpoint
1372 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1374 jsonString = client->response;
1375 value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1377 body = value.value("body").toMap();
1379 QCOMPARE(body.value("sourceLine").toInt(), sourceLine2);
1382 void tst_QDeclarativeDebugJS::setExceptionBreak()
1384 //void setExceptionBreak(QString type, bool enabled = false);
1386 int sourceLine = 49;
1387 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(QMLFILE), sourceLine, -1, true);
1388 client->setExceptionBreak(QJSDebugClient::All,true);
1389 client->startDebugging();
1390 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1391 client->evaluate("root.raiseException = true");
1392 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1393 client->continueDebugging(QJSDebugClient::Continue);
1394 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped()), 10000));
1397 void tst_QDeclarativeDebugJS::stepNext()
1399 //void continueDebugging(StepAction stepAction, int stepCount = 1);
1401 int sourceLine = 57;
1403 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(QMLFILE), sourceLine, -1, true);
1404 client->startDebugging();
1405 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1407 client->continueDebugging(QJSDebugClient::Next);
1408 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped()), 10000));
1410 QString jsonString(client->response);
1411 QVariantMap value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1413 QVariantMap body = value.value("body").toMap();
1415 QCOMPARE(body.value("sourceLine").toInt(), sourceLine + 1);
1416 QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(QMLFILE));
1419 void tst_QDeclarativeDebugJS::stepNextWithCount()
1421 //void continueDebugging(StepAction stepAction, int stepCount = 1);
1423 int sourceLine = 59;
1425 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(QMLFILE), sourceLine, -1, true);
1426 client->startDebugging();
1427 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1429 client->continueDebugging(QJSDebugClient::Next,2);
1430 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped()), 10000));
1432 QString jsonString(client->response);
1433 QVariantMap value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1435 QVariantMap body = value.value("body").toMap();
1437 QCOMPARE(body.value("sourceLine").toInt(), sourceLine + 2);
1438 QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(QMLFILE));
1441 void tst_QDeclarativeDebugJS::stepIn()
1443 //void continueDebugging(StepAction stepAction, int stepCount = 1);
1445 int sourceLine = 61;
1446 int actualLine = 78;
1448 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(QMLFILE), sourceLine, -1, true);
1449 client->startDebugging();
1450 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1452 client->continueDebugging(QJSDebugClient::In);
1453 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped()), 10000));
1455 QString jsonString(client->response);
1456 QVariantMap value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1458 QVariantMap body = value.value("body").toMap();
1460 QCOMPARE(body.value("sourceLine").toInt(), actualLine);
1461 QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(QMLFILE));
1464 void tst_QDeclarativeDebugJS::stepOut()
1466 //void continueDebugging(StepAction stepAction, int stepCount = 1);
1468 int sourceLine = 56;
1469 int actualLine = 49;
1471 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(QMLFILE), sourceLine, -1, true);
1472 client->startDebugging();
1473 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1475 client->continueDebugging(QJSDebugClient::Out);
1476 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped()), 10000));
1478 QString jsonString(client->response);
1479 QVariantMap value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1481 QVariantMap body = value.value("body").toMap();
1483 QCOMPARE(body.value("sourceLine").toInt(), actualLine);
1484 QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(QMLFILE));
1487 void tst_QDeclarativeDebugJS::continueDebugging()
1489 //void continueDebugging(StepAction stepAction, int stepCount = 1);
1491 int sourceLine1 = 56;
1492 int sourceLine2 = 60;
1494 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(QMLFILE), sourceLine1, -1, true);
1495 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(QMLFILE), sourceLine2, -1, true);
1496 client->startDebugging();
1497 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1499 client->continueDebugging(QJSDebugClient::Continue);
1500 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped()), 10000));
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(), sourceLine2);
1508 QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(QMLFILE));
1511 void tst_QDeclarativeDebugJS::backtrace()
1513 //void backtrace(int fromFrame = -1, int toFrame = -1, bool bottom = false);
1515 int sourceLine = 60;
1516 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(QMLFILE), sourceLine, -1, true);
1517 client->startDebugging();
1518 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1520 client->backtrace();
1521 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1524 void tst_QDeclarativeDebugJS::getFrameDetails()
1526 //void frame(int number = -1);
1528 int sourceLine = 60;
1529 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(QMLFILE), sourceLine, -1, true);
1530 client->startDebugging();
1531 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1534 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1537 void tst_QDeclarativeDebugJS::getScopeDetails()
1539 //void scope(int number = -1, int frameNumber = -1);
1541 int sourceLine = 60;
1542 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(QMLFILE), sourceLine, -1, true);
1543 client->startDebugging();
1544 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1547 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1550 void tst_QDeclarativeDebugJS::evaluateInGlobalScope()
1552 //void evaluate(QString expr, bool global = false, bool disableBreak = false, int frame = -1, const QVariantMap &addContext = QVariantMap());
1554 int sourceLine = 49;
1555 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(QMLFILE), sourceLine, -1, true);
1556 client->startDebugging();
1557 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1559 client->evaluate(QLatin1String("print('Hello World')"),true);
1560 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1562 //Verify the value of 'print'
1563 QString jsonString(client->response);
1564 QVariantMap value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1566 QVariantMap body = value.value("body").toMap();
1568 QCOMPARE(body.value("text").toString(),QLatin1String("undefined"));
1571 void tst_QDeclarativeDebugJS::evaluateInLocalScope()
1573 //void evaluate(QString expr, bool global = false, bool disableBreak = false, int frame = -1, const QVariantMap &addContext = QVariantMap());
1575 int sourceLine = 60;
1576 client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(QMLFILE), sourceLine, -1, true);
1577 client->startDebugging();
1578 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1581 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1583 //Get the frame index
1584 QString jsonString(client->response);
1585 QVariantMap value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1587 QVariantMap body = value.value("body").toMap();
1589 int frameIndex = body.value("index").toInt();
1591 client->evaluate(QLatin1String("root.someValue"),frameIndex);
1592 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1594 //Verify the value of 'root.someValue'
1595 jsonString = client->response;
1596 value = client->parser.call(QJSValue(), QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1598 body = value.value("body").toMap();
1600 QCOMPARE(body.value("value").toInt(),10);
1603 void tst_QDeclarativeDebugJS::getScopes()
1605 //void scopes(int frameNumber = -1);
1607 client->interrupt();
1608 client->startDebugging();
1609 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1612 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1615 void tst_QDeclarativeDebugJS::getScripts()
1617 //void scripts(int types = -1, QList<int> ids = QList<int>(), bool includeSource = false, QVariant filter = QVariant());
1619 client->interrupt();
1620 client->startDebugging();
1621 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1624 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1627 void tst_QDeclarativeDebugJS::getSource()
1629 //void source(int frame = -1, int fromLine = -1, int toLine = -1);
1631 client->interrupt();
1632 client->startDebugging();
1633 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1636 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1639 QTEST_MAIN(tst_QDeclarativeDebugJS)
1641 #include "tst_qdeclarativedebugjs.moc"