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