1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the test suite of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** 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";
110 const char *BREAKAFTERCOMPILE = "breakaftercompile";
112 const char *REQUEST = "request";
113 const char *IN = "in";
114 const char *NEXT = "next";
115 const char *OUT = "out";
117 const char *FUNCTION = "function";
118 const char *SCRIPT = "script";
119 const char *SCRIPTREGEXP = "scriptRegExp";
120 const char *EVENT = "event";
122 const char *ALL = "all";
123 const char *UNCAUGHT = "uncaught";
125 //const char *PAUSE = "pause";
126 //const char *RESUME = "resume";
128 const char *BLOCKMODE = "-qmljsdebugger=port:3771,block";
129 const char *NORMALMODE = "-qmljsdebugger=port:3771";
130 const char *TEST_QMLFILE = "test.qml";
131 const char *TEST_JSFILE = "test.js";
132 const char *TIMER_QMLFILE = "timer.qml";
133 const char *LOADJSFILE_QMLFILE = "loadjsfile.qml";
134 const char *EXCEPTION_QMLFILE = "exception.qml";
135 const char *ONCOMPLETED_QMLFILE = "oncompleted.qml";
136 const char *CREATECOMPONENT_QMLFILE = "createComponent.qml";
137 const char *CONDITION_QMLFILE = "condition.qml";
138 const char *CHANGEBREAKPOINT_QMLFILE = "changeBreakpoint.qml";
139 const char *STEPACTION_QMLFILE = "stepAction.qml";
140 const char *BREAKPOINTRELOCATION_QMLFILE = "breakpointRelocation.qml";
142 #define VARIANTMAPINIT \
144 QJSValue jsonVal = parser.call(QJSValueList() << obj); \
145 jsonVal.setProperty(SEQ,QJSValue(seq++)); \
146 jsonVal.setProperty(TYPE,REQUEST);
150 #define QVERIFY(statement) \
152 if (!QTest::qVerify((statement), #statement, "", __FILE__, __LINE__)) {\
153 if (QTest::currentTestFailed()) \
154 qDebug().nospace() << "\nDEBUGGEE OUTPUT:\n" << process->output();\
160 class QJSDebugClient;
162 class tst_QDeclarativeDebugJS : public QDeclarativeDataTest
166 bool init(const QString &qmlFile = QString(TEST_QMLFILE), bool blockMode = true);
170 void cleanupTestCase();
176 void breakAfterCompile();
178 void getVersionWhenAttaching();
186 void listBreakpoints();
188 void setBreakpointInScriptOnCompleted();
189 void setBreakpointInScriptOnComponentCreated();
190 void setBreakpointInScriptOnTimerCallback();
191 void setBreakpointInScriptInDifferentFile();
192 void setBreakpointInScriptOnComment();
193 void setBreakpointInScriptOnEmptyLine();
194 void setBreakpointInScriptWithCondition();
195 //void setBreakpointInFunction(); //NOT SUPPORTED
196 void setBreakpointOnEvent();
197 void setBreakpointWhenAttaching();
199 void changeBreakpoint();
200 void changeBreakpointOnCondition();
202 void clearBreakpoint();
204 void setExceptionBreak();
207 void stepNextWithCount();
210 void continueDebugging();
214 void getFrameDetails();
216 void getScopeDetails();
218 void evaluateInGlobalScope();
219 void evaluateInLocalScope();
227 // void profile(); //NOT SUPPORTED
229 // void verifyQMLOptimizerDisabled();
232 QDeclarativeDebugProcess *process;
233 QJSDebugClient *client;
234 QDeclarativeDebugConnection *connection;
238 class QJSDebugClient : public QDeclarativeDebugClient
256 // enum ProfileCommand
262 QJSDebugClient(QDeclarativeDebugConnection *connection)
263 : QDeclarativeDebugClient(QLatin1String("V8Debugger"), connection),
266 parser = jsEngine.evaluate(QLatin1String("JSON.parse"));
267 stringify = jsEngine.evaluate(QLatin1String("JSON.stringify"));
272 void breakAfterCompile(bool enabled);
274 void continueDebugging(StepAction stepAction, int stepCount = 1);
275 void evaluate(QString expr, bool global = false, bool disableBreak = false, int frame = -1, const QVariantMap &addContext = QVariantMap());
276 void lookup(QList<int> handles, bool includeSource = false);
277 void backtrace(int fromFrame = -1, int toFrame = -1, bool bottom = false);
278 void frame(int number = -1);
279 void scope(int number = -1, int frameNumber = -1);
280 void scopes(int frameNumber = -1);
281 void scripts(int types = 4, QList<int> ids = QList<int>(), bool includeSource = false, QVariant filter = QVariant());
282 void source(int frame = -1, int fromLine = -1, int toLine = -1);
283 void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = true, QString condition = QString(), int ignoreCount = -1);
284 void changeBreakpoint(int breakpoint, bool enabled = true, QString condition = QString(), int ignoreCount = -1);
285 void clearBreakpoint(int breakpoint);
286 void setExceptionBreak(Exception type, bool enabled = false);
287 void v8flags(QString flags);
289 //void profile(ProfileCommand command); //NOT SUPPORTED
292 void listBreakpoints();
295 //inherited from QDeclarativeDebugClient
296 void stateChanged(State state);
297 void messageReceived(const QByteArray &data);
302 void interruptRequested();
303 void breakAfterCompileRequested();
308 void sendMessage(const QByteArray &);
309 void flushSendBuffer();
310 QByteArray packMessage(const QByteArray &type, const QByteArray &message = QByteArray());
316 QList<QByteArray> sendBuffer;
324 void QJSDebugClient::connect()
326 sendMessage(packMessage(CONNECT));
329 void QJSDebugClient::interrupt()
331 sendMessage(packMessage(INTERRUPT));
334 void QJSDebugClient::breakAfterCompile(bool enabled)
337 QDataStream rs(&request, QIODevice::WriteOnly);
339 sendMessage(packMessage(BREAKAFTERCOMPILE, request));
342 void QJSDebugClient::continueDebugging(StepAction action, int count)
344 // { "seq" : <number>,
345 // "type" : "request",
346 // "command" : "continue",
347 // "arguments" : { "stepaction" : <"in", "next" or "out">,
348 // "stepcount" : <number of steps (default 1)>
352 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(CONTINEDEBUGGING)));
354 if (action != Continue) {
355 QJSValue args = parser.call(QJSValueList() << obj);
357 case In: args.setProperty(QLatin1String(STEPACTION),QJSValue(QLatin1String(IN)));
359 case Out: args.setProperty(QLatin1String(STEPACTION),QJSValue(QLatin1String(OUT)));
361 case Next: args.setProperty(QLatin1String(STEPACTION),QJSValue(QLatin1String(NEXT)));
365 if (!args.isUndefined()) {
367 args.setProperty(QLatin1String(STEPCOUNT),QJSValue(count));
368 jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
371 QJSValue json = stringify.call(QJSValueList() << jsonVal);
372 sendMessage(packMessage(V8REQUEST, json.toString().toUtf8()));
375 void QJSDebugClient::evaluate(QString expr, bool global, bool disableBreak, int frame, const QVariantMap &/*addContext*/)
377 // { "seq" : <number>,
378 // "type" : "request",
379 // "command" : "evaluate",
380 // "arguments" : { "expression" : <expression to evaluate>,
381 // "frame" : <number>,
382 // "global" : <boolean>,
383 // "disable_break" : <boolean>,
384 // "additional_context" : [
385 // { "name" : <name1>, "handle" : <handle1> },
386 // { "name" : <name2>, "handle" : <handle2> },
392 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(EVALUATE)));
394 QJSValue args = parser.call(QJSValueList() << obj);
395 args.setProperty(QLatin1String(EXPRESSION),QJSValue(expr));
398 args.setProperty(QLatin1String(FRAME),QJSValue(frame));
401 args.setProperty(QLatin1String(GLOBAL),QJSValue(global));
404 args.setProperty(QLatin1String(DISABLEBREAK),QJSValue(disableBreak));
406 if (!args.isUndefined()) {
407 jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
410 QJSValue json = stringify.call(QJSValueList() << jsonVal);
411 sendMessage(packMessage(V8REQUEST, json.toString().toUtf8()));
414 void QJSDebugClient::lookup(QList<int> handles, bool includeSource)
416 // { "seq" : <number>,
417 // "type" : "request",
418 // "command" : "lookup",
419 // "arguments" : { "handles" : <array of handles>,
420 // "includeSource" : <boolean indicating whether the source will be included when script objects are returned>,
424 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(LOOKUP)));
426 QJSValue args = parser.call(QJSValueList() << obj);
429 QJSValue array = parser.call(QJSValueList() << arr);
431 foreach (int handle, handles) {
432 array.setProperty(index++,QJSValue(handle));
434 args.setProperty(QLatin1String(HANDLES),array);
437 args.setProperty(QLatin1String(INCLUDESOURCE),QJSValue(includeSource));
439 if (!args.isUndefined()) {
440 jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
443 QJSValue json = stringify.call(QJSValueList() << jsonVal);
444 sendMessage(packMessage(V8REQUEST, json.toString().toUtf8()));
447 void QJSDebugClient::backtrace(int fromFrame, int toFrame, bool bottom)
449 // { "seq" : <number>,
450 // "type" : "request",
451 // "command" : "backtrace",
452 // "arguments" : { "fromFrame" : <number>
453 // "toFrame" : <number>
454 // "bottom" : <boolean, set to true if the bottom of the stack is requested>
458 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(BACKTRACE)));
460 QJSValue args = parser.call(QJSValueList() << obj);
463 args.setProperty(QLatin1String(FROMFRAME),QJSValue(fromFrame));
466 args.setProperty(QLatin1String(TOFRAME),QJSValue(toFrame));
469 args.setProperty(QLatin1String(BOTTOM),QJSValue(bottom));
471 if (!args.isUndefined()) {
472 jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
475 QJSValue json = stringify.call(QJSValueList() << jsonVal);
476 sendMessage(packMessage(V8REQUEST, json.toString().toUtf8()));
479 void QJSDebugClient::frame(int number)
481 // { "seq" : <number>,
482 // "type" : "request",
483 // "command" : "frame",
484 // "arguments" : { "number" : <frame number>
488 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(FRAME)));
491 QJSValue args = parser.call(QJSValueList() << obj);
492 args.setProperty(QLatin1String(NUMBER),QJSValue(number));
494 if (!args.isUndefined()) {
495 jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
499 QJSValue json = stringify.call(QJSValueList() << jsonVal);
500 sendMessage(packMessage(V8REQUEST, json.toString().toUtf8()));
503 void QJSDebugClient::scope(int number, int frameNumber)
505 // { "seq" : <number>,
506 // "type" : "request",
507 // "command" : "scope",
508 // "arguments" : { "number" : <scope number>
509 // "frameNumber" : <frame number, optional uses selected frame if missing>
513 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(SCOPE)));
516 QJSValue args = parser.call(QJSValueList() << obj);
517 args.setProperty(QLatin1String(NUMBER),QJSValue(number));
519 if (frameNumber != -1)
520 args.setProperty(QLatin1String(FRAMENUMBER),QJSValue(frameNumber));
522 if (!args.isUndefined()) {
523 jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
527 QJSValue json = stringify.call(QJSValueList() << jsonVal);
528 sendMessage(packMessage(V8REQUEST, json.toString().toUtf8()));
531 void QJSDebugClient::scopes(int frameNumber)
533 // { "seq" : <number>,
534 // "type" : "request",
535 // "command" : "scopes",
536 // "arguments" : { "frameNumber" : <frame number, optional uses selected frame if missing>
540 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(SCOPES)));
542 if (frameNumber != -1) {
543 QJSValue args = parser.call(QJSValueList() << obj);
544 args.setProperty(QLatin1String(FRAMENUMBER),QJSValue(frameNumber));
546 if (!args.isUndefined()) {
547 jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
551 QJSValue json = stringify.call(QJSValueList() << jsonVal);
552 sendMessage(packMessage(V8REQUEST, json.toString().toUtf8()));
555 void QJSDebugClient::scripts(int types, QList<int> ids, bool includeSource, QVariant /*filter*/)
557 // { "seq" : <number>,
558 // "type" : "request",
559 // "command" : "scripts",
560 // "arguments" : { "types" : <types of scripts to retrieve
561 // set bit 0 for native scripts
562 // set bit 1 for extension scripts
563 // set bit 2 for normal scripts
564 // (default is 4 for normal scripts)>
565 // "ids" : <array of id's of scripts to return. If this is not specified all scripts are requrned>
566 // "includeSource" : <boolean indicating whether the source code should be included for the scripts returned>
567 // "filter" : <string or number: filter string or script id.
568 // If a number is specified, then only the script with the same number as its script id will be retrieved.
569 // If a string is specified, then only scripts whose names contain the filter string will be retrieved.>
573 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(SCRIPTS)));
575 QJSValue args = parser.call(QJSValueList() << obj);
576 args.setProperty(QLatin1String(TYPES),QJSValue(types));
580 QJSValue array = parser.call(QJSValueList() << arr);
582 foreach (int id, ids) {
583 array.setProperty(index++,QJSValue(id));
585 args.setProperty(QLatin1String(IDS),array);
589 args.setProperty(QLatin1String(INCLUDESOURCE),QJSValue(includeSource));
591 if (!args.isUndefined()) {
592 jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
595 QJSValue json = stringify.call(QJSValueList() << jsonVal);
596 sendMessage(packMessage(V8REQUEST, json.toString().toUtf8()));
599 void QJSDebugClient::source(int frame, int fromLine, int toLine)
601 // { "seq" : <number>,
602 // "type" : "request",
603 // "command" : "source",
604 // "arguments" : { "frame" : <frame number (default selected frame)>
605 // "fromLine" : <from line within the source default is line 0>
606 // "toLine" : <to line within the source this line is not included in
607 // the result default is the number of lines in the script>
611 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(SOURCE)));
613 QJSValue args = parser.call(QJSValueList() << obj);
616 args.setProperty(QLatin1String(FRAME),QJSValue(frame));
619 args.setProperty(QLatin1String(FROMLINE),QJSValue(fromLine));
622 args.setProperty(QLatin1String(TOLINE),QJSValue(toLine));
624 if (!args.isUndefined()) {
625 jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
628 QJSValue json = stringify.call(QJSValueList() << jsonVal);
629 sendMessage(packMessage(V8REQUEST, json.toString().toUtf8()));
632 void QJSDebugClient::setBreakpoint(QString type, QString target, int line, int column, bool enabled, QString condition, int ignoreCount)
634 // { "seq" : <number>,
635 // "type" : "request",
636 // "command" : "setbreakpoint",
637 // "arguments" : { "type" : <"function" or "script" or "scriptId" or "scriptRegExp">
638 // "target" : <function expression or script identification>
639 // "line" : <line in script or function>
640 // "column" : <character position within the line>
641 // "enabled" : <initial enabled state. True or false, default is true>
642 // "condition" : <string with break point condition>
643 // "ignoreCount" : <number specifying the number of break point hits to ignore, default value is 0>
647 if (type == QLatin1String(EVENT)) {
649 QDataStream rs(&reply, QIODevice::WriteOnly);
650 rs << target.toUtf8() << enabled;
651 sendMessage(packMessage(QByteArray("breakonsignal"), reply));
655 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(SETBREAKPOINT)));
657 QJSValue args = parser.call(QJSValueList() << obj);
659 args.setProperty(QLatin1String(TYPE),QJSValue(type));
660 args.setProperty(QLatin1String(TARGET),QJSValue(target));
663 args.setProperty(QLatin1String(LINE),QJSValue(line));
666 args.setProperty(QLatin1String(COLUMN),QJSValue(column));
668 args.setProperty(QLatin1String(ENABLED),QJSValue(enabled));
670 if (!condition.isEmpty())
671 args.setProperty(QLatin1String(CONDITION),QJSValue(condition));
673 if (ignoreCount != -1)
674 args.setProperty(QLatin1String(IGNORECOUNT),QJSValue(ignoreCount));
676 if (!args.isUndefined()) {
677 jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
680 QJSValue json = stringify.call(QJSValueList() << jsonVal);
681 sendMessage(packMessage(V8REQUEST, json.toString().toUtf8()));
685 void QJSDebugClient::changeBreakpoint(int breakpoint, bool enabled, QString condition, int ignoreCount)
687 // { "seq" : <number>,
688 // "type" : "request",
689 // "command" : "changebreakpoint",
690 // "arguments" : { "breakpoint" : <number of the break point to clear>
691 // "enabled" : <initial enabled state. True or false, default is true>
692 // "condition" : <string with break point condition>
693 // "ignoreCount" : <number specifying the number of break point hits }
696 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(CHANGEBREAKPOINT)));
698 QJSValue args = parser.call(QJSValueList() << obj);
700 args.setProperty(QLatin1String(BREAKPOINT),QJSValue(breakpoint));
702 args.setProperty(QLatin1String(ENABLED),QJSValue(enabled));
704 if (!condition.isEmpty())
705 args.setProperty(QLatin1String(CONDITION),QJSValue(condition));
707 if (ignoreCount != -1)
708 args.setProperty(QLatin1String(IGNORECOUNT),QJSValue(ignoreCount));
710 if (!args.isUndefined()) {
711 jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
714 QJSValue json = stringify.call(QJSValueList() << jsonVal);
715 sendMessage(packMessage(V8REQUEST, json.toString().toUtf8()));
718 void QJSDebugClient::clearBreakpoint(int breakpoint)
720 // { "seq" : <number>,
721 // "type" : "request",
722 // "command" : "clearbreakpoint",
723 // "arguments" : { "breakpoint" : <number of the break point to clear>
727 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(CLEARBREAKPOINT)));
729 QJSValue args = parser.call(QJSValueList() << obj);
731 args.setProperty(QLatin1String(BREAKPOINT),QJSValue(breakpoint));
733 if (!args.isUndefined()) {
734 jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
737 QJSValue json = stringify.call(QJSValueList() << jsonVal);
738 sendMessage(packMessage(V8REQUEST, json.toString().toUtf8()));
741 void QJSDebugClient::setExceptionBreak(Exception type, bool enabled)
743 // { "seq" : <number>,
744 // "type" : "request",
745 // "command" : "setexceptionbreak",
746 // "arguments" : { "type" : <string: "all", or "uncaught">,
747 // "enabled" : <optional bool: enables the break type if true>
751 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(SETEXCEPTIONBREAK)));
753 QJSValue args = parser.call(QJSValueList() << obj);
756 args.setProperty(QLatin1String(TYPE),QJSValue(QLatin1String(ALL)));
757 else if (type == Uncaught)
758 args.setProperty(QLatin1String(TYPE),QJSValue(QLatin1String(UNCAUGHT)));
761 args.setProperty(QLatin1String(ENABLED),QJSValue(enabled));
763 if (!args.isUndefined()) {
764 jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
767 QJSValue json = stringify.call(QJSValueList() << jsonVal);
768 sendMessage(packMessage(V8REQUEST, json.toString().toUtf8()));
771 void QJSDebugClient::v8flags(QString flags)
773 // { "seq" : <number>,
774 // "type" : "request",
775 // "command" : "v8flags",
776 // "arguments" : { "flags" : <string: a sequence of v8 flags just like those used on the command line>
780 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(V8FLAGS)));
782 QJSValue args = parser.call(QJSValueList() << obj);
784 args.setProperty(QLatin1String(FLAGS),QJSValue(flags));
786 if (!args.isUndefined()) {
787 jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
790 QJSValue json = stringify.call(QJSValueList() << jsonVal);
791 sendMessage(packMessage(V8REQUEST, json.toString().toUtf8()));
794 void QJSDebugClient::version()
796 // { "seq" : <number>,
797 // "type" : "request",
798 // "command" : "version",
801 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(VERSION)));
803 QJSValue json = stringify.call(QJSValueList() << jsonVal);
804 sendMessage(packMessage(V8REQUEST, json.toString().toUtf8()));
807 //void QJSDebugClient::profile(ProfileCommand command)
809 //// { "seq" : <number>,
810 //// "type" : "request",
811 //// "command" : "profile",
812 //// "arguments" : { "command" : "resume" or "pause" }
815 // jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(PROFILE)));
817 // QJSValue args = parser.call(QJSValueList() << obj);
819 // if (command == Resume)
820 // args.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(RESUME)));
822 // args.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(PAUSE)));
824 // args.setProperty(QLatin1String("modules"),QJSValue(1));
825 // if (!args.isUndefined()) {
826 // jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
829 // QJSValue json = stringify.call(QJSValueList() << jsonVal);
830 // sendMessage(packMessage(V8REQUEST, json.toString().toUtf8()));
833 void QJSDebugClient::disconnect()
835 // { "seq" : <number>,
836 // "type" : "request",
837 // "command" : "disconnect",
840 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(DISCONNECT)));
842 QJSValue json = stringify.call(QJSValueList() << jsonVal);
843 sendMessage(packMessage(DISCONNECT, json.toString().toUtf8()));
846 void QJSDebugClient::gc()
848 // { "seq" : <number>,
849 // "type" : "request",
851 // "arguments" : { "type" : <string: "all">,
855 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(GARBAGECOLLECTOR)));
857 QJSValue args = parser.call(QJSValueList() << obj);
859 args.setProperty(QLatin1String(TYPE),QJSValue(QLatin1String(ALL)));
861 if (!args.isUndefined()) {
862 jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
865 QJSValue json = stringify.call(QJSValueList() << jsonVal);
866 sendMessage(packMessage(V8REQUEST, json.toString().toUtf8()));
869 void QJSDebugClient::listBreakpoints()
871 // { "seq" : <number>,
872 // "type" : "request",
873 // "command" : "listbreakpoints",
876 jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(LISTBREAKPOINTS)));
878 QJSValue json = stringify.call(QJSValueList() << jsonVal);
879 sendMessage(packMessage(V8REQUEST, json.toString().toUtf8()));
882 void QJSDebugClient::stateChanged(State state)
884 if (state == Enabled) {
890 void QJSDebugClient::messageReceived(const QByteArray &data)
892 QDataStream ds(data);
896 if (command == "V8DEBUG") {
898 ds >> type >> response;
900 if (type == CONNECT) {
903 } else if (type == INTERRUPT) {
904 emit interruptRequested();
906 } else if (type == V8MESSAGE) {
907 QString jsonString(response);
908 QVariantMap value = parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
909 QString type = value.value("type").toString();
911 if (type == "response") {
913 if (!value.value("success").toBool()) {
914 // qDebug() << "Error: The test case will fail since no signal is emitted";
918 QString debugCommand(value.value("command").toString());
919 if (debugCommand == "backtrace" ||
920 debugCommand == "lookup" ||
921 debugCommand == "setbreakpoint" ||
922 debugCommand == "evaluate" ||
923 debugCommand == "listbreakpoints" ||
924 debugCommand == "version" ||
925 debugCommand == "v8flags" ||
926 debugCommand == "disconnect" ||
927 debugCommand == "gc" ||
928 debugCommand == "changebreakpoint" ||
929 debugCommand == "clearbreakpoint" ||
930 debugCommand == "frame" ||
931 debugCommand == "scope" ||
932 debugCommand == "scopes" ||
933 debugCommand == "scripts" ||
934 debugCommand == "source" ||
935 debugCommand == "setexceptionbreak" /*||
936 debugCommand == "profile"*/) {
943 } else if (type == QLatin1String(EVENT)) {
944 QString event(value.value(QLatin1String(EVENT)).toString());
946 if (event == "break" ||
947 event == "exception")
951 } else if (type == BREAKAFTERCOMPILE) {
952 emit breakAfterCompileRequested();
958 void QJSDebugClient::sendMessage(const QByteArray &msg)
960 if (state() == Enabled) {
961 QDeclarativeDebugClient::sendMessage(msg);
963 sendBuffer.append(msg);
967 void QJSDebugClient::flushSendBuffer()
969 foreach (const QByteArray &msg, sendBuffer)
970 QDeclarativeDebugClient::sendMessage(msg);
974 QByteArray QJSDebugClient::packMessage(const QByteArray &type, const QByteArray &message)
977 QDataStream rs(&reply, QIODevice::WriteOnly);
978 QByteArray cmd = "V8DEBUG";
979 rs << cmd << type << message;
983 void tst_QDeclarativeDebugJS::initTestCase()
985 QDeclarativeDataTest::initTestCase();
992 void tst_QDeclarativeDebugJS::cleanupTestCase()
1005 // qDebug() << "Time Elapsed:" << t.elapsed();
1008 bool tst_QDeclarativeDebugJS::init(const QString &qmlFile, bool blockMode)
1010 connection = new QDeclarativeDebugConnection();
1011 process = new QDeclarativeDebugProcess(QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene");
1012 client = new QJSDebugClient(connection);
1014 QStringList systemEnvironment = QProcess::systemEnvironment();
1015 systemEnvironment << "QML_DISABLE_OPTIMIZER=1";
1016 process->setEnvironment(systemEnvironment);
1018 process->start(QStringList() << QLatin1String(BLOCKMODE) << testFile(qmlFile));
1020 process->start(QStringList() << QLatin1String(NORMALMODE) << testFile(qmlFile));
1022 if (!process->waitForSessionStart()) {
1026 connection->connectToHost("127.0.0.1", 3771);
1027 if (!connection->waitForConnected())
1030 return QDeclarativeDebugTest::waitForSignal(client, SIGNAL(enabled()));
1033 void tst_QDeclarativeDebugJS::cleanup()
1051 void tst_QDeclarativeDebugJS::connect()
1057 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(connected())));
1060 void tst_QDeclarativeDebugJS::interrupt()
1067 client->interrupt();
1068 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(interruptRequested())));
1071 void tst_QDeclarativeDebugJS::breakAfterCompile()
1073 //void breakAfterCompile(bool enabled)
1076 client->breakAfterCompile(true);
1079 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(breakAfterCompileRequested())));
1080 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1083 void tst_QDeclarativeDebugJS::getVersion()
1089 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(connected())));
1092 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1095 void tst_QDeclarativeDebugJS::getVersionWhenAttaching()
1099 QVERIFY(init(QLatin1String(TIMER_QMLFILE), false));
1103 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1106 void tst_QDeclarativeDebugJS::applyV8Flags()
1108 //void v8flags(QString flags)
1113 client->v8flags(QString());
1114 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1117 void tst_QDeclarativeDebugJS::disconnect()
1124 client->disconnect();
1125 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1128 void tst_QDeclarativeDebugJS::gc()
1136 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1139 void tst_QDeclarativeDebugJS::listBreakpoints()
1141 //void listBreakpoints()
1143 int sourceLine1 = 47;
1144 int sourceLine2 = 48;
1145 int sourceLine3 = 49;
1150 client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(TEST_QMLFILE), sourceLine1, -1, true);
1151 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1152 client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(TEST_QMLFILE), sourceLine2, -1, true);
1153 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1154 client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(TEST_QMLFILE), sourceLine3, -1, true);
1155 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1156 client->listBreakpoints();
1157 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1159 QString jsonString(client->response);
1160 QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1162 QList<QVariant> breakpoints = value.value("body").toMap().value("breakpoints").toList();
1164 QCOMPARE(breakpoints.count(), 3);
1167 void tst_QDeclarativeDebugJS::setBreakpointInScriptOnCompleted()
1169 //void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1)
1171 int sourceLine = 47;
1172 QVERIFY(init(ONCOMPLETED_QMLFILE));
1174 client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true);
1176 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1178 QString jsonString(client->response);
1179 QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1181 QVariantMap body = value.value("body").toMap();
1183 QCOMPARE(body.value("sourceLine").toInt(), sourceLine);
1184 QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(ONCOMPLETED_QMLFILE));
1187 void tst_QDeclarativeDebugJS::setBreakpointInScriptOnComponentCreated()
1189 //void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1)
1191 int sourceLine = 47;
1192 QVERIFY(init(CREATECOMPONENT_QMLFILE));
1194 client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true);
1196 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1198 QString jsonString(client->response);
1199 QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1201 QVariantMap body = value.value("body").toMap();
1203 QCOMPARE(body.value("sourceLine").toInt(), sourceLine);
1204 QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(ONCOMPLETED_QMLFILE));
1207 void tst_QDeclarativeDebugJS::setBreakpointInScriptOnTimerCallback()
1209 int sourceLine = 48;
1210 QVERIFY(init(TIMER_QMLFILE));
1214 client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(TIMER_QMLFILE), sourceLine, -1, true);
1215 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1217 QString jsonString(client->response);
1218 QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1220 QVariantMap body = value.value("body").toMap();
1222 QCOMPARE(body.value("sourceLine").toInt(), sourceLine);
1223 QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(TIMER_QMLFILE));
1226 void tst_QDeclarativeDebugJS::setBreakpointInScriptInDifferentFile()
1228 //void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1)
1230 int sourceLine = 43;
1231 QVERIFY(init(LOADJSFILE_QMLFILE));
1234 client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(TEST_JSFILE), sourceLine, -1, true);
1235 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1237 QString jsonString(client->response);
1238 QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1240 QVariantMap body = value.value("body").toMap();
1242 QCOMPARE(body.value("sourceLine").toInt(), sourceLine);
1243 QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(TEST_JSFILE));
1246 void tst_QDeclarativeDebugJS::setBreakpointInScriptOnComment()
1248 //void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1)
1250 int sourceLine = 47;
1251 int actualLine = 49;
1252 QVERIFY(init(BREAKPOINTRELOCATION_QMLFILE));
1255 client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(BREAKPOINTRELOCATION_QMLFILE), sourceLine, -1, true);
1256 QEXPECT_FAIL("", "Relocation of breakpoints is disabled right now", Abort);
1257 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped()), 1));
1259 QString jsonString(client->response);
1260 QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1262 QVariantMap body = value.value("body").toMap();
1264 QCOMPARE(body.value("sourceLine").toInt(), actualLine);
1265 QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(BREAKPOINTRELOCATION_QMLFILE));
1268 void tst_QDeclarativeDebugJS::setBreakpointInScriptOnEmptyLine()
1270 //void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1)
1272 int sourceLine = 48;
1273 int actualLine = 49;
1274 QVERIFY(init(BREAKPOINTRELOCATION_QMLFILE));
1277 client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(BREAKPOINTRELOCATION_QMLFILE), sourceLine, -1, true);
1278 QEXPECT_FAIL("", "Relocation of breakpoints is disabled right now", Abort);
1279 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped()), 1));
1281 QString jsonString(client->response);
1282 QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1284 QVariantMap body = value.value("body").toMap();
1286 QCOMPARE(body.value("sourceLine").toInt(), actualLine);
1287 QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(BREAKPOINTRELOCATION_QMLFILE));
1290 void tst_QDeclarativeDebugJS::setBreakpointInScriptWithCondition()
1292 //void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1)
1295 int sourceLine = 50;
1296 QVERIFY(init(CONDITION_QMLFILE));
1299 client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(CONDITION_QMLFILE), sourceLine, 1, true, QLatin1String("a > 10"));
1300 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1302 //Get the frame index
1303 QString jsonString = client->response;
1304 QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1306 QVariantMap body = value.value("body").toMap();
1308 int frameIndex = body.value("index").toInt();
1310 //Verify the value of 'result'
1311 client->evaluate(QLatin1String("a"),frameIndex);
1313 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1315 jsonString = client->response;
1316 value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1318 body = value.value("body").toMap();
1320 QVERIFY(body.value("value").toInt() > out);
1323 void tst_QDeclarativeDebugJS::setBreakpointWhenAttaching()
1325 int sourceLine = 49;
1326 QVERIFY(init(QLatin1String(TIMER_QMLFILE), false));
1329 client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(TIMER_QMLFILE), sourceLine);
1330 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1333 //void tst_QDeclarativeDebugJS::setBreakpointInFunction()
1335 // //void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1)
1337 // int actualLine = 31;
1339 // client->connect();
1340 // client->setBreakpoint(QLatin1String(FUNCTION), QLatin1String("doSomethingElse"), -1, -1, true);
1342 // QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1344 // QString jsonString(client->response);
1345 // QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1347 // QVariantMap body = value.value("body").toMap();
1349 // QCOMPARE(body.value("sourceLine").toInt(), actualLine);
1350 // QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(QMLFILE));
1353 void tst_QDeclarativeDebugJS::setBreakpointOnEvent()
1355 //void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1)
1357 QVERIFY(init(TIMER_QMLFILE));
1361 client->setBreakpoint(QLatin1String(EVENT), QLatin1String("triggered"), -1, -1, true);
1362 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1364 QString jsonString(client->response);
1365 QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1367 QVariantMap body = value.value("body").toMap();
1369 QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(TIMER_QMLFILE));
1373 void tst_QDeclarativeDebugJS::changeBreakpoint()
1375 //void changeBreakpoint(int breakpoint, bool enabled = false, QString condition = QString(), int ignoreCount = -1)
1377 int sourceLine1 = 50;
1378 int sourceLine2 = 51;
1379 QVERIFY(init(CHANGEBREAKPOINT_QMLFILE));
1382 client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(CHANGEBREAKPOINT_QMLFILE), sourceLine2, -1, true);
1383 client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(CHANGEBREAKPOINT_QMLFILE), sourceLine1, -1, true);
1385 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1387 //Will hit 1st brakpoint, change this breakpoint enable = false
1388 QString jsonString(client->response);
1389 QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1391 QVariantMap body = value.value("body").toMap();
1392 QList<QVariant> breakpointsHit = body.value("breakpoints").toList();
1394 int breakpoint = breakpointsHit.at(0).toInt();
1395 client->changeBreakpoint(breakpoint,false);
1397 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1399 //Continue with debugging
1400 client->continueDebugging(QJSDebugClient::Continue);
1401 //Hit 2nd breakpoint
1402 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1404 //Continue with debugging
1405 client->continueDebugging(QJSDebugClient::Continue);
1406 //Should stop at 2nd breakpoint
1407 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1409 jsonString = client->response;
1410 value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1412 body = value.value("body").toMap();
1414 QCOMPARE(body.value("sourceLine").toInt(), sourceLine2);
1417 void tst_QDeclarativeDebugJS::changeBreakpointOnCondition()
1419 //void changeBreakpoint(int breakpoint, bool enabled = false, QString condition = QString(), int ignoreCount = -1)
1421 int sourceLine1 = 50;
1422 int sourceLine2 = 51;
1424 QVERIFY(init(CHANGEBREAKPOINT_QMLFILE));
1427 client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(CHANGEBREAKPOINT_QMLFILE), sourceLine1, -1, true);
1428 client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(CHANGEBREAKPOINT_QMLFILE), sourceLine2, -1, true);
1430 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1432 //Will hit 1st brakpoint, change this breakpoint enable = false
1433 QString jsonString(client->response);
1434 QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1436 QVariantMap body = value.value("body").toMap();
1437 QList<QVariant> breakpointsHit = body.value("breakpoints").toList();
1439 int breakpoint = breakpointsHit.at(0).toInt();
1440 client->changeBreakpoint(breakpoint, false, QLatin1String("d == 0"));
1442 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1444 //Continue with debugging
1445 client->continueDebugging(QJSDebugClient::Continue);
1446 //Hit 2nd breakpoint
1447 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1449 //Continue with debugging
1450 client->continueDebugging(QJSDebugClient::Continue);
1451 //Should stop at 2nd breakpoint
1452 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1454 jsonString = client->response;
1455 value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1457 body = value.value("body").toMap();
1459 QCOMPARE(body.value("sourceLine").toInt(), sourceLine2);
1463 void tst_QDeclarativeDebugJS::clearBreakpoint()
1465 //void clearBreakpoint(int breakpoint);
1467 int sourceLine1 = 50;
1468 int sourceLine2 = 51;
1469 QVERIFY(init(CHANGEBREAKPOINT_QMLFILE));
1472 client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(CHANGEBREAKPOINT_QMLFILE), sourceLine1, -1, true);
1473 client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(CHANGEBREAKPOINT_QMLFILE), sourceLine2, -1, true);
1475 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1477 //Will hit 1st brakpoint, change this breakpoint enable = false
1478 QString jsonString(client->response);
1479 QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1481 QVariantMap body = value.value("body").toMap();
1482 QList<QVariant> breakpointsHit = body.value("breakpoints").toList();
1484 int breakpoint = breakpointsHit.at(0).toInt();
1485 client->clearBreakpoint(breakpoint);
1487 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1489 //Continue with debugging
1490 client->continueDebugging(QJSDebugClient::Continue);
1491 //Hit 2nd breakpoint
1492 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1494 //Continue with debugging
1495 client->continueDebugging(QJSDebugClient::Continue);
1496 //Should stop at 2nd breakpoint
1497 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1499 jsonString = client->response;
1500 value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1502 body = value.value("body").toMap();
1504 QCOMPARE(body.value("sourceLine").toInt(), sourceLine2);
1507 void tst_QDeclarativeDebugJS::setExceptionBreak()
1509 //void setExceptionBreak(QString type, bool enabled = false);
1511 QVERIFY(init(EXCEPTION_QMLFILE));
1512 client->setExceptionBreak(QJSDebugClient::All,true);
1514 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1517 void tst_QDeclarativeDebugJS::stepNext()
1519 //void continueDebugging(StepAction stepAction, int stepCount = 1);
1521 int sourceLine = 50;
1522 QVERIFY(init(STEPACTION_QMLFILE));
1524 client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(STEPACTION_QMLFILE), sourceLine, -1, true);
1526 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1528 client->continueDebugging(QJSDebugClient::Next);
1529 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1531 QString jsonString(client->response);
1532 QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1534 QVariantMap body = value.value("body").toMap();
1536 QCOMPARE(body.value("sourceLine").toInt(), sourceLine + 1);
1537 QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(STEPACTION_QMLFILE));
1540 void tst_QDeclarativeDebugJS::stepNextWithCount()
1542 //void continueDebugging(StepAction stepAction, int stepCount = 1);
1544 int sourceLine = 50;
1545 QVERIFY(init(STEPACTION_QMLFILE));
1548 client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(STEPACTION_QMLFILE), sourceLine, -1, true);
1549 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1551 client->continueDebugging(QJSDebugClient::Next, 2);
1552 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1554 QString jsonString(client->response);
1555 QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1557 QVariantMap body = value.value("body").toMap();
1559 QCOMPARE(body.value("sourceLine").toInt(), sourceLine + 2);
1560 QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(STEPACTION_QMLFILE));
1563 void tst_QDeclarativeDebugJS::stepIn()
1565 //void continueDebugging(StepAction stepAction, int stepCount = 1);
1567 int sourceLine = 54;
1568 int actualLine = 50;
1569 QVERIFY(init(STEPACTION_QMLFILE));
1572 client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(STEPACTION_QMLFILE), sourceLine, 1, true);
1573 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1575 client->continueDebugging(QJSDebugClient::In);
1576 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1578 QString jsonString(client->response);
1579 QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1581 QVariantMap body = value.value("body").toMap();
1583 QCOMPARE(body.value("sourceLine").toInt(), actualLine);
1584 QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(STEPACTION_QMLFILE));
1587 void tst_QDeclarativeDebugJS::stepOut()
1589 //void continueDebugging(StepAction stepAction, int stepCount = 1);
1591 int sourceLine = 50;
1592 int actualLine = 54;
1593 QVERIFY(init(STEPACTION_QMLFILE));
1596 client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(STEPACTION_QMLFILE), sourceLine, -1, true);
1597 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1599 client->continueDebugging(QJSDebugClient::Out);
1600 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1602 QString jsonString(client->response);
1603 QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1605 QVariantMap body = value.value("body").toMap();
1607 QCOMPARE(body.value("sourceLine").toInt(), actualLine);
1608 QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(STEPACTION_QMLFILE));
1611 void tst_QDeclarativeDebugJS::continueDebugging()
1613 //void continueDebugging(StepAction stepAction, int stepCount = 1);
1615 int sourceLine1 = 54;
1616 int sourceLine2 = 51;
1617 QVERIFY(init(STEPACTION_QMLFILE));
1620 client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(STEPACTION_QMLFILE), sourceLine1, -1, true);
1621 client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(STEPACTION_QMLFILE), sourceLine2, -1, true);
1622 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1624 client->continueDebugging(QJSDebugClient::Continue);
1625 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1627 QString jsonString(client->response);
1628 QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1630 QVariantMap body = value.value("body").toMap();
1632 QCOMPARE(body.value("sourceLine").toInt(), sourceLine2);
1633 QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(STEPACTION_QMLFILE));
1636 void tst_QDeclarativeDebugJS::backtrace()
1638 //void backtrace(int fromFrame = -1, int toFrame = -1, bool bottom = false);
1640 int sourceLine = 47;
1641 QVERIFY(init(ONCOMPLETED_QMLFILE));
1643 client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true);
1645 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1647 client->backtrace();
1648 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1651 void tst_QDeclarativeDebugJS::getFrameDetails()
1653 //void frame(int number = -1);
1655 int sourceLine = 47;
1656 QVERIFY(init(ONCOMPLETED_QMLFILE));
1658 client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true);
1660 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1663 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1666 void tst_QDeclarativeDebugJS::getScopeDetails()
1668 //void scope(int number = -1, int frameNumber = -1);
1670 int sourceLine = 47;
1671 QVERIFY(init(ONCOMPLETED_QMLFILE));
1673 client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true);
1675 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1678 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1681 void tst_QDeclarativeDebugJS::evaluateInGlobalScope()
1683 //void evaluate(QString expr, bool global = false, bool disableBreak = false, int frame = -1, const QVariantMap &addContext = QVariantMap());
1688 client->evaluate(QLatin1String("print('Hello World')"), true);
1689 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1691 //Verify the value of 'print'
1692 QString jsonString(client->response);
1693 QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1695 QVariantMap body = value.value("body").toMap();
1697 QCOMPARE(body.value("text").toString(),QLatin1String("undefined"));
1700 void tst_QDeclarativeDebugJS::evaluateInLocalScope()
1702 //void evaluate(QString expr, bool global = false, bool disableBreak = false, int frame = -1, const QVariantMap &addContext = QVariantMap());
1704 int sourceLine = 47;
1705 QVERIFY(init(ONCOMPLETED_QMLFILE));
1707 client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true);
1709 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1712 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1714 //Get the frame index
1715 QString jsonString(client->response);
1716 QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1718 QVariantMap body = value.value("body").toMap();
1720 int frameIndex = body.value("index").toInt();
1722 client->evaluate(QLatin1String("root.a"), frameIndex);
1723 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1725 //Verify the value of 'timer.interval'
1726 jsonString = client->response;
1727 value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1729 body = value.value("body").toMap();
1731 QCOMPARE(body.value("value").toInt(),10);
1734 void tst_QDeclarativeDebugJS::getScopes()
1736 //void scopes(int frameNumber = -1);
1738 int sourceLine = 47;
1739 QVERIFY(init(ONCOMPLETED_QMLFILE));
1741 client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true);
1743 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1746 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1749 void tst_QDeclarativeDebugJS::getScripts()
1751 //void scripts(int types = -1, QList<int> ids = QList<int>(), bool includeSource = false, QVariant filter = QVariant());
1754 QSKIP("QTBUG-23475 - Unreliable test on Mac OS X");
1762 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1763 QString jsonString(client->response);
1764 QVariantMap value = client->parser.call(QJSValueList()
1765 << QJSValue(jsonString)).toVariant().toMap();
1767 QList<QVariant> scripts = value.value("body").toList();
1769 QCOMPARE(scripts.count(), 2);
1772 void tst_QDeclarativeDebugJS::getSource()
1774 //void source(int frame = -1, int fromLine = -1, int toLine = -1);
1776 int sourceLine = 47;
1777 QVERIFY(init(ONCOMPLETED_QMLFILE));
1779 client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true);
1781 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
1784 QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
1787 QTEST_MAIN(tst_QDeclarativeDebugJS)
1789 #include "tst_qdeclarativedebugjs.moc"