Debugger: Improve output of autotests
[profile/ivi/qtdeclarative.git] / tests / auto / qml / debugger / qqmldebugjs / tst_qqmldebugjs.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the test suite of the Qt Toolkit.
7 **
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.
16 **
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.
20 **
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.
28 **
29 ** Other Usage
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.
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include <qtest.h>
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 <QtQml/QJSEngine>
50
51 //QQmlDebugTest
52 #include "debugutil_p.h"
53 #include "qqmldebugclient.h"
54 #include "../../../shared/util.h"
55
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";
88
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";
107
108 const char *CONNECT = "connect";
109 const char *INTERRUPT = "interrupt";
110
111 const char *REQUEST = "request";
112 const char *IN = "in";
113 const char *NEXT = "next";
114 const char *OUT = "out";
115
116 const char *FUNCTION = "function";
117 const char *SCRIPT = "script";
118 const char *SCRIPTREGEXP = "scriptRegExp";
119 const char *EVENT = "event";
120
121 const char *ALL = "all";
122 const char *UNCAUGHT = "uncaught";
123
124 //const char *PAUSE = "pause";
125 //const char *RESUME = "resume";
126
127 const char *BLOCKMODE = "-qmljsdebugger=port:3771,block";
128 const char *NORMALMODE = "-qmljsdebugger=port:3771";
129 const char *TEST_QMLFILE = "test.qml";
130 const char *TEST_JSFILE = "test.js";
131 const char *TIMER_QMLFILE = "timer.qml";
132 const char *LOADJSFILE_QMLFILE = "loadjsfile.qml";
133 const char *EXCEPTION_QMLFILE = "exception.qml";
134 const char *ONCOMPLETED_QMLFILE = "oncompleted.qml";
135 const char *CREATECOMPONENT_QMLFILE = "createComponent.qml";
136 const char *CONDITION_QMLFILE = "condition.qml";
137 const char *CHANGEBREAKPOINT_QMLFILE = "changeBreakpoint.qml";
138 const char *STEPACTION_QMLFILE = "stepAction.qml";
139 const char *BREAKPOINTRELOCATION_QMLFILE = "breakpointRelocation.qml";
140
141 #define VARIANTMAPINIT \
142     QString obj("{}"); \
143     QJSValue jsonVal = parser.call(QJSValueList() << obj); \
144     jsonVal.setProperty(SEQ,QJSValue(seq++)); \
145     jsonVal.setProperty(TYPE,REQUEST);
146
147
148 #undef QVERIFY
149 #define QVERIFY(statement) \
150 do {\
151     if (!QTest::qVerify((statement), #statement, "", __FILE__, __LINE__)) {\
152         if (QTest::currentTestFailed()) \
153           qDebug().nospace() << "\nDEBUGGEE OUTPUT:\n" << process->output();\
154         return;\
155     }\
156 } while (0)
157
158
159 class QJSDebugClient;
160
161 class tst_QQmlDebugJS : public QQmlDataTest
162 {
163     Q_OBJECT
164
165     bool init(const QString &qmlFile = QString(TEST_QMLFILE), bool blockMode = true);
166
167 private slots:
168     void initTestCase();
169     void cleanupTestCase();
170
171     void cleanup();
172
173     void connect();
174     void interrupt();
175     void getVersion();
176     void getVersionWhenAttaching();
177
178     void applyV8Flags();
179
180     void disconnect();
181
182     void gc();
183
184     void listBreakpoints();
185
186     void setBreakpointInScriptOnCompleted();
187     void setBreakpointInScriptOnComponentCreated();
188     void setBreakpointInScriptOnTimerCallback();
189     void setBreakpointInScriptInDifferentFile();
190     void setBreakpointInScriptOnComment();
191     void setBreakpointInScriptOnEmptyLine();
192     void setBreakpointInScriptOnOptimizedBinding();
193     void setBreakpointInScriptWithCondition();
194     //void setBreakpointInFunction(); //NOT SUPPORTED
195     void setBreakpointOnEvent();
196     void setBreakpointWhenAttaching();
197
198     void changeBreakpoint();
199     void changeBreakpointOnCondition();
200
201     void clearBreakpoint();
202
203     void setExceptionBreak();
204
205     void stepNext();
206     void stepNextWithCount();
207     void stepIn();
208     void stepOut();
209     void continueDebugging();
210
211     void backtrace();
212
213     void getFrameDetails();
214
215     void getScopeDetails();
216
217     void evaluateInGlobalScope();
218     void evaluateInLocalScope();
219
220     void getScopes();
221
222     void getScripts();
223
224     void getSource();
225
226     //    void profile(); //NOT SUPPORTED
227
228     //    void verifyQMLOptimizerDisabled();
229
230 private:
231     QQmlDebugProcess *process;
232     QJSDebugClient *client;
233     QQmlDebugConnection *connection;
234     QTime t;
235 };
236
237 class QJSDebugClient : public QQmlDebugClient
238 {
239     Q_OBJECT
240 public:
241     enum StepAction
242     {
243         Continue,
244         In,
245         Out,
246         Next
247     };
248
249     enum Exception
250     {
251         All,
252         Uncaught
253     };
254
255 //    enum ProfileCommand
256 //    {
257 //        Pause,
258 //        Resume
259 //    };
260
261     QJSDebugClient(QQmlDebugConnection *connection)
262         : QQmlDebugClient(QLatin1String("V8Debugger"), connection),
263           seq(0)
264     {
265         parser = jsEngine.evaluate(QLatin1String("JSON.parse"));
266         stringify = jsEngine.evaluate(QLatin1String("JSON.stringify"));
267     }
268
269     void connect();
270     void interrupt();
271
272     void continueDebugging(StepAction stepAction, int stepCount = 1);
273     void evaluate(QString expr, bool global = false, bool disableBreak = false, int frame = -1, const QVariantMap &addContext = QVariantMap());
274     void lookup(QList<int> handles, bool includeSource = false);
275     void backtrace(int fromFrame = -1, int toFrame = -1, bool bottom = false);
276     void frame(int number = -1);
277     void scope(int number = -1, int frameNumber = -1);
278     void scopes(int frameNumber = -1);
279     void scripts(int types = 4, QList<int> ids = QList<int>(), bool includeSource = false, QVariant filter = QVariant());
280     void source(int frame = -1, int fromLine = -1, int toLine = -1);
281     void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = true, QString condition = QString(), int ignoreCount = -1);
282     void changeBreakpoint(int breakpoint, bool enabled = true, QString condition = QString(), int ignoreCount = -1);
283     void clearBreakpoint(int breakpoint);
284     void setExceptionBreak(Exception type, bool enabled = false);
285     void v8flags(QString flags);
286     void version();
287     //void profile(ProfileCommand command); //NOT SUPPORTED
288     void disconnect();
289     void gc();
290     void listBreakpoints();
291
292 protected:
293     //inherited from QQmlDebugClient
294     void stateChanged(State state);
295     void messageReceived(const QByteArray &data);
296
297 signals:
298     void enabled();
299     void connected();
300     void interruptRequested();
301     void result();
302     void stopped();
303     void scriptsResult();
304     void evaluateResult();
305
306 private:
307     void sendMessage(const QByteArray &);
308     void flushSendBuffer();
309     QByteArray packMessage(const QByteArray &type, const QByteArray &message = QByteArray());
310
311 private:
312     QJSEngine jsEngine;
313     int seq;
314
315     QList<QByteArray> sendBuffer;
316 public:
317     QJSValue parser;
318     QJSValue stringify;
319     QByteArray response;
320
321 };
322
323 void QJSDebugClient::connect()
324 {
325     sendMessage(packMessage(CONNECT));
326 }
327
328 void QJSDebugClient::interrupt()
329 {
330     sendMessage(packMessage(INTERRUPT));
331 }
332
333 void QJSDebugClient::continueDebugging(StepAction action, int count)
334 {
335     //    { "seq"       : <number>,
336     //      "type"      : "request",
337     //      "command"   : "continue",
338     //      "arguments" : { "stepaction" : <"in", "next" or "out">,
339     //                      "stepcount"  : <number of steps (default 1)>
340     //                    }
341     //    }
342     VARIANTMAPINIT;
343     jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(CONTINEDEBUGGING)));
344
345     if (action != Continue) {
346         QJSValue args = parser.call(QJSValueList() << obj);
347         switch (action) {
348         case In: args.setProperty(QLatin1String(STEPACTION),QJSValue(QLatin1String(IN)));
349             break;
350         case Out: args.setProperty(QLatin1String(STEPACTION),QJSValue(QLatin1String(OUT)));
351             break;
352         case Next: args.setProperty(QLatin1String(STEPACTION),QJSValue(QLatin1String(NEXT)));
353             break;
354         default:break;
355         }
356         if (!args.isUndefined()) {
357             if (count != 1)
358                 args.setProperty(QLatin1String(STEPCOUNT),QJSValue(count));
359             jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
360         }
361     }
362     QJSValue json = stringify.call(QJSValueList() << jsonVal);
363     sendMessage(packMessage(V8REQUEST, json.toString().toUtf8()));
364 }
365
366 void QJSDebugClient::evaluate(QString expr, bool global, bool disableBreak, int frame, const QVariantMap &/*addContext*/)
367 {
368     //    { "seq"       : <number>,
369     //      "type"      : "request",
370     //      "command"   : "evaluate",
371     //      "arguments" : { "expression"    : <expression to evaluate>,
372     //                      "frame"         : <number>,
373     //                      "global"        : <boolean>,
374     //                      "disable_break" : <boolean>,
375     //                      "additional_context" : [
376     //                           { "name" : <name1>, "handle" : <handle1> },
377     //                           { "name" : <name2>, "handle" : <handle2> },
378     //                           ...
379     //                      ]
380     //                    }
381     //    }
382     VARIANTMAPINIT;
383     jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(EVALUATE)));
384
385     QJSValue args = parser.call(QJSValueList() << obj);
386     args.setProperty(QLatin1String(EXPRESSION),QJSValue(expr));
387
388     if (frame != -1)
389         args.setProperty(QLatin1String(FRAME),QJSValue(frame));
390
391     if (global)
392         args.setProperty(QLatin1String(GLOBAL),QJSValue(global));
393
394     if (disableBreak)
395         args.setProperty(QLatin1String(DISABLEBREAK),QJSValue(disableBreak));
396
397     if (!args.isUndefined()) {
398         jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
399     }
400
401     QJSValue json = stringify.call(QJSValueList() << jsonVal);
402     sendMessage(packMessage(V8REQUEST, json.toString().toUtf8()));
403 }
404
405 void QJSDebugClient::lookup(QList<int> handles, bool includeSource)
406 {
407     //    { "seq"       : <number>,
408     //      "type"      : "request",
409     //      "command"   : "lookup",
410     //      "arguments" : { "handles"       : <array of handles>,
411     //                      "includeSource" : <boolean indicating whether the source will be included when script objects are returned>,
412     //                    }
413     //    }
414     VARIANTMAPINIT;
415     jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(LOOKUP)));
416
417     QJSValue args = parser.call(QJSValueList() << obj);
418
419     QString arr("[]");
420     QJSValue array = parser.call(QJSValueList() << arr);
421     int index = 0;
422     foreach (int handle, handles) {
423         array.setProperty(index++,QJSValue(handle));
424     }
425     args.setProperty(QLatin1String(HANDLES),array);
426
427     if (includeSource)
428         args.setProperty(QLatin1String(INCLUDESOURCE),QJSValue(includeSource));
429
430     if (!args.isUndefined()) {
431         jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
432     }
433
434     QJSValue json = stringify.call(QJSValueList() << jsonVal);
435     sendMessage(packMessage(V8REQUEST, json.toString().toUtf8()));
436 }
437
438 void QJSDebugClient::backtrace(int fromFrame, int toFrame, bool bottom)
439 {
440     //    { "seq"       : <number>,
441     //      "type"      : "request",
442     //      "command"   : "backtrace",
443     //      "arguments" : { "fromFrame" : <number>
444     //                      "toFrame" : <number>
445     //                      "bottom" : <boolean, set to true if the bottom of the stack is requested>
446     //                    }
447     //    }
448     VARIANTMAPINIT;
449     jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(BACKTRACE)));
450
451     QJSValue args = parser.call(QJSValueList() << obj);
452
453     if (fromFrame != -1)
454         args.setProperty(QLatin1String(FROMFRAME),QJSValue(fromFrame));
455
456     if (toFrame != -1)
457         args.setProperty(QLatin1String(TOFRAME),QJSValue(toFrame));
458
459     if (bottom)
460         args.setProperty(QLatin1String(BOTTOM),QJSValue(bottom));
461
462     if (!args.isUndefined()) {
463         jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
464     }
465
466     QJSValue json = stringify.call(QJSValueList() << jsonVal);
467     sendMessage(packMessage(V8REQUEST, json.toString().toUtf8()));
468 }
469
470 void QJSDebugClient::frame(int number)
471 {
472     //    { "seq"       : <number>,
473     //      "type"      : "request",
474     //      "command"   : "frame",
475     //      "arguments" : { "number" : <frame number>
476     //                    }
477     //    }
478     VARIANTMAPINIT;
479     jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(FRAME)));
480
481     if (number != -1) {
482         QJSValue args = parser.call(QJSValueList() << obj);
483         args.setProperty(QLatin1String(NUMBER),QJSValue(number));
484
485         if (!args.isUndefined()) {
486             jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
487         }
488     }
489
490     QJSValue json = stringify.call(QJSValueList() << jsonVal);
491     sendMessage(packMessage(V8REQUEST, json.toString().toUtf8()));
492 }
493
494 void QJSDebugClient::scope(int number, int frameNumber)
495 {
496     //    { "seq"       : <number>,
497     //      "type"      : "request",
498     //      "command"   : "scope",
499     //      "arguments" : { "number" : <scope number>
500     //                      "frameNumber" : <frame number, optional uses selected frame if missing>
501     //                    }
502     //    }
503     VARIANTMAPINIT;
504     jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(SCOPE)));
505
506     if (number != -1) {
507         QJSValue args = parser.call(QJSValueList() << obj);
508         args.setProperty(QLatin1String(NUMBER),QJSValue(number));
509
510         if (frameNumber != -1)
511             args.setProperty(QLatin1String(FRAMENUMBER),QJSValue(frameNumber));
512
513         if (!args.isUndefined()) {
514             jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
515         }
516     }
517
518     QJSValue json = stringify.call(QJSValueList() << jsonVal);
519     sendMessage(packMessage(V8REQUEST, json.toString().toUtf8()));
520 }
521
522 void QJSDebugClient::scopes(int frameNumber)
523 {
524     //    { "seq"       : <number>,
525     //      "type"      : "request",
526     //      "command"   : "scopes",
527     //      "arguments" : { "frameNumber" : <frame number, optional uses selected frame if missing>
528     //                    }
529     //    }
530     VARIANTMAPINIT;
531     jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(SCOPES)));
532
533     if (frameNumber != -1) {
534         QJSValue args = parser.call(QJSValueList() << obj);
535         args.setProperty(QLatin1String(FRAMENUMBER),QJSValue(frameNumber));
536
537         if (!args.isUndefined()) {
538             jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
539         }
540     }
541
542     QJSValue json = stringify.call(QJSValueList() << jsonVal);
543     sendMessage(packMessage(V8REQUEST, json.toString().toUtf8()));
544 }
545
546 void QJSDebugClient::scripts(int types, QList<int> ids, bool includeSource, QVariant /*filter*/)
547 {
548     //    { "seq"       : <number>,
549     //      "type"      : "request",
550     //      "command"   : "scripts",
551     //      "arguments" : { "types"         : <types of scripts to retrieve
552     //                                           set bit 0 for native scripts
553     //                                           set bit 1 for extension scripts
554     //                                           set bit 2 for normal scripts
555     //                                         (default is 4 for normal scripts)>
556     //                      "ids"           : <array of id's of scripts to return. If this is not specified all scripts are requrned>
557     //                      "includeSource" : <boolean indicating whether the source code should be included for the scripts returned>
558     //                      "filter"        : <string or number: filter string or script id.
559     //                                         If a number is specified, then only the script with the same number as its script id will be retrieved.
560     //                                         If a string is specified, then only scripts whose names contain the filter string will be retrieved.>
561     //                    }
562     //    }
563     VARIANTMAPINIT;
564     jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(SCRIPTS)));
565
566     QJSValue args = parser.call(QJSValueList() << obj);
567     args.setProperty(QLatin1String(TYPES),QJSValue(types));
568
569     if (ids.count()) {
570         QString arr("[]");
571         QJSValue array = parser.call(QJSValueList() << arr);
572         int index = 0;
573         foreach (int id, ids) {
574             array.setProperty(index++,QJSValue(id));
575         }
576         args.setProperty(QLatin1String(IDS),array);
577     }
578
579     if (includeSource)
580         args.setProperty(QLatin1String(INCLUDESOURCE),QJSValue(includeSource));
581
582     if (!args.isUndefined()) {
583         jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
584     }
585
586     QJSValue json = stringify.call(QJSValueList() << jsonVal);
587     sendMessage(packMessage(V8REQUEST, json.toString().toUtf8()));
588 }
589
590 void QJSDebugClient::source(int frame, int fromLine, int toLine)
591 {
592     //    { "seq"       : <number>,
593     //      "type"      : "request",
594     //      "command"   : "source",
595     //      "arguments" : { "frame"    : <frame number (default selected frame)>
596     //                      "fromLine" : <from line within the source default is line 0>
597     //                      "toLine"   : <to line within the source this line is not included in
598     //                                    the result default is the number of lines in the script>
599     //                    }
600     //    }
601     VARIANTMAPINIT;
602     jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(SOURCE)));
603
604     QJSValue args = parser.call(QJSValueList() << obj);
605
606     if (frame != -1)
607         args.setProperty(QLatin1String(FRAME),QJSValue(frame));
608
609     if (fromLine != -1)
610         args.setProperty(QLatin1String(FROMLINE),QJSValue(fromLine));
611
612     if (toLine != -1)
613         args.setProperty(QLatin1String(TOLINE),QJSValue(toLine));
614
615     if (!args.isUndefined()) {
616         jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
617     }
618
619     QJSValue json = stringify.call(QJSValueList() << jsonVal);
620     sendMessage(packMessage(V8REQUEST, json.toString().toUtf8()));
621 }
622
623 void QJSDebugClient::setBreakpoint(QString type, QString target, int line, int column, bool enabled, QString condition, int ignoreCount)
624 {
625     //    { "seq"       : <number>,
626     //      "type"      : "request",
627     //      "command"   : "setbreakpoint",
628     //      "arguments" : { "type"        : <"function" or "script" or "scriptId" or "scriptRegExp">
629     //                      "target"      : <function expression or script identification>
630     //                      "line"        : <line in script or function>
631     //                      "column"      : <character position within the line>
632     //                      "enabled"     : <initial enabled state. True or false, default is true>
633     //                      "condition"   : <string with break point condition>
634     //                      "ignoreCount" : <number specifying the number of break point hits to ignore, default value is 0>
635     //                    }
636     //    }
637
638     if (type == QLatin1String(EVENT)) {
639         QByteArray reply;
640         QDataStream rs(&reply, QIODevice::WriteOnly);
641         rs <<  target.toUtf8() << enabled;
642         sendMessage(packMessage(QByteArray("breakonsignal"), reply));
643
644     } else {
645         VARIANTMAPINIT;
646         jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(SETBREAKPOINT)));
647
648         QJSValue args = parser.call(QJSValueList() << obj);
649
650         args.setProperty(QLatin1String(TYPE),QJSValue(type));
651         args.setProperty(QLatin1String(TARGET),QJSValue(target));
652
653         if (line != -1)
654             args.setProperty(QLatin1String(LINE),QJSValue(line));
655
656         if (column != -1)
657             args.setProperty(QLatin1String(COLUMN),QJSValue(column));
658
659         args.setProperty(QLatin1String(ENABLED),QJSValue(enabled));
660
661         if (!condition.isEmpty())
662             args.setProperty(QLatin1String(CONDITION),QJSValue(condition));
663
664         if (ignoreCount != -1)
665             args.setProperty(QLatin1String(IGNORECOUNT),QJSValue(ignoreCount));
666
667         if (!args.isUndefined()) {
668             jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
669         }
670
671         QJSValue json = stringify.call(QJSValueList() << jsonVal);
672         sendMessage(packMessage(V8REQUEST, json.toString().toUtf8()));
673     }
674 }
675
676 void QJSDebugClient::changeBreakpoint(int breakpoint, bool enabled, QString condition, int ignoreCount)
677 {
678     //    { "seq"       : <number>,
679     //      "type"      : "request",
680     //      "command"   : "changebreakpoint",
681     //      "arguments" : { "breakpoint"  : <number of the break point to clear>
682     //                      "enabled"     : <initial enabled state. True or false, default is true>
683     //                      "condition"   : <string with break point condition>
684     //                      "ignoreCount" : <number specifying the number of break point hits            }
685     //    }
686     VARIANTMAPINIT;
687     jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(CHANGEBREAKPOINT)));
688
689     QJSValue args = parser.call(QJSValueList() << obj);
690
691     args.setProperty(QLatin1String(BREAKPOINT),QJSValue(breakpoint));
692
693     args.setProperty(QLatin1String(ENABLED),QJSValue(enabled));
694
695     if (!condition.isEmpty())
696         args.setProperty(QLatin1String(CONDITION),QJSValue(condition));
697
698     if (ignoreCount != -1)
699         args.setProperty(QLatin1String(IGNORECOUNT),QJSValue(ignoreCount));
700
701     if (!args.isUndefined()) {
702         jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
703     }
704
705     QJSValue json = stringify.call(QJSValueList() << jsonVal);
706     sendMessage(packMessage(V8REQUEST, json.toString().toUtf8()));
707 }
708
709 void QJSDebugClient::clearBreakpoint(int breakpoint)
710 {
711     //    { "seq"       : <number>,
712     //      "type"      : "request",
713     //      "command"   : "clearbreakpoint",
714     //      "arguments" : { "breakpoint" : <number of the break point to clear>
715     //                    }
716     //    }
717     VARIANTMAPINIT;
718     jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(CLEARBREAKPOINT)));
719
720     QJSValue args = parser.call(QJSValueList() << obj);
721
722     args.setProperty(QLatin1String(BREAKPOINT),QJSValue(breakpoint));
723
724     if (!args.isUndefined()) {
725         jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
726     }
727
728     QJSValue json = stringify.call(QJSValueList() << jsonVal);
729     sendMessage(packMessage(V8REQUEST, json.toString().toUtf8()));
730 }
731
732 void QJSDebugClient::setExceptionBreak(Exception type, bool enabled)
733 {
734     //    { "seq"       : <number>,
735     //      "type"      : "request",
736     //      "command"   : "setexceptionbreak",
737     //      "arguments" : { "type"    : <string: "all", or "uncaught">,
738     //                      "enabled" : <optional bool: enables the break type if true>
739     //                    }
740     //    }
741     VARIANTMAPINIT;
742     jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(SETEXCEPTIONBREAK)));
743
744     QJSValue args = parser.call(QJSValueList() << obj);
745
746     if (type == All)
747         args.setProperty(QLatin1String(TYPE),QJSValue(QLatin1String(ALL)));
748     else if (type == Uncaught)
749         args.setProperty(QLatin1String(TYPE),QJSValue(QLatin1String(UNCAUGHT)));
750
751     if (enabled)
752         args.setProperty(QLatin1String(ENABLED),QJSValue(enabled));
753
754     if (!args.isUndefined()) {
755         jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
756     }
757
758     QJSValue json = stringify.call(QJSValueList() << jsonVal);
759     sendMessage(packMessage(V8REQUEST, json.toString().toUtf8()));
760 }
761
762 void QJSDebugClient::v8flags(QString flags)
763 {
764     //    { "seq"       : <number>,
765     //      "type"      : "request",
766     //      "command"   : "v8flags",
767     //      "arguments" : { "flags" : <string: a sequence of v8 flags just like those used on the command line>
768     //                    }
769     //    }
770     VARIANTMAPINIT;
771     jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(V8FLAGS)));
772
773     QJSValue args = parser.call(QJSValueList() << obj);
774
775     args.setProperty(QLatin1String(FLAGS),QJSValue(flags));
776
777     if (!args.isUndefined()) {
778         jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
779     }
780
781     QJSValue json = stringify.call(QJSValueList() << jsonVal);
782     sendMessage(packMessage(V8REQUEST, json.toString().toUtf8()));
783 }
784
785 void QJSDebugClient::version()
786 {
787     //    { "seq"       : <number>,
788     //      "type"      : "request",
789     //      "command"   : "version",
790     //    }
791     VARIANTMAPINIT;
792     jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(VERSION)));
793
794     QJSValue json = stringify.call(QJSValueList() << jsonVal);
795     sendMessage(packMessage(V8REQUEST, json.toString().toUtf8()));
796 }
797
798 //void QJSDebugClient::profile(ProfileCommand command)
799 //{
800 ////    { "seq"       : <number>,
801 ////      "type"      : "request",
802 ////      "command"   : "profile",
803 ////      "arguments" : { "command"  : "resume" or "pause" }
804 ////    }
805 //    VARIANTMAPINIT;
806 //    jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(PROFILE)));
807
808 //    QJSValue args = parser.call(QJSValueList() << obj);
809
810 //    if (command == Resume)
811 //        args.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(RESUME)));
812 //    else
813 //        args.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(PAUSE)));
814
815 //    args.setProperty(QLatin1String("modules"),QJSValue(1));
816 //    if (!args.isUndefined()) {
817 //        jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
818 //    }
819
820 //    QJSValue json = stringify.call(QJSValueList() << jsonVal);
821 //    sendMessage(packMessage(V8REQUEST, json.toString().toUtf8()));
822 //}
823
824 void QJSDebugClient::disconnect()
825 {
826     //    { "seq"     : <number>,
827     //      "type"    : "request",
828     //      "command" : "disconnect",
829     //    }
830     VARIANTMAPINIT;
831     jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(DISCONNECT)));
832
833     QJSValue json = stringify.call(QJSValueList() << jsonVal);
834     sendMessage(packMessage(DISCONNECT, json.toString().toUtf8()));
835 }
836
837 void QJSDebugClient::gc()
838 {
839     //    { "seq"       : <number>,
840     //      "type"      : "request",
841     //      "command"   : "gc",
842     //      "arguments" : { "type" : <string: "all">,
843     //                    }
844     //    }
845     VARIANTMAPINIT;
846     jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(GARBAGECOLLECTOR)));
847
848     QJSValue args = parser.call(QJSValueList() << obj);
849
850     args.setProperty(QLatin1String(TYPE),QJSValue(QLatin1String(ALL)));
851
852     if (!args.isUndefined()) {
853         jsonVal.setProperty(QLatin1String(ARGUMENTS),args);
854     }
855
856     QJSValue json = stringify.call(QJSValueList() << jsonVal);
857     sendMessage(packMessage(V8REQUEST, json.toString().toUtf8()));
858 }
859
860 void QJSDebugClient::listBreakpoints()
861 {
862     //    { "seq"       : <number>,
863     //      "type"      : "request",
864     //      "command"   : "listbreakpoints",
865     //    }
866     VARIANTMAPINIT;
867     jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(LISTBREAKPOINTS)));
868
869     QJSValue json = stringify.call(QJSValueList() << jsonVal);
870     sendMessage(packMessage(V8REQUEST, json.toString().toUtf8()));
871 }
872
873 void QJSDebugClient::stateChanged(State state)
874 {
875     if (state == Enabled) {
876         flushSendBuffer();
877         emit enabled();
878     }
879 }
880
881 void QJSDebugClient::messageReceived(const QByteArray &data)
882 {
883     QDataStream ds(data);
884     QByteArray command;
885     ds >> command;
886
887     if (command == "V8DEBUG") {
888         QByteArray type;
889         ds >> type >> response;
890
891         if (type == CONNECT) {
892             emit connected();
893
894         } else if (type == INTERRUPT) {
895             emit interruptRequested();
896
897         } else if (type == V8MESSAGE) {
898             QString jsonString(response);
899             QVariantMap value = parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
900             QString type = value.value("type").toString();
901
902             if (type == "response") {
903
904                 if (!value.value("success").toBool()) {
905 //                    qDebug() << "Error: The test case will fail since no signal is emitted";
906                     return;
907                 }
908
909                 QString debugCommand(value.value("command").toString());
910                 if (debugCommand == "backtrace" ||
911                         debugCommand == "lookup" ||
912                         debugCommand == "setbreakpoint" ||
913                         debugCommand == "evaluate" ||
914                         debugCommand == "listbreakpoints" ||
915                         debugCommand == "version" ||
916                         debugCommand == "v8flags" ||
917                         debugCommand == "disconnect" ||
918                         debugCommand == "gc" ||
919                         debugCommand == "changebreakpoint" ||
920                         debugCommand == "clearbreakpoint" ||
921                         debugCommand == "frame" ||
922                         debugCommand == "scope" ||
923                         debugCommand == "scopes" ||
924                         debugCommand == "scripts" ||
925                         debugCommand == "source" ||
926                         debugCommand == "setexceptionbreak" /*||
927                         debugCommand == "profile"*/) {
928                     emit result();
929
930                 } else {
931                     // DO NOTHING
932                 }
933                 //Emit separate signals for scripts ane evaluate
934                 //as the associated test cases are flaky
935                 if (debugCommand == "scripts")
936                     emit scriptsResult();
937                 if (debugCommand == "evaluate")
938                     emit evaluateResult();
939
940             } else if (type == QLatin1String(EVENT)) {
941                 QString event(value.value(QLatin1String(EVENT)).toString());
942
943                 if (event == "break" ||
944                         event == "exception")
945                     emit stopped();
946                 }
947
948         }
949     }
950 }
951
952 void QJSDebugClient::sendMessage(const QByteArray &msg)
953 {
954     if (state() == Enabled) {
955         QQmlDebugClient::sendMessage(msg);
956     } else {
957         sendBuffer.append(msg);
958     }
959 }
960
961 void QJSDebugClient::flushSendBuffer()
962 {
963     foreach (const QByteArray &msg, sendBuffer)
964         QQmlDebugClient::sendMessage(msg);
965     sendBuffer.clear();
966 }
967
968 QByteArray QJSDebugClient::packMessage(const QByteArray &type, const QByteArray &message)
969 {
970     QByteArray reply;
971     QDataStream rs(&reply, QIODevice::WriteOnly);
972     QByteArray cmd = "V8DEBUG";
973     rs << cmd << type << message;
974     return reply;
975 }
976
977 void tst_QQmlDebugJS::initTestCase()
978 {
979     QQmlDataTest::initTestCase();
980     t.start();
981     process = 0;
982     client = 0;
983     connection = 0;
984 }
985
986 void tst_QQmlDebugJS::cleanupTestCase()
987 {
988     if (process) {
989         process->stop();
990         delete process;
991     }
992
993     if (client)
994         delete client;
995
996     if (connection)
997         delete connection;
998
999 //    qDebug() << "Time Elapsed:" << t.elapsed();
1000 }
1001
1002 bool tst_QQmlDebugJS::init(const QString &qmlFile, bool blockMode)
1003 {
1004     connection = new QQmlDebugConnection();
1005     process = new QQmlDebugProcess(QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene");
1006     client = new QJSDebugClient(connection);
1007
1008     if (blockMode)
1009         process->start(QStringList() << QLatin1String(BLOCKMODE) << testFile(qmlFile));
1010     else
1011         process->start(QStringList() << QLatin1String(NORMALMODE) << testFile(qmlFile));
1012
1013     if (!process->waitForSessionStart()) {
1014         qDebug() << "could not launch application, or did not get 'Waiting for connection'.";
1015         return false;
1016     }
1017
1018     connection->connectToHost("127.0.0.1", 3771);
1019     if (!connection->waitForConnected()) {
1020         qDebug() << "could not connect to host!";
1021         return false;
1022     }
1023
1024     if (client->state() == QQmlDebugClient::Enabled)
1025         return true;
1026
1027     return QQmlDebugTest::waitForSignal(client, SIGNAL(enabled()));
1028 }
1029
1030 void tst_QQmlDebugJS::cleanup()
1031 {
1032     if (QTest::currentTestFailed()) {
1033         qDebug() << "Process State:" << process->state();
1034         qDebug() << "Application Output:" << process->output();
1035     }
1036
1037     if (process) {
1038         process->stop();
1039         delete process;
1040     }
1041
1042     if (client)
1043         delete client;
1044
1045     if (connection)
1046         delete connection;
1047
1048     process = 0;
1049     client = 0;
1050     connection = 0;
1051 }
1052
1053 void tst_QQmlDebugJS::connect()
1054 {
1055     //void connect()
1056
1057     QVERIFY(init());
1058     client->connect();
1059     QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(connected())));
1060 }
1061
1062 void tst_QQmlDebugJS::interrupt()
1063 {
1064     //void connect()
1065
1066     QVERIFY(init());
1067     client->connect();
1068
1069     client->interrupt();
1070     QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(interruptRequested())));
1071 }
1072
1073 void tst_QQmlDebugJS::getVersion()
1074 {
1075     //void version()
1076
1077     QVERIFY(init());
1078     client->connect();
1079     QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(connected())));
1080
1081     client->version();
1082     QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result())));
1083 }
1084
1085 void tst_QQmlDebugJS::getVersionWhenAttaching()
1086 {
1087     //void version()
1088
1089     QVERIFY(init(QLatin1String(TIMER_QMLFILE), false));
1090     client->connect();
1091
1092     client->version();
1093     QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result())));
1094 }
1095
1096 void tst_QQmlDebugJS::applyV8Flags()
1097 {
1098     //void v8flags(QString flags)
1099
1100     QVERIFY(init());
1101     client->connect();
1102
1103     client->v8flags(QString());
1104     QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result())));
1105 }
1106
1107 void tst_QQmlDebugJS::disconnect()
1108 {
1109     //void disconnect()
1110
1111     QVERIFY(init());
1112     client->connect();
1113
1114     client->disconnect();
1115     QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result())));
1116 }
1117
1118 void tst_QQmlDebugJS::gc()
1119 {
1120     //void gc()
1121
1122     QVERIFY(init());
1123     client->connect();
1124
1125     client->gc();
1126     QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result())));
1127 }
1128
1129 void tst_QQmlDebugJS::listBreakpoints()
1130 {
1131     //void listBreakpoints()
1132
1133     int sourceLine1 = 53;
1134     int sourceLine2 = 54;
1135     int sourceLine3 = 55;
1136
1137     QVERIFY(init());
1138     client->connect();
1139
1140     client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(TEST_QMLFILE), sourceLine1, -1, true);
1141     QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result())));
1142     client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(TEST_QMLFILE), sourceLine2, -1, true);
1143     QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result())));
1144     client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(TEST_QMLFILE), sourceLine3, -1, true);
1145     QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result())));
1146     client->listBreakpoints();
1147     QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result())));
1148
1149     QString jsonString(client->response);
1150     QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1151
1152     QList<QVariant> breakpoints = value.value("body").toMap().value("breakpoints").toList();
1153
1154     QCOMPARE(breakpoints.count(), 3);
1155 }
1156
1157 void tst_QQmlDebugJS::setBreakpointInScriptOnCompleted()
1158 {
1159     //void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1)
1160
1161     int sourceLine = 47;
1162     QVERIFY(init(ONCOMPLETED_QMLFILE));
1163
1164     client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true);
1165     client->connect();
1166     QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
1167
1168     QString jsonString(client->response);
1169     QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1170
1171     QVariantMap body = value.value("body").toMap();
1172
1173     QCOMPARE(body.value("sourceLine").toInt(), sourceLine);
1174     QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(ONCOMPLETED_QMLFILE));
1175 }
1176
1177 void tst_QQmlDebugJS::setBreakpointInScriptOnComponentCreated()
1178 {
1179     //void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1)
1180
1181     int sourceLine = 47;
1182     QVERIFY(init(CREATECOMPONENT_QMLFILE));
1183
1184     client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true);
1185     client->connect();
1186     QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
1187
1188     QString jsonString(client->response);
1189     QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1190
1191     QVariantMap body = value.value("body").toMap();
1192
1193     QCOMPARE(body.value("sourceLine").toInt(), sourceLine);
1194     QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(ONCOMPLETED_QMLFILE));
1195 }
1196
1197 void tst_QQmlDebugJS::setBreakpointInScriptOnTimerCallback()
1198 {
1199     int sourceLine = 48;
1200     QVERIFY(init(TIMER_QMLFILE));
1201
1202     client->connect();
1203
1204     client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(TIMER_QMLFILE), sourceLine, -1, true);
1205     QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
1206
1207     QString jsonString(client->response);
1208     QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1209
1210     QVariantMap body = value.value("body").toMap();
1211
1212     QCOMPARE(body.value("sourceLine").toInt(), sourceLine);
1213     QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(TIMER_QMLFILE));
1214 }
1215
1216 void tst_QQmlDebugJS::setBreakpointInScriptInDifferentFile()
1217 {
1218     //void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1)
1219
1220     int sourceLine = 43;
1221     QVERIFY(init(LOADJSFILE_QMLFILE));
1222
1223     client->connect();
1224     client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(TEST_JSFILE), sourceLine, -1, true);
1225     QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
1226
1227     QString jsonString(client->response);
1228     QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1229
1230     QVariantMap body = value.value("body").toMap();
1231
1232     QCOMPARE(body.value("sourceLine").toInt(), sourceLine);
1233     QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(TEST_JSFILE));
1234 }
1235
1236 void tst_QQmlDebugJS::setBreakpointInScriptOnComment()
1237 {
1238     //void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1)
1239
1240     int sourceLine = 47;
1241     int actualLine = 49;
1242     QVERIFY(init(BREAKPOINTRELOCATION_QMLFILE));
1243
1244     client->connect();
1245     client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(BREAKPOINTRELOCATION_QMLFILE), sourceLine, -1, true);
1246     QEXPECT_FAIL("", "Relocation of breakpoints is disabled right now", Abort);
1247     QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()), 1));
1248
1249     QString jsonString(client->response);
1250     QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1251
1252     QVariantMap body = value.value("body").toMap();
1253
1254     QCOMPARE(body.value("sourceLine").toInt(), actualLine);
1255     QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(BREAKPOINTRELOCATION_QMLFILE));
1256 }
1257
1258 void tst_QQmlDebugJS::setBreakpointInScriptOnEmptyLine()
1259 {
1260     //void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1)
1261
1262     int sourceLine = 48;
1263     int actualLine = 49;
1264     QVERIFY(init(BREAKPOINTRELOCATION_QMLFILE));
1265
1266     client->connect();
1267     client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(BREAKPOINTRELOCATION_QMLFILE), sourceLine, -1, true);
1268     QEXPECT_FAIL("", "Relocation of breakpoints is disabled right now", Abort);
1269     QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()), 1));
1270
1271     QString jsonString(client->response);
1272     QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1273
1274     QVariantMap body = value.value("body").toMap();
1275
1276     QCOMPARE(body.value("sourceLine").toInt(), actualLine);
1277     QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(BREAKPOINTRELOCATION_QMLFILE));
1278 }
1279
1280 void tst_QQmlDebugJS::setBreakpointInScriptOnOptimizedBinding()
1281 {
1282     //void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1)
1283
1284     int sourceLine = 52;
1285     QVERIFY(init(BREAKPOINTRELOCATION_QMLFILE));
1286
1287     client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(BREAKPOINTRELOCATION_QMLFILE), sourceLine, -1, true);
1288     client->connect();
1289     QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
1290
1291     QString jsonString(client->response);
1292     QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1293
1294     QVariantMap body = value.value("body").toMap();
1295
1296     QCOMPARE(body.value("sourceLine").toInt(), sourceLine);
1297     QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(BREAKPOINTRELOCATION_QMLFILE));
1298 }
1299
1300 void tst_QQmlDebugJS::setBreakpointInScriptWithCondition()
1301 {
1302     //void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1)
1303
1304     int out = 10;
1305     int sourceLine = 50;
1306     QVERIFY(init(CONDITION_QMLFILE));
1307
1308     client->connect();
1309     client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(CONDITION_QMLFILE), sourceLine, 1, true, QLatin1String("a > 10"));
1310     QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
1311
1312     //Get the frame index
1313     QString jsonString = client->response;
1314     QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1315
1316     QVariantMap body = value.value("body").toMap();
1317
1318     int frameIndex = body.value("index").toInt();
1319
1320     //Verify the value of 'result'
1321     client->evaluate(QLatin1String("a"),frameIndex);
1322
1323     QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result())));
1324
1325     jsonString = client->response;
1326     value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1327
1328     body = value.value("body").toMap();
1329
1330     QVERIFY(body.value("value").toInt() > out);
1331 }
1332
1333 void tst_QQmlDebugJS::setBreakpointWhenAttaching()
1334 {
1335     int sourceLine = 49;
1336     QVERIFY(init(QLatin1String(TIMER_QMLFILE), false));
1337
1338     client->connect();
1339     client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(TIMER_QMLFILE), sourceLine);
1340     QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
1341 }
1342
1343 //void tst_QQmlDebugJS::setBreakpointInFunction()
1344 //{
1345 //    //void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1)
1346
1347 //    int actualLine = 31;
1348
1349 //    client->connect();
1350 //    client->setBreakpoint(QLatin1String(FUNCTION), QLatin1String("doSomethingElse"), -1, -1, true);
1351
1352 //    QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
1353
1354 //    QString jsonString(client->response);
1355 //    QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1356
1357 //    QVariantMap body = value.value("body").toMap();
1358
1359 //    QCOMPARE(body.value("sourceLine").toInt(), actualLine);
1360 //    QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(QMLFILE));
1361 //}
1362
1363 void tst_QQmlDebugJS::setBreakpointOnEvent()
1364 {
1365     //void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1)
1366
1367     QVERIFY(init(TIMER_QMLFILE));
1368
1369     client->connect();
1370
1371     client->setBreakpoint(QLatin1String(EVENT), QLatin1String("triggered"), -1, -1, true);
1372     QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
1373
1374     QString jsonString(client->response);
1375     QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1376
1377     QVariantMap body = value.value("body").toMap();
1378
1379     QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(TIMER_QMLFILE));
1380 }
1381
1382
1383 void tst_QQmlDebugJS::changeBreakpoint()
1384 {
1385     //void changeBreakpoint(int breakpoint, bool enabled = false, QString condition = QString(), int ignoreCount = -1)
1386
1387     int sourceLine1 = 50;
1388     int sourceLine2 = 51;
1389     QVERIFY(init(CHANGEBREAKPOINT_QMLFILE));
1390
1391     client->connect();
1392     client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(CHANGEBREAKPOINT_QMLFILE), sourceLine2, -1, true);
1393     client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(CHANGEBREAKPOINT_QMLFILE), sourceLine1, -1, true);
1394
1395     QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
1396
1397     //Will hit 1st brakpoint, change this breakpoint enable = false
1398     QString jsonString(client->response);
1399     QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1400
1401     QVariantMap body = value.value("body").toMap();
1402     QList<QVariant> breakpointsHit = body.value("breakpoints").toList();
1403
1404     int breakpoint = breakpointsHit.at(0).toInt();
1405     client->changeBreakpoint(breakpoint,false);
1406
1407     QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result())));
1408
1409     //Continue with debugging
1410     client->continueDebugging(QJSDebugClient::Continue);
1411     //Hit 2nd breakpoint
1412     QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
1413
1414     //Continue with debugging
1415     client->continueDebugging(QJSDebugClient::Continue);
1416     //Should stop at 2nd breakpoint
1417     QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
1418
1419     jsonString = client->response;
1420     value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1421
1422     body = value.value("body").toMap();
1423
1424     QCOMPARE(body.value("sourceLine").toInt(), sourceLine2);
1425 }
1426
1427 void tst_QQmlDebugJS::changeBreakpointOnCondition()
1428 {
1429     //void changeBreakpoint(int breakpoint, bool enabled = false, QString condition = QString(), int ignoreCount = -1)
1430
1431     int sourceLine1 = 50;
1432     int sourceLine2 = 51;
1433
1434     QVERIFY(init(CHANGEBREAKPOINT_QMLFILE));
1435
1436     client->connect();
1437     client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(CHANGEBREAKPOINT_QMLFILE), sourceLine1, -1, true);
1438     client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(CHANGEBREAKPOINT_QMLFILE), sourceLine2, -1, true);
1439
1440     QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
1441
1442     //Will hit 1st brakpoint, change this breakpoint enable = false
1443     QString jsonString(client->response);
1444     QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1445
1446     QVariantMap body = value.value("body").toMap();
1447     QList<QVariant> breakpointsHit = body.value("breakpoints").toList();
1448
1449     int breakpoint = breakpointsHit.at(0).toInt();
1450     client->changeBreakpoint(breakpoint, false, QLatin1String("d == 0"));
1451
1452     QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result())));
1453
1454     //Continue with debugging
1455     client->continueDebugging(QJSDebugClient::Continue);
1456     //Hit 2nd breakpoint
1457     QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
1458
1459     //Continue with debugging
1460     client->continueDebugging(QJSDebugClient::Continue);
1461     //Should stop at 2nd breakpoint
1462     QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
1463
1464     jsonString = client->response;
1465     value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1466
1467     body = value.value("body").toMap();
1468
1469     QCOMPARE(body.value("sourceLine").toInt(), sourceLine2);
1470
1471 }
1472
1473 void tst_QQmlDebugJS::clearBreakpoint()
1474 {
1475     //void clearBreakpoint(int breakpoint);
1476
1477     int sourceLine1 = 50;
1478     int sourceLine2 = 51;
1479     QVERIFY(init(CHANGEBREAKPOINT_QMLFILE));
1480
1481     client->connect();
1482     client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(CHANGEBREAKPOINT_QMLFILE), sourceLine1, -1, true);
1483     client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(CHANGEBREAKPOINT_QMLFILE), sourceLine2, -1, true);
1484
1485     QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
1486
1487     //Will hit 1st brakpoint, change this breakpoint enable = false
1488     QString jsonString(client->response);
1489     QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1490
1491     QVariantMap body = value.value("body").toMap();
1492     QList<QVariant> breakpointsHit = body.value("breakpoints").toList();
1493
1494     int breakpoint = breakpointsHit.at(0).toInt();
1495     client->clearBreakpoint(breakpoint);
1496
1497     QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result())));
1498
1499     //Continue with debugging
1500     client->continueDebugging(QJSDebugClient::Continue);
1501     //Hit 2nd breakpoint
1502     QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
1503
1504     //Continue with debugging
1505     client->continueDebugging(QJSDebugClient::Continue);
1506     //Should stop at 2nd breakpoint
1507     QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
1508
1509     jsonString = client->response;
1510     value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1511
1512     body = value.value("body").toMap();
1513
1514     QCOMPARE(body.value("sourceLine").toInt(), sourceLine2);
1515 }
1516
1517 void tst_QQmlDebugJS::setExceptionBreak()
1518 {
1519     //void setExceptionBreak(QString type, bool enabled = false);
1520
1521     QVERIFY(init(EXCEPTION_QMLFILE));
1522     client->setExceptionBreak(QJSDebugClient::All,true);
1523     client->connect();
1524     QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
1525 }
1526
1527 void tst_QQmlDebugJS::stepNext()
1528 {
1529     //void continueDebugging(StepAction stepAction, int stepCount = 1);
1530
1531     int sourceLine = 50;
1532     QVERIFY(init(STEPACTION_QMLFILE));
1533
1534     client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(STEPACTION_QMLFILE), sourceLine, -1, true);
1535     client->connect();
1536     QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
1537
1538     client->continueDebugging(QJSDebugClient::Next);
1539     QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
1540
1541     QString jsonString(client->response);
1542     QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1543
1544     QVariantMap body = value.value("body").toMap();
1545
1546     QCOMPARE(body.value("sourceLine").toInt(), sourceLine + 1);
1547     QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(STEPACTION_QMLFILE));
1548 }
1549
1550 void tst_QQmlDebugJS::stepNextWithCount()
1551 {
1552     //void continueDebugging(StepAction stepAction, int stepCount = 1);
1553
1554     int sourceLine = 50;
1555     QVERIFY(init(STEPACTION_QMLFILE));
1556
1557     client->connect();
1558     client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(STEPACTION_QMLFILE), sourceLine, -1, true);
1559     QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
1560
1561     client->continueDebugging(QJSDebugClient::Next, 2);
1562     QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
1563
1564     QString jsonString(client->response);
1565     QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1566
1567     QVariantMap body = value.value("body").toMap();
1568
1569     QCOMPARE(body.value("sourceLine").toInt(), sourceLine + 2);
1570     QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(STEPACTION_QMLFILE));
1571 }
1572
1573 void tst_QQmlDebugJS::stepIn()
1574 {
1575     //void continueDebugging(StepAction stepAction, int stepCount = 1);
1576
1577     int sourceLine = 54;
1578     int actualLine = 50;
1579     QVERIFY(init(STEPACTION_QMLFILE));
1580
1581     client->connect();
1582     client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(STEPACTION_QMLFILE), sourceLine, 1, true);
1583     QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
1584
1585     client->continueDebugging(QJSDebugClient::In);
1586     QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
1587
1588     QString jsonString(client->response);
1589     QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1590
1591     QVariantMap body = value.value("body").toMap();
1592
1593     QCOMPARE(body.value("sourceLine").toInt(), actualLine);
1594     QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(STEPACTION_QMLFILE));
1595 }
1596
1597 void tst_QQmlDebugJS::stepOut()
1598 {
1599     //void continueDebugging(StepAction stepAction, int stepCount = 1);
1600
1601     int sourceLine = 50;
1602     int actualLine = 54;
1603     QVERIFY(init(STEPACTION_QMLFILE));
1604
1605     client->connect();
1606     client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(STEPACTION_QMLFILE), sourceLine, -1, true);
1607     QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
1608
1609     client->continueDebugging(QJSDebugClient::Out);
1610     QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
1611
1612     QString jsonString(client->response);
1613     QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1614
1615     QVariantMap body = value.value("body").toMap();
1616
1617     QCOMPARE(body.value("sourceLine").toInt(), actualLine);
1618     QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(STEPACTION_QMLFILE));
1619 }
1620
1621 void tst_QQmlDebugJS::continueDebugging()
1622 {
1623     //void continueDebugging(StepAction stepAction, int stepCount = 1);
1624
1625     int sourceLine1 = 54;
1626     int sourceLine2 = 51;
1627     QVERIFY(init(STEPACTION_QMLFILE));
1628
1629     client->connect();
1630     client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(STEPACTION_QMLFILE), sourceLine1, -1, true);
1631     client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(STEPACTION_QMLFILE), sourceLine2, -1, true);
1632     QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
1633
1634     client->continueDebugging(QJSDebugClient::Continue);
1635     QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
1636
1637     QString jsonString(client->response);
1638     QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1639
1640     QVariantMap body = value.value("body").toMap();
1641
1642     QCOMPARE(body.value("sourceLine").toInt(), sourceLine2);
1643     QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(STEPACTION_QMLFILE));
1644 }
1645
1646 void tst_QQmlDebugJS::backtrace()
1647 {
1648     //void backtrace(int fromFrame = -1, int toFrame = -1, bool bottom = false);
1649
1650     int sourceLine = 47;
1651     QVERIFY(init(ONCOMPLETED_QMLFILE));
1652
1653     client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true);
1654     client->connect();
1655     QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
1656
1657     client->backtrace();
1658     QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result())));
1659 }
1660
1661 void tst_QQmlDebugJS::getFrameDetails()
1662 {
1663     //void frame(int number = -1);
1664
1665     int sourceLine = 47;
1666     QVERIFY(init(ONCOMPLETED_QMLFILE));
1667
1668     client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true);
1669     client->connect();
1670     QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
1671
1672     client->frame();
1673     QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result())));
1674 }
1675
1676 void tst_QQmlDebugJS::getScopeDetails()
1677 {
1678     //void scope(int number = -1, int frameNumber = -1);
1679
1680     int sourceLine = 47;
1681     QVERIFY(init(ONCOMPLETED_QMLFILE));
1682
1683     client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true);
1684     client->connect();
1685     QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
1686
1687     client->scope();
1688     QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result())));
1689 }
1690
1691 void tst_QQmlDebugJS::evaluateInGlobalScope()
1692 {
1693     //void evaluate(QString expr, bool global = false, bool disableBreak = false, int frame = -1, const QVariantMap &addContext = QVariantMap());
1694
1695     QVERIFY(init());
1696
1697     client->connect();
1698     client->evaluate(QLatin1String("console.log('Hello World')"), true);
1699     QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(evaluateResult())));
1700
1701     //Verify the value of 'print'
1702     QString jsonString(client->response);
1703     QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1704
1705     QVariantMap body = value.value("body").toMap();
1706
1707     QCOMPARE(body.value("text").toString(),QLatin1String("undefined"));
1708 }
1709
1710 void tst_QQmlDebugJS::evaluateInLocalScope()
1711 {
1712     //void evaluate(QString expr, bool global = false, bool disableBreak = false, int frame = -1, const QVariantMap &addContext = QVariantMap());
1713
1714     int sourceLine = 47;
1715     QVERIFY(init(ONCOMPLETED_QMLFILE));
1716
1717     client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true);
1718     client->connect();
1719     QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
1720
1721     client->frame();
1722     QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result())));
1723
1724     //Get the frame index
1725     QString jsonString(client->response);
1726     QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1727
1728     QVariantMap body = value.value("body").toMap();
1729
1730     int frameIndex = body.value("index").toInt();
1731
1732     client->evaluate(QLatin1String("root.a"), frameIndex);
1733     QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(evaluateResult())));
1734
1735     //Verify the value of 'timer.interval'
1736     jsonString = client->response;
1737     value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
1738
1739     body = value.value("body").toMap();
1740
1741     QCOMPARE(body.value("value").toInt(),10);
1742 }
1743
1744 void tst_QQmlDebugJS::getScopes()
1745 {
1746     //void scopes(int frameNumber = -1);
1747
1748     int sourceLine = 47;
1749     QVERIFY(init(ONCOMPLETED_QMLFILE));
1750
1751     client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true);
1752     client->connect();
1753     QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
1754
1755     client->scopes();
1756     QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result())));
1757 }
1758
1759 void tst_QQmlDebugJS::getScripts()
1760 {
1761     //void scripts(int types = -1, QList<int> ids = QList<int>(), bool includeSource = false, QVariant filter = QVariant());
1762
1763 #ifdef Q_OS_MAC
1764     QSKIP("QTBUG-23475 - Unreliable test on Mac OS X");
1765 #endif
1766
1767     QVERIFY(init());
1768
1769     client->connect();
1770
1771     client->scripts();
1772     QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(scriptsResult())));
1773     QString jsonString(client->response);
1774     QVariantMap value = client->parser.call(QJSValueList()
1775                                             << QJSValue(jsonString)).toVariant().toMap();
1776
1777     QList<QVariant> scripts = value.value("body").toList();
1778
1779     QCOMPARE(scripts.count(), 2);
1780 }
1781
1782 void tst_QQmlDebugJS::getSource()
1783 {
1784     //void source(int frame = -1, int fromLine = -1, int toLine = -1);
1785
1786     int sourceLine = 47;
1787     QVERIFY(init(ONCOMPLETED_QMLFILE));
1788
1789     client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true);
1790     client->connect();
1791     QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
1792
1793     client->source();
1794     QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result())));
1795 }
1796
1797 QTEST_MAIN(tst_QQmlDebugJS)
1798
1799 #include "tst_qqmldebugjs.moc"
1800