|
1 /**************************************************************************** |
|
2 ** |
|
3 ** Copyright (C) 2009 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 ** No Commercial Usage |
|
11 ** This file contains pre-release code and may not be distributed. |
|
12 ** You may use this file in accordance with the terms and conditions |
|
13 ** contained in the Technology Preview License Agreement accompanying |
|
14 ** this package. |
|
15 ** |
|
16 ** GNU Lesser General Public License Usage |
|
17 ** Alternatively, this file may be used under the terms of the GNU Lesser |
|
18 ** General Public License version 2.1 as published by the Free Software |
|
19 ** Foundation and appearing in the file LICENSE.LGPL included in the |
|
20 ** packaging of this file. Please review the following information to |
|
21 ** ensure the GNU Lesser General Public License version 2.1 requirements |
|
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. |
|
23 ** |
|
24 ** In addition, as a special exception, Nokia gives you certain additional |
|
25 ** rights. These rights are described in the Nokia Qt LGPL Exception |
|
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. |
|
27 ** |
|
28 ** If you have questions regarding the use of this file, please contact |
|
29 ** Nokia at qt-info@nokia.com. |
|
30 ** |
|
31 ** |
|
32 ** |
|
33 ** |
|
34 ** |
|
35 ** |
|
36 ** |
|
37 ** |
|
38 ** $QT_END_LICENSE$ |
|
39 ** |
|
40 ****************************************************************************/ |
|
41 |
|
42 |
|
43 #include <QtTest/QtTest> |
|
44 |
|
45 #include <QtScript/qscriptengineagent.h> |
|
46 #include <QtScript/qscriptengine.h> |
|
47 #include <qscriptvalueiterator.h> |
|
48 |
|
49 //TESTED_CLASS= |
|
50 //TESTED_FILES= |
|
51 |
|
52 QT_BEGIN_NAMESPACE |
|
53 extern bool qt_script_isJITEnabled(); |
|
54 QT_END_NAMESPACE |
|
55 |
|
56 class tst_QScriptEngineAgent : public QObject |
|
57 { |
|
58 Q_OBJECT |
|
59 Q_PROPERTY(double testProperty READ testProperty WRITE setTestProperty) |
|
60 |
|
61 public: |
|
62 tst_QScriptEngineAgent(); |
|
63 virtual ~tst_QScriptEngineAgent(); |
|
64 |
|
65 double testProperty() const { return m_testProperty; } |
|
66 void setTestProperty(double val) { m_testProperty = val; } |
|
67 |
|
68 public slots: |
|
69 double testSlot(double arg) { return arg; } |
|
70 |
|
71 signals: |
|
72 void testSignal(double arg); |
|
73 |
|
74 private slots: |
|
75 void scriptLoadAndUnload_statement(); |
|
76 void scriptLoadAndUnload(); |
|
77 void scriptLoadAndUnload_eval(); |
|
78 void contextPushAndPop(); |
|
79 void functionEntryAndExit_semicolon(); |
|
80 void functionEntryAndExit_expression(); |
|
81 void functionEntryAndExit_functionCall(); |
|
82 void functionEntryAndExit_functionCallWithoutReturn(); |
|
83 void functionEntryAndExit_functionDefinition(); |
|
84 void functionEntryAndExit_native(); |
|
85 void functionEntryAndExit_native2(); |
|
86 void functionEntryAndExit_nativeThrowing(); |
|
87 void functionEntryAndExit_builtin(); |
|
88 void functionEntryAndExit_objects(); |
|
89 void functionEntryAndExit_slots(); |
|
90 void functionEntryAndExit_property_set(); |
|
91 void functionEntryAndExit_property_get(); |
|
92 void functionEntryAndExit_call(); |
|
93 void functionEntryAndExit_functionReturn_construct(); |
|
94 void functionEntryAndExit_functionReturn_call(); |
|
95 void functionEntryAndExit_objectCall(); |
|
96 void positionChange_1(); |
|
97 void positionChange_2(); |
|
98 void exceptionThrowAndCatch(); |
|
99 void eventOrder_assigment(); |
|
100 void eventOrder_functionDefinition(); |
|
101 void eventOrder_throwError(); |
|
102 void eventOrder_throwAndCatch(); |
|
103 void eventOrder_functions(); |
|
104 void eventOrder_throwCatchFinally(); |
|
105 void eventOrder_signalsHandling(); |
|
106 void recursiveObserve(); |
|
107 void multipleAgents(); |
|
108 void syntaxError(); |
|
109 void extension_invoctaion(); |
|
110 void extension(); |
|
111 void isEvaluatingInExtension(); |
|
112 void hasUncaughtException(); |
|
113 |
|
114 private: |
|
115 double m_testProperty; |
|
116 }; |
|
117 |
|
118 tst_QScriptEngineAgent::tst_QScriptEngineAgent() |
|
119 { |
|
120 } |
|
121 |
|
122 tst_QScriptEngineAgent::~tst_QScriptEngineAgent() |
|
123 { |
|
124 } |
|
125 |
|
126 struct ScriptEngineEvent |
|
127 { |
|
128 enum Type { |
|
129 ScriptLoad, |
|
130 ScriptUnload,//1 |
|
131 ContextPush, |
|
132 ContextPop, //3 |
|
133 FunctionEntry, //4 |
|
134 FunctionExit, //5 |
|
135 PositionChange, |
|
136 ExceptionThrow,//7 |
|
137 ExceptionCatch, |
|
138 DebuggerInvocationRequest |
|
139 }; |
|
140 |
|
141 Type type; |
|
142 |
|
143 qint64 scriptId; |
|
144 QString script; |
|
145 QString fileName; |
|
146 int lineNumber; |
|
147 int columnNumber; |
|
148 QScriptValue value; |
|
149 bool hasExceptionHandler; |
|
150 |
|
151 ScriptEngineEvent(qint64 scriptId, |
|
152 const QString &script, const QString &fileName, |
|
153 int lineNumber) |
|
154 : type(ScriptLoad), scriptId(scriptId), |
|
155 script(script), fileName(fileName), |
|
156 lineNumber(lineNumber) |
|
157 { } |
|
158 |
|
159 ScriptEngineEvent(Type type, qint64 scriptId = -777) |
|
160 : type(type), scriptId(scriptId) |
|
161 { } |
|
162 |
|
163 ScriptEngineEvent(Type type, qint64 scriptId, |
|
164 const QScriptValue &value) |
|
165 : type(type), scriptId(scriptId), |
|
166 value(value) |
|
167 { } |
|
168 |
|
169 ScriptEngineEvent(qint64 scriptId, |
|
170 int lineNumber, int columnNumber) |
|
171 : type(PositionChange), scriptId(scriptId), |
|
172 lineNumber(lineNumber), columnNumber(columnNumber) |
|
173 { } |
|
174 |
|
175 ScriptEngineEvent(qint64 scriptId, |
|
176 const QScriptValue &exception, bool hasHandler) |
|
177 : type(ExceptionThrow), scriptId(scriptId), |
|
178 value(exception), hasExceptionHandler(hasHandler) |
|
179 { } |
|
180 |
|
181 static QString typeToQString(Type t) |
|
182 { |
|
183 switch (t) { |
|
184 case ScriptEngineEvent::ScriptLoad: return "ScriptLoad"; |
|
185 case ScriptEngineEvent::ScriptUnload: return "ScriptUnload"; |
|
186 case ScriptEngineEvent::ContextPush: return "ContextPush"; |
|
187 case ScriptEngineEvent::ContextPop: return "ContextPop"; |
|
188 case ScriptEngineEvent::FunctionEntry: return "FunctionEntry"; |
|
189 case ScriptEngineEvent::FunctionExit: return "FunctionExit"; |
|
190 case ScriptEngineEvent::PositionChange: return "PositionChange"; |
|
191 case ScriptEngineEvent::ExceptionThrow: return "ExceptionThrow"; |
|
192 case ScriptEngineEvent::ExceptionCatch: return "ExceptionCatch"; |
|
193 case ScriptEngineEvent::DebuggerInvocationRequest: return "DebuggerInvocationRequest"; |
|
194 } |
|
195 } |
|
196 }; |
|
197 |
|
198 class ScriptEngineSpy : public QScriptEngineAgent, public QList<ScriptEngineEvent> |
|
199 { |
|
200 public: |
|
201 enum IgnoreFlag { |
|
202 IgnoreScriptLoad = 0x001, |
|
203 IgnoreScriptUnload = 0x002, |
|
204 IgnoreFunctionEntry = 0x004, |
|
205 IgnoreFunctionExit = 0x008, |
|
206 IgnorePositionChange = 0x010, |
|
207 IgnoreExceptionThrow = 0x020, |
|
208 IgnoreExceptionCatch = 0x040, |
|
209 IgnoreContextPush = 0x0100, |
|
210 IgnoreContextPop = 0x0200, |
|
211 IgnoreDebuggerInvocationRequest = 0x0400 |
|
212 }; |
|
213 |
|
214 ScriptEngineSpy(QScriptEngine *engine, int ignores = 0); |
|
215 ~ScriptEngineSpy(); |
|
216 |
|
217 void enableIgnoreFlags(int flags) |
|
218 { m_ignores |= flags; } |
|
219 void disableIgnoreFlags(int flags) |
|
220 { m_ignores &= ~flags; } |
|
221 |
|
222 protected: |
|
223 void scriptLoad(qint64 id, const QString &script, |
|
224 const QString &fileName, int lineNumber); |
|
225 void scriptUnload(qint64 id); |
|
226 |
|
227 void contextPush(); |
|
228 void contextPop(); |
|
229 |
|
230 void functionEntry(qint64 scriptId); |
|
231 void functionExit(qint64 scriptId, const QScriptValue &returnValue); |
|
232 |
|
233 void positionChange(qint64 scriptId, |
|
234 int lineNumber, int columnNumber); |
|
235 |
|
236 void exceptionThrow(qint64 scriptId, const QScriptValue &exception, |
|
237 bool hasHandler); |
|
238 void exceptionCatch(qint64 scriptId, const QScriptValue &exception); |
|
239 |
|
240 bool supportsExtension(Extension ext) const; |
|
241 QVariant extension(Extension ext, const QVariant &arg); |
|
242 |
|
243 private: |
|
244 int m_ignores; |
|
245 }; |
|
246 |
|
247 ScriptEngineSpy::ScriptEngineSpy(QScriptEngine *engine, int ignores) |
|
248 : QScriptEngineAgent(engine) |
|
249 { |
|
250 m_ignores = ignores; |
|
251 engine->setAgent(this); |
|
252 } |
|
253 |
|
254 ScriptEngineSpy::~ScriptEngineSpy() |
|
255 { |
|
256 } |
|
257 |
|
258 void ScriptEngineSpy::scriptLoad(qint64 id, const QString &script, |
|
259 const QString &fileName, int lineNumber) |
|
260 { |
|
261 if (!(m_ignores & IgnoreScriptLoad)) |
|
262 append(ScriptEngineEvent(id, script, fileName, lineNumber)); |
|
263 } |
|
264 |
|
265 void ScriptEngineSpy::scriptUnload(qint64 id) |
|
266 { |
|
267 if (!(m_ignores & IgnoreScriptUnload)) |
|
268 append(ScriptEngineEvent(ScriptEngineEvent::ScriptUnload, id)); |
|
269 } |
|
270 |
|
271 void ScriptEngineSpy::contextPush() |
|
272 { |
|
273 if (!(m_ignores & IgnoreContextPush)) |
|
274 append(ScriptEngineEvent(ScriptEngineEvent::ContextPush)); |
|
275 } |
|
276 |
|
277 void ScriptEngineSpy::contextPop() |
|
278 { |
|
279 if (!(m_ignores & IgnoreContextPop)) |
|
280 append(ScriptEngineEvent(ScriptEngineEvent::ContextPop)); |
|
281 } |
|
282 |
|
283 void ScriptEngineSpy::functionEntry(qint64 scriptId) |
|
284 { |
|
285 if (!(m_ignores & IgnoreFunctionEntry)) |
|
286 append(ScriptEngineEvent(ScriptEngineEvent::FunctionEntry, scriptId)); |
|
287 } |
|
288 |
|
289 void ScriptEngineSpy::functionExit(qint64 scriptId, |
|
290 const QScriptValue &returnValue) |
|
291 { |
|
292 if (!(m_ignores & IgnoreFunctionExit)) |
|
293 append(ScriptEngineEvent(ScriptEngineEvent::FunctionExit, scriptId, returnValue)); |
|
294 } |
|
295 |
|
296 void ScriptEngineSpy::positionChange(qint64 scriptId, |
|
297 int lineNumber, int columnNumber) |
|
298 { |
|
299 if (!(m_ignores & IgnorePositionChange)) |
|
300 append(ScriptEngineEvent(scriptId, lineNumber, columnNumber)); |
|
301 } |
|
302 |
|
303 void ScriptEngineSpy::exceptionThrow(qint64 scriptId, |
|
304 const QScriptValue &exception, bool hasHandler) |
|
305 { |
|
306 if (!(m_ignores & IgnoreExceptionThrow)) |
|
307 append(ScriptEngineEvent(scriptId, exception, hasHandler)); |
|
308 } |
|
309 |
|
310 void ScriptEngineSpy::exceptionCatch(qint64 scriptId, |
|
311 const QScriptValue &exception) |
|
312 { |
|
313 if (!(m_ignores & IgnoreExceptionCatch)) |
|
314 append(ScriptEngineEvent(ScriptEngineEvent::ExceptionCatch, scriptId, exception)); |
|
315 } |
|
316 |
|
317 bool ScriptEngineSpy::supportsExtension(Extension ext) const |
|
318 { |
|
319 if (ext == DebuggerInvocationRequest) |
|
320 return !(m_ignores & IgnoreDebuggerInvocationRequest); |
|
321 return false; |
|
322 } |
|
323 |
|
324 QVariant ScriptEngineSpy::extension(Extension ext, const QVariant &arg) |
|
325 { |
|
326 if (ext == DebuggerInvocationRequest) { |
|
327 QVariantList lst = arg.toList(); |
|
328 qint64 scriptId = lst.at(0).toLongLong(); |
|
329 int lineNumber = lst.at(1).toInt(); |
|
330 int columnNumber = lst.at(2).toInt(); |
|
331 ScriptEngineEvent evt(scriptId, lineNumber, columnNumber); |
|
332 evt.type = ScriptEngineEvent::DebuggerInvocationRequest; |
|
333 append(evt); |
|
334 return QString::fromLatin1("extension(DebuggerInvocationRequest)"); |
|
335 } |
|
336 return QVariant(); |
|
337 } |
|
338 |
|
339 void tst_QScriptEngineAgent::scriptLoadAndUnload_statement() |
|
340 { |
|
341 QScriptEngine eng; |
|
342 ScriptEngineSpy *spy = new ScriptEngineSpy(&eng, ~(ScriptEngineSpy::IgnoreScriptLoad |
|
343 | ScriptEngineSpy::IgnoreScriptUnload)); |
|
344 QCOMPARE(eng.agent(), (QScriptEngineAgent*)spy); |
|
345 { |
|
346 spy->clear(); |
|
347 QString code = ";"; |
|
348 QString fileName = "foo.qs"; |
|
349 int lineNumber = 123; |
|
350 eng.evaluate(code, fileName, lineNumber); |
|
351 |
|
352 QCOMPARE(spy->count(), 2); |
|
353 |
|
354 QCOMPARE(spy->at(0).type, ScriptEngineEvent::ScriptLoad); |
|
355 QVERIFY(spy->at(0).scriptId != -1); |
|
356 QCOMPARE(spy->at(0).script, code); |
|
357 QCOMPARE(spy->at(0).fileName, fileName); |
|
358 QCOMPARE(spy->at(0).lineNumber, lineNumber); |
|
359 |
|
360 QCOMPARE(spy->at(1).type, ScriptEngineEvent::ScriptUnload); |
|
361 QCOMPARE(spy->at(1).scriptId, spy->at(0).scriptId); |
|
362 } |
|
363 |
|
364 { |
|
365 spy->clear(); |
|
366 QString code = ";"; |
|
367 QString fileName = "bar.qs"; |
|
368 int lineNumber = 456; |
|
369 eng.evaluate(code, fileName, lineNumber); |
|
370 |
|
371 QCOMPARE(spy->count(), 2); |
|
372 |
|
373 QCOMPARE(spy->at(0).type, ScriptEngineEvent::ScriptLoad); |
|
374 QVERIFY(spy->at(0).scriptId != -1); |
|
375 QCOMPARE(spy->at(0).script, code); |
|
376 QCOMPARE(spy->at(0).fileName, fileName); |
|
377 QCOMPARE(spy->at(0).lineNumber, lineNumber); |
|
378 |
|
379 QCOMPARE(spy->at(1).type, ScriptEngineEvent::ScriptUnload); |
|
380 QCOMPARE(spy->at(1).scriptId, spy->at(0).scriptId); |
|
381 } |
|
382 delete spy; |
|
383 } |
|
384 |
|
385 void tst_QScriptEngineAgent::scriptLoadAndUnload() |
|
386 { |
|
387 QScriptEngine eng; |
|
388 ScriptEngineSpy *spy = new ScriptEngineSpy(&eng, ~(ScriptEngineSpy::IgnoreScriptLoad |
|
389 | ScriptEngineSpy::IgnoreScriptUnload)); |
|
390 QCOMPARE(eng.agent(), (QScriptEngineAgent*)spy); |
|
391 { |
|
392 spy->clear(); |
|
393 QString code = "function foo() { print('ciao'); }"; |
|
394 QString fileName = "baz.qs"; |
|
395 int lineNumber = 789; |
|
396 eng.evaluate(code, fileName, lineNumber); |
|
397 |
|
398 QCOMPARE(spy->count(), 1); |
|
399 |
|
400 QCOMPARE(spy->at(0).type, ScriptEngineEvent::ScriptLoad); |
|
401 QVERIFY(spy->at(0).scriptId != -1); |
|
402 QCOMPARE(spy->at(0).script, code); |
|
403 QCOMPARE(spy->at(0).fileName, fileName); |
|
404 QCOMPARE(spy->at(0).lineNumber, lineNumber); |
|
405 |
|
406 code = "foo = null"; |
|
407 eng.evaluate(code); |
|
408 QCOMPARE(spy->count(), 3); |
|
409 |
|
410 QCOMPARE(spy->at(1).type, ScriptEngineEvent::ScriptLoad); |
|
411 QVERIFY(spy->at(1).scriptId != -1); |
|
412 QVERIFY(spy->at(1).scriptId != spy->at(0).scriptId); |
|
413 QCOMPARE(spy->at(1).script, code); |
|
414 QCOMPARE(spy->at(1).lineNumber, 1); |
|
415 |
|
416 QCOMPARE(spy->at(2).type, ScriptEngineEvent::ScriptUnload); |
|
417 QCOMPARE(spy->at(2).scriptId, spy->at(1).scriptId); |
|
418 |
|
419 eng.collectGarbage(); // foo() is GC'ed |
|
420 QCOMPARE(spy->count(), 4); |
|
421 QCOMPARE(spy->at(3).type, ScriptEngineEvent::ScriptUnload); |
|
422 QCOMPARE(spy->at(3).scriptId, spy->at(0).scriptId); |
|
423 } |
|
424 |
|
425 { |
|
426 spy->clear(); |
|
427 QString code = "function foo() { return function() { print('ciao'); } }"; |
|
428 QString fileName = "foo.qs"; |
|
429 int lineNumber = 123; |
|
430 eng.evaluate(code, fileName, lineNumber); |
|
431 |
|
432 QCOMPARE(spy->count(), 1); |
|
433 |
|
434 QCOMPARE(spy->at(0).type, ScriptEngineEvent::ScriptLoad); |
|
435 QVERIFY(spy->at(0).scriptId != -1); |
|
436 QCOMPARE(spy->at(0).script, code); |
|
437 QCOMPARE(spy->at(0).fileName, fileName); |
|
438 QCOMPARE(spy->at(0).lineNumber, lineNumber); |
|
439 |
|
440 code = "bar = foo(); foo = null"; |
|
441 eng.evaluate(code); |
|
442 QCOMPARE(spy->count(), 3); |
|
443 |
|
444 QCOMPARE(spy->at(1).type, ScriptEngineEvent::ScriptLoad); |
|
445 QVERIFY(spy->at(1).scriptId != -1); |
|
446 QVERIFY(spy->at(1).scriptId != spy->at(0).scriptId); |
|
447 QCOMPARE(spy->at(1).script, code); |
|
448 |
|
449 QCOMPARE(spy->at(2).type, ScriptEngineEvent::ScriptUnload); |
|
450 QCOMPARE(spy->at(2).scriptId, spy->at(1).scriptId); |
|
451 |
|
452 eng.collectGarbage(); // foo() is not GC'ed |
|
453 QCOMPARE(spy->count(), 3); |
|
454 |
|
455 code = "bar = null"; |
|
456 eng.evaluate(code); |
|
457 QCOMPARE(spy->count(), 5); |
|
458 |
|
459 eng.collectGarbage(); // foo() is GC'ed |
|
460 QCOMPARE(spy->count(), 6); |
|
461 } |
|
462 delete spy; |
|
463 } |
|
464 |
|
465 void tst_QScriptEngineAgent::scriptLoadAndUnload_eval() |
|
466 { |
|
467 QScriptEngine eng; |
|
468 ScriptEngineSpy *spy = new ScriptEngineSpy(&eng, ~(ScriptEngineSpy::IgnoreScriptLoad |
|
469 | ScriptEngineSpy::IgnoreScriptUnload)); |
|
470 { |
|
471 spy->clear(); |
|
472 eng.evaluate("eval('function foo() { print(123); }')"); |
|
473 |
|
474 QEXPECT_FAIL("","Eval is threaded in different way that in old backend", Abort); |
|
475 QCOMPARE(spy->count(), 3); |
|
476 |
|
477 QCOMPARE(spy->at(0).type, ScriptEngineEvent::ScriptLoad); |
|
478 QVERIFY(spy->at(0).scriptId != -1); |
|
479 |
|
480 QCOMPARE(spy->at(1).type, ScriptEngineEvent::ScriptLoad); |
|
481 QVERIFY(spy->at(1).scriptId != -1); |
|
482 QVERIFY(spy->at(1).scriptId != spy->at(0).scriptId); |
|
483 |
|
484 QCOMPARE(spy->at(2).type, ScriptEngineEvent::ScriptUnload); |
|
485 QCOMPARE(spy->at(2).scriptId, spy->at(0).scriptId); |
|
486 } |
|
487 delete spy; |
|
488 } |
|
489 |
|
490 void tst_QScriptEngineAgent::contextPushAndPop() |
|
491 { |
|
492 QScriptEngine eng; |
|
493 ScriptEngineSpy *spy = new ScriptEngineSpy(&eng, ~(ScriptEngineSpy::IgnoreContextPush |
|
494 | ScriptEngineSpy::IgnoreContextPop)); |
|
495 |
|
496 { |
|
497 spy->clear(); |
|
498 eng.pushContext(); |
|
499 eng.popContext(); |
|
500 QCOMPARE(spy->count(), 2); |
|
501 |
|
502 QCOMPARE(spy->at(0).type, ScriptEngineEvent::ContextPush); |
|
503 QCOMPARE(spy->at(1).type, ScriptEngineEvent::ContextPop); |
|
504 } |
|
505 } |
|
506 |
|
507 static QScriptValue nativeFunctionReturningArg(QScriptContext *ctx, QScriptEngine *) |
|
508 { |
|
509 return ctx->argument(0); |
|
510 } |
|
511 |
|
512 static QScriptValue nativeFunctionThrowingError(QScriptContext *ctx, QScriptEngine *) |
|
513 { |
|
514 return ctx->throwError(ctx->argument(0).toString()); |
|
515 } |
|
516 |
|
517 static QScriptValue nativeFunctionCallingArg(QScriptContext *ctx, QScriptEngine *) |
|
518 { |
|
519 return ctx->argument(0).call(); |
|
520 } |
|
521 |
|
522 /** check behaiviour of ';' */ |
|
523 void tst_QScriptEngineAgent::functionEntryAndExit_semicolon() |
|
524 { |
|
525 QScriptEngine eng; |
|
526 ScriptEngineSpy *spy = new ScriptEngineSpy(&eng, ~(ScriptEngineSpy::IgnoreFunctionEntry |
|
527 | ScriptEngineSpy::IgnoreFunctionExit)); |
|
528 { |
|
529 spy->clear(); |
|
530 eng.evaluate(";"); |
|
531 |
|
532 QCOMPARE(spy->count(), 2); |
|
533 |
|
534 QCOMPARE(spy->at(0).type, ScriptEngineEvent::FunctionEntry); |
|
535 QVERIFY(spy->at(0).scriptId != -1); |
|
536 |
|
537 QCOMPARE(spy->at(1).type, ScriptEngineEvent::FunctionExit); |
|
538 QCOMPARE(spy->at(1).scriptId, spy->at(0).scriptId); |
|
539 QVERIFY(spy->at(1).value.isUndefined()); |
|
540 } |
|
541 delete spy; |
|
542 } |
|
543 |
|
544 /** check behaiviour of expression */ |
|
545 void tst_QScriptEngineAgent::functionEntryAndExit_expression() |
|
546 { |
|
547 QScriptEngine eng; |
|
548 ScriptEngineSpy *spy = new ScriptEngineSpy(&eng, ~(ScriptEngineSpy::IgnoreFunctionEntry |
|
549 | ScriptEngineSpy::IgnoreFunctionExit)); |
|
550 { |
|
551 spy->clear(); |
|
552 eng.evaluate("1 + 2"); |
|
553 |
|
554 QCOMPARE(spy->count(), 2); |
|
555 |
|
556 // evaluate() entry |
|
557 QCOMPARE(spy->at(0).type, ScriptEngineEvent::FunctionEntry); |
|
558 QVERIFY(spy->at(0).scriptId != -1); |
|
559 |
|
560 // evaluate() exit |
|
561 QCOMPARE(spy->at(1).type, ScriptEngineEvent::FunctionExit); |
|
562 QCOMPARE(spy->at(1).scriptId, spy->at(0).scriptId); |
|
563 QVERIFY(spy->at(1).value.isNumber()); |
|
564 QCOMPARE(spy->at(1).value.toNumber(), qsreal(3)); |
|
565 } |
|
566 delete spy; |
|
567 } |
|
568 |
|
569 /** check behaiviour of standard function call */ |
|
570 void tst_QScriptEngineAgent::functionEntryAndExit_functionCall() |
|
571 { |
|
572 QScriptEngine eng; |
|
573 ScriptEngineSpy *spy = new ScriptEngineSpy(&eng, ~(ScriptEngineSpy::IgnoreFunctionEntry |
|
574 | ScriptEngineSpy::IgnoreFunctionExit)); |
|
575 { |
|
576 spy->clear(); |
|
577 QVERIFY(eng.evaluate("(function() { return 123; } )()").toNumber()==123); |
|
578 |
|
579 QCOMPARE(spy->count(), 4); |
|
580 |
|
581 // evaluate() entry |
|
582 QCOMPARE(spy->at(0).type, ScriptEngineEvent::FunctionEntry); |
|
583 QVERIFY(spy->at(0).scriptId != -1); |
|
584 |
|
585 // anonymous function entry |
|
586 QCOMPARE(spy->at(1).type, ScriptEngineEvent::FunctionEntry); |
|
587 QCOMPARE(spy->at(1).scriptId, spy->at(0).scriptId); |
|
588 |
|
589 // anonymous function exit |
|
590 QCOMPARE(spy->at(2).type, ScriptEngineEvent::FunctionExit); |
|
591 QCOMPARE(spy->at(2).scriptId, spy->at(0).scriptId); |
|
592 QVERIFY(spy->at(2).value.isNumber()); |
|
593 QCOMPARE(spy->at(2).value.toNumber(), qsreal(123)); |
|
594 |
|
595 // evaluate() exit |
|
596 QCOMPARE(spy->at(3).type, ScriptEngineEvent::FunctionExit); |
|
597 QCOMPARE(spy->at(3).scriptId, spy->at(0).scriptId); |
|
598 QVERIFY(spy->at(3).value.isNumber()); |
|
599 QCOMPARE(spy->at(3).value.toNumber(), qsreal(123)); |
|
600 } |
|
601 delete spy; |
|
602 } |
|
603 |
|
604 /** check behaiviour of standard function call */ |
|
605 void tst_QScriptEngineAgent::functionEntryAndExit_functionCallWithoutReturn() |
|
606 { |
|
607 QScriptEngine eng; |
|
608 ScriptEngineSpy *spy = new ScriptEngineSpy(&eng, ~(ScriptEngineSpy::IgnoreFunctionEntry |
|
609 | ScriptEngineSpy::IgnoreFunctionExit)); |
|
610 { |
|
611 spy->clear(); |
|
612 eng.evaluate("(function() { var a = 123; } )()"); |
|
613 |
|
614 QCOMPARE(spy->count(), 4); |
|
615 |
|
616 // evaluate() entry |
|
617 QCOMPARE(spy->at(0).type, ScriptEngineEvent::FunctionEntry); |
|
618 QVERIFY(spy->at(0).scriptId != -1); |
|
619 |
|
620 // anonymous function entry |
|
621 QCOMPARE(spy->at(1).type, ScriptEngineEvent::FunctionEntry); |
|
622 QCOMPARE(spy->at(1).scriptId, spy->at(0).scriptId); |
|
623 |
|
624 // anonymous function exit |
|
625 QCOMPARE(spy->at(2).type, ScriptEngineEvent::FunctionExit); |
|
626 QCOMPARE(spy->at(2).scriptId, spy->at(0).scriptId); |
|
627 |
|
628 // evaluate() exit |
|
629 QCOMPARE(spy->at(3).type, ScriptEngineEvent::FunctionExit); |
|
630 QCOMPARE(spy->at(3).scriptId, spy->at(0).scriptId); |
|
631 } |
|
632 delete spy; |
|
633 } |
|
634 |
|
635 /** check behaiviour of function definition */ |
|
636 void tst_QScriptEngineAgent::functionEntryAndExit_functionDefinition() |
|
637 { |
|
638 QScriptEngine eng; |
|
639 ScriptEngineSpy *spy = new ScriptEngineSpy(&eng, ~(ScriptEngineSpy::IgnoreFunctionEntry |
|
640 | ScriptEngineSpy::IgnoreFunctionExit)); |
|
641 { |
|
642 spy->clear(); |
|
643 eng.evaluate("function foo() { return 456; }"); |
|
644 QCOMPARE(spy->count(), 2); |
|
645 |
|
646 // evaluate() entry |
|
647 QCOMPARE(spy->at(0).type, ScriptEngineEvent::FunctionEntry); |
|
648 QVERIFY(spy->at(0).scriptId != -1); |
|
649 |
|
650 // evaluate() exit |
|
651 QCOMPARE(spy->at(1).type, ScriptEngineEvent::FunctionExit); |
|
652 QCOMPARE(spy->at(1).scriptId, spy->at(0).scriptId); |
|
653 QVERIFY(spy->at(1).value.isUndefined()); |
|
654 |
|
655 eng.evaluate("foo()"); |
|
656 QCOMPARE(spy->count(), 6); |
|
657 |
|
658 // evaluate() entry |
|
659 QCOMPARE(spy->at(2).type, ScriptEngineEvent::FunctionEntry); |
|
660 QVERIFY(spy->at(2).scriptId != spy->at(0).scriptId); |
|
661 |
|
662 // foo() entry |
|
663 QCOMPARE(spy->at(3).type, ScriptEngineEvent::FunctionEntry); |
|
664 QCOMPARE(spy->at(3).scriptId, spy->at(0).scriptId); |
|
665 |
|
666 // foo() exit |
|
667 QCOMPARE(spy->at(4).type, ScriptEngineEvent::FunctionExit); |
|
668 QCOMPARE(spy->at(4).scriptId, spy->at(0).scriptId); |
|
669 QVERIFY(spy->at(4).value.isNumber()); |
|
670 QCOMPARE(spy->at(4).value.toNumber(), qsreal(456)); |
|
671 |
|
672 // evaluate() exit |
|
673 QCOMPARE(spy->at(5).type, ScriptEngineEvent::FunctionExit); |
|
674 QCOMPARE(spy->at(5).scriptId, spy->at(2).scriptId); |
|
675 QVERIFY(spy->at(5).value.isNumber()); |
|
676 QCOMPARE(spy->at(5).value.toNumber(), qsreal(456)); |
|
677 } |
|
678 delete spy; |
|
679 } |
|
680 |
|
681 /** check behaiviour of native function */ |
|
682 void tst_QScriptEngineAgent::functionEntryAndExit_native() |
|
683 { |
|
684 QScriptEngine eng; |
|
685 ScriptEngineSpy *spy = new ScriptEngineSpy(&eng, ~(ScriptEngineSpy::IgnoreFunctionEntry |
|
686 | ScriptEngineSpy::IgnoreFunctionExit)); |
|
687 // native functions |
|
688 { |
|
689 QScriptValue fun = eng.newFunction(nativeFunctionReturningArg); |
|
690 eng.globalObject().setProperty("nativeFunctionReturningArg", fun); |
|
691 |
|
692 spy->clear(); |
|
693 eng.evaluate("nativeFunctionReturningArg(123)"); |
|
694 |
|
695 QCOMPARE(spy->count(), 4); |
|
696 |
|
697 // evaluate() entry |
|
698 QCOMPARE(spy->at(0).type, ScriptEngineEvent::FunctionEntry); |
|
699 |
|
700 // native function entry |
|
701 QCOMPARE(spy->at(1).type, ScriptEngineEvent::FunctionEntry); |
|
702 QCOMPARE(spy->at(1).scriptId, qint64(-1)); |
|
703 |
|
704 // native function exit |
|
705 QCOMPARE(spy->at(2).type, ScriptEngineEvent::FunctionExit); |
|
706 QCOMPARE(spy->at(2).scriptId, qint64(-1)); |
|
707 QVERIFY(spy->at(2).value.isNumber()); |
|
708 QCOMPARE(spy->at(2).value.toNumber(), qsreal(123)); |
|
709 |
|
710 // evaluate() exit |
|
711 QCOMPARE(spy->at(3).type, ScriptEngineEvent::FunctionExit); |
|
712 QCOMPARE(spy->at(3).scriptId, spy->at(0).scriptId); |
|
713 QVERIFY(spy->at(3).value.isNumber()); |
|
714 QCOMPARE(spy->at(3).value.toNumber(), qsreal(123)); |
|
715 } |
|
716 delete spy; |
|
717 } |
|
718 |
|
719 /** check behaiviour of native function */ |
|
720 void tst_QScriptEngineAgent::functionEntryAndExit_native2() |
|
721 { |
|
722 QScriptEngine eng; |
|
723 ScriptEngineSpy *spy = new ScriptEngineSpy(&eng, ~(ScriptEngineSpy::IgnoreFunctionEntry |
|
724 | ScriptEngineSpy::IgnoreFunctionExit)); |
|
725 { |
|
726 QScriptValue fun = eng.newFunction(nativeFunctionCallingArg); |
|
727 eng.globalObject().setProperty("nativeFunctionCallingArg", fun); |
|
728 |
|
729 spy->clear(); |
|
730 eng.evaluate("nativeFunctionCallingArg(function() { return 123; })"); |
|
731 QCOMPARE(spy->count(), 6); |
|
732 |
|
733 // evaluate() entry |
|
734 QCOMPARE(spy->at(0).type, ScriptEngineEvent::FunctionEntry); |
|
735 |
|
736 // native function entry |
|
737 QCOMPARE(spy->at(1).type, ScriptEngineEvent::FunctionEntry); |
|
738 QCOMPARE(spy->at(1).scriptId, qint64(-1)); |
|
739 |
|
740 // script function entry |
|
741 QCOMPARE(spy->at(2).type, ScriptEngineEvent::FunctionEntry); |
|
742 QCOMPARE(spy->at(2).scriptId, spy->at(0).scriptId); |
|
743 |
|
744 // script function exit |
|
745 QCOMPARE(spy->at(3).type, ScriptEngineEvent::FunctionExit); |
|
746 QCOMPARE(spy->at(3).scriptId, spy->at(0).scriptId); |
|
747 |
|
748 // native function exit |
|
749 QCOMPARE(spy->at(4).type, ScriptEngineEvent::FunctionExit); |
|
750 QCOMPARE(spy->at(4).scriptId, qint64(-1)); |
|
751 QVERIFY(spy->at(4).value.isNumber()); |
|
752 QCOMPARE(spy->at(4).value.toNumber(), qsreal(123)); |
|
753 |
|
754 // evaluate() exit |
|
755 QCOMPARE(spy->at(5).type, ScriptEngineEvent::FunctionExit); |
|
756 QCOMPARE(spy->at(5).scriptId, spy->at(0).scriptId); |
|
757 QVERIFY(spy->at(5).value.isNumber()); |
|
758 QCOMPARE(spy->at(5).value.toNumber(), qsreal(123)); |
|
759 } |
|
760 delete spy; |
|
761 } |
|
762 |
|
763 /** check behaiviour of native function throwing error*/ |
|
764 void tst_QScriptEngineAgent::functionEntryAndExit_nativeThrowing() |
|
765 { |
|
766 /* This function was changed from old backend. JSC return more Entrys / Exits, (exactly +1) |
|
767 in exception creation time */ |
|
768 |
|
769 QScriptEngine eng; |
|
770 ScriptEngineSpy *spy = new ScriptEngineSpy(&eng, ~(ScriptEngineSpy::IgnoreFunctionEntry |
|
771 | ScriptEngineSpy::IgnoreFunctionExit)); |
|
772 { |
|
773 QScriptValue fun = eng.newFunction(nativeFunctionThrowingError); |
|
774 eng.globalObject().setProperty("nativeFunctionThrowingError", fun); |
|
775 |
|
776 spy->clear(); |
|
777 eng.evaluate("nativeFunctionThrowingError('ciao')"); |
|
778 QCOMPARE(spy->count(), 6); |
|
779 |
|
780 // evaluate() entry |
|
781 QCOMPARE(spy->at(0).type, ScriptEngineEvent::FunctionEntry); |
|
782 |
|
783 // native function entry |
|
784 QCOMPARE(spy->at(1).type, ScriptEngineEvent::FunctionEntry); |
|
785 QCOMPARE(spy->at(1).scriptId, qint64(-1)); |
|
786 |
|
787 // Exception constructor entry |
|
788 QCOMPARE(spy->at(2).type, ScriptEngineEvent::FunctionEntry); |
|
789 QCOMPARE(spy->at(2).scriptId, qint64(-1)); |
|
790 |
|
791 // Exception constructor exit |
|
792 QCOMPARE(spy->at(3).type, ScriptEngineEvent::FunctionExit); |
|
793 QCOMPARE(spy->at(3).scriptId, qint64(-1)); |
|
794 QVERIFY(spy->at(3).value.isError()); |
|
795 |
|
796 // native function exit |
|
797 QCOMPARE(spy->at(4).type, ScriptEngineEvent::FunctionExit); |
|
798 QCOMPARE(spy->at(4).scriptId, qint64(-1)); |
|
799 QVERIFY(spy->at(4).value.isError()); |
|
800 |
|
801 // evaluate() exit |
|
802 QCOMPARE(spy->at(5).type, ScriptEngineEvent::FunctionExit); |
|
803 QCOMPARE(spy->at(5).scriptId, spy->at(0).scriptId); |
|
804 QVERIFY(spy->at(5).value.isError()); |
|
805 } |
|
806 delete spy; |
|
807 } |
|
808 |
|
809 /** check behaiviour of built-in function */ |
|
810 void tst_QScriptEngineAgent::functionEntryAndExit_builtin() |
|
811 { |
|
812 QScriptEngine eng; |
|
813 ScriptEngineSpy *spy = new ScriptEngineSpy(&eng, ~(ScriptEngineSpy::IgnoreFunctionEntry |
|
814 | ScriptEngineSpy::IgnoreFunctionExit)); |
|
815 { |
|
816 spy->clear(); |
|
817 eng.evaluate("'ciao'.toString()"); |
|
818 |
|
819 if (qt_script_isJITEnabled()) |
|
820 QEXPECT_FAIL("", "Some events are missing when JIT is enabled", Abort); |
|
821 QCOMPARE(spy->count(), 4); |
|
822 |
|
823 // evaluate() entry |
|
824 QCOMPARE(spy->at(0).type, ScriptEngineEvent::FunctionEntry); |
|
825 |
|
826 // built-in native function entry |
|
827 QCOMPARE(spy->at(1).type, ScriptEngineEvent::FunctionEntry); |
|
828 QCOMPARE(spy->at(1).scriptId, qint64(-1)); |
|
829 |
|
830 // built-in native function exit |
|
831 QCOMPARE(spy->at(2).type, ScriptEngineEvent::FunctionExit); |
|
832 QCOMPARE(spy->at(2).scriptId, qint64(-1)); |
|
833 QVERIFY(spy->at(2).value.isString()); |
|
834 QCOMPARE(spy->at(2).value.toString(), QString("ciao")); |
|
835 |
|
836 // evaluate() exit |
|
837 QCOMPARE(spy->at(3).type, ScriptEngineEvent::FunctionExit); |
|
838 QCOMPARE(spy->at(3).scriptId, spy->at(0).scriptId); |
|
839 QVERIFY(spy->at(3).value.isString()); |
|
840 QCOMPARE(spy->at(3).value.toString(), QString("ciao")); |
|
841 } |
|
842 delete spy; |
|
843 } |
|
844 |
|
845 /** check behaiviour of object creation*/ |
|
846 void tst_QScriptEngineAgent::functionEntryAndExit_objects() |
|
847 { |
|
848 QScriptEngine eng; |
|
849 ScriptEngineSpy *spy = new ScriptEngineSpy(&eng, ~(ScriptEngineSpy::IgnoreFunctionEntry |
|
850 | ScriptEngineSpy::IgnoreFunctionExit)); |
|
851 { |
|
852 spy->clear(); |
|
853 eng.evaluate("Array(); Boolean(); Date(); Function(); Number(); Object(); RegExp(); String()"); |
|
854 QCOMPARE(spy->count(), 18); |
|
855 |
|
856 // evaluate() entry |
|
857 QCOMPARE(spy->at(0).type, ScriptEngineEvent::FunctionEntry); |
|
858 |
|
859 // Array constructor entry |
|
860 QCOMPARE(spy->at(1).type, ScriptEngineEvent::FunctionEntry); |
|
861 QCOMPARE(spy->at(1).scriptId, qint64(-1)); |
|
862 |
|
863 // Array constructor exit |
|
864 QCOMPARE(spy->at(2).type, ScriptEngineEvent::FunctionExit); |
|
865 QCOMPARE(spy->at(2).scriptId, qint64(-1)); |
|
866 QVERIFY(spy->at(2).value.isArray()); |
|
867 |
|
868 // Boolean constructor entry |
|
869 QCOMPARE(spy->at(3).type, ScriptEngineEvent::FunctionEntry); |
|
870 QCOMPARE(spy->at(3).scriptId, qint64(-1)); |
|
871 |
|
872 // Boolean constructor exit |
|
873 QCOMPARE(spy->at(4).type, ScriptEngineEvent::FunctionExit); |
|
874 QCOMPARE(spy->at(4).scriptId, qint64(-1)); |
|
875 QVERIFY(spy->at(4).value.isBoolean()); |
|
876 |
|
877 // Date constructor entry |
|
878 QCOMPARE(spy->at(5).type, ScriptEngineEvent::FunctionEntry); |
|
879 QCOMPARE(spy->at(5).scriptId, qint64(-1)); |
|
880 |
|
881 // Date constructor exit |
|
882 QCOMPARE(spy->at(6).type, ScriptEngineEvent::FunctionExit); |
|
883 QCOMPARE(spy->at(6).scriptId, qint64(-1)); |
|
884 QVERIFY(spy->at(6).value.isString()); |
|
885 |
|
886 // Function constructor entry |
|
887 QCOMPARE(spy->at(7).type, ScriptEngineEvent::FunctionEntry); |
|
888 QCOMPARE(spy->at(7).scriptId, qint64(-1)); |
|
889 |
|
890 // Function constructor exit |
|
891 QCOMPARE(spy->at(8).type, ScriptEngineEvent::FunctionExit); |
|
892 QCOMPARE(spy->at(8).scriptId, qint64(-1)); |
|
893 QVERIFY(spy->at(8).value.isFunction()); |
|
894 |
|
895 // Number constructor entry |
|
896 QCOMPARE(spy->at(9).type, ScriptEngineEvent::FunctionEntry); |
|
897 QCOMPARE(spy->at(9).scriptId, qint64(-1)); |
|
898 |
|
899 // Number constructor exit |
|
900 QCOMPARE(spy->at(10).type, ScriptEngineEvent::FunctionExit); |
|
901 QCOMPARE(spy->at(10).scriptId, qint64(-1)); |
|
902 QVERIFY(spy->at(10).value.isNumber()); |
|
903 |
|
904 // Object constructor entry |
|
905 QCOMPARE(spy->at(11).type, ScriptEngineEvent::FunctionEntry); |
|
906 QCOMPARE(spy->at(11).scriptId, qint64(-1)); |
|
907 |
|
908 // Object constructor exit |
|
909 QCOMPARE(spy->at(12).type, ScriptEngineEvent::FunctionExit); |
|
910 QCOMPARE(spy->at(12).scriptId, qint64(-1)); |
|
911 QVERIFY(spy->at(12).value.isObject()); |
|
912 |
|
913 // RegExp constructor entry |
|
914 QCOMPARE(spy->at(13).type, ScriptEngineEvent::FunctionEntry); |
|
915 QCOMPARE(spy->at(13).scriptId, qint64(-1)); |
|
916 |
|
917 // RegExp constructor exit |
|
918 QCOMPARE(spy->at(14).type, ScriptEngineEvent::FunctionExit); |
|
919 QCOMPARE(spy->at(14).scriptId, qint64(-1)); |
|
920 QVERIFY(spy->at(14).value.isRegExp()); |
|
921 |
|
922 // String constructor entry |
|
923 QCOMPARE(spy->at(15).type, ScriptEngineEvent::FunctionEntry); |
|
924 QCOMPARE(spy->at(15).scriptId, qint64(-1)); |
|
925 |
|
926 // String constructor exit |
|
927 QCOMPARE(spy->at(16).type, ScriptEngineEvent::FunctionExit); |
|
928 QCOMPARE(spy->at(16).scriptId, qint64(-1)); |
|
929 QVERIFY(spy->at(16).value.isString()); |
|
930 |
|
931 // evaluate() exit |
|
932 QCOMPARE(spy->at(17).type, ScriptEngineEvent::FunctionExit); |
|
933 QCOMPARE(spy->at(17).scriptId, spy->at(0).scriptId); |
|
934 QVERIFY(spy->at(17).value.isString()); |
|
935 QCOMPARE(spy->at(17).value.toString(), QString()); |
|
936 } |
|
937 delete spy; |
|
938 } |
|
939 |
|
940 /** check behaiviour of slots*/ |
|
941 void tst_QScriptEngineAgent::functionEntryAndExit_slots() |
|
942 { |
|
943 QScriptEngine eng; |
|
944 ScriptEngineSpy *spy = new ScriptEngineSpy(&eng, ~(ScriptEngineSpy::IgnoreFunctionEntry |
|
945 | ScriptEngineSpy::IgnoreFunctionExit)); |
|
946 // slots |
|
947 { |
|
948 eng.globalObject().setProperty("qobj", eng.newQObject(this)); |
|
949 spy->clear(); |
|
950 eng.evaluate("qobj.testSlot(123)"); |
|
951 QCOMPARE(spy->count(), 4); |
|
952 // evaluate() entry |
|
953 QCOMPARE(spy->at(0).type, ScriptEngineEvent::FunctionEntry); |
|
954 // testSlot() entry |
|
955 QCOMPARE(spy->at(1).type, ScriptEngineEvent::FunctionEntry); |
|
956 QCOMPARE(spy->at(1).scriptId, qint64(-1)); |
|
957 // testSlot() exit |
|
958 QCOMPARE(spy->at(2).type, ScriptEngineEvent::FunctionExit); |
|
959 QCOMPARE(spy->at(2).scriptId, qint64(-1)); |
|
960 QVERIFY(spy->at(2).value.isNumber()); |
|
961 QCOMPARE(spy->at(2).value.toNumber(), qsreal(123)); |
|
962 // evaluate() exit |
|
963 QCOMPARE(spy->at(3).type, ScriptEngineEvent::FunctionExit); |
|
964 } |
|
965 delete spy; |
|
966 } |
|
967 |
|
968 /** check behaiviour of property accessors*/ |
|
969 void tst_QScriptEngineAgent::functionEntryAndExit_property_set() |
|
970 { |
|
971 QScriptEngine eng; |
|
972 ScriptEngineSpy *spy = new ScriptEngineSpy(&eng, ~(ScriptEngineSpy::IgnoreFunctionEntry |
|
973 | ScriptEngineSpy::IgnoreFunctionExit)); |
|
974 // property accessors |
|
975 { |
|
976 eng.globalObject().setProperty("qobj", eng.newQObject(this)); |
|
977 // set |
|
978 spy->clear(); |
|
979 eng.evaluate("qobj.testProperty = 456"); |
|
980 QCOMPARE(spy->count(), 4); |
|
981 // evaluate() entry |
|
982 QCOMPARE(spy->at(0).type, ScriptEngineEvent::FunctionEntry); |
|
983 // setTestProperty() entry |
|
984 QCOMPARE(spy->at(1).type, ScriptEngineEvent::FunctionEntry); |
|
985 QCOMPARE(spy->at(1).scriptId, qint64(-1)); |
|
986 // setTestProperty() exit |
|
987 QCOMPARE(spy->at(2).type, ScriptEngineEvent::FunctionExit); |
|
988 QCOMPARE(spy->at(2).scriptId, qint64(-1)); |
|
989 QVERIFY(spy->at(2).value.isNumber()); |
|
990 QCOMPARE(spy->at(2).value.toNumber(), testProperty()); |
|
991 // evaluate() exit |
|
992 QCOMPARE(spy->at(3).type, ScriptEngineEvent::FunctionExit); |
|
993 QVERIFY(spy->at(3).value.strictlyEquals(spy->at(2).value)); |
|
994 } |
|
995 delete spy; |
|
996 } |
|
997 |
|
998 /** check behaiviour of property accessors*/ |
|
999 void tst_QScriptEngineAgent::functionEntryAndExit_property_get() |
|
1000 { |
|
1001 QScriptEngine eng; |
|
1002 ScriptEngineSpy *spy = new ScriptEngineSpy(&eng, ~(ScriptEngineSpy::IgnoreFunctionEntry |
|
1003 | ScriptEngineSpy::IgnoreFunctionExit)); |
|
1004 // property accessors |
|
1005 { |
|
1006 eng.globalObject().setProperty("qobj", eng.newQObject(this)); |
|
1007 // set |
|
1008 eng.evaluate("qobj.testProperty = 456"); |
|
1009 // get |
|
1010 spy->clear(); |
|
1011 eng.evaluate("qobj.testProperty"); |
|
1012 QCOMPARE(spy->count(), 4); |
|
1013 // evaluate() entry |
|
1014 QCOMPARE(spy->at(0).type, ScriptEngineEvent::FunctionEntry); |
|
1015 // testProperty() entry |
|
1016 QCOMPARE(spy->at(1).type, ScriptEngineEvent::FunctionEntry); |
|
1017 QCOMPARE(spy->at(1).scriptId, qint64(-1)); |
|
1018 // testProperty() exit |
|
1019 QCOMPARE(spy->at(2).type, ScriptEngineEvent::FunctionExit); |
|
1020 QCOMPARE(spy->at(2).scriptId, qint64(-1)); |
|
1021 QVERIFY(spy->at(2).value.isNumber()); |
|
1022 QCOMPARE(spy->at(2).value.toNumber(), testProperty()); |
|
1023 // evaluate() exit |
|
1024 QCOMPARE(spy->at(3).type, ScriptEngineEvent::FunctionExit); |
|
1025 QVERIFY(spy->at(3).value.strictlyEquals(spy->at(2).value)); |
|
1026 } |
|
1027 delete spy; |
|
1028 } |
|
1029 |
|
1030 |
|
1031 /** check behaiviour of calling script functions from c++*/ |
|
1032 void tst_QScriptEngineAgent::functionEntryAndExit_call() |
|
1033 { |
|
1034 QScriptEngine eng; |
|
1035 ScriptEngineSpy *spy = new ScriptEngineSpy(&eng, ~(ScriptEngineSpy::IgnoreFunctionEntry |
|
1036 | ScriptEngineSpy::IgnoreFunctionExit)); |
|
1037 // calling script functions from C++ |
|
1038 |
|
1039 { |
|
1040 QScriptValue fun = eng.evaluate("function foo() { return 123; }; foo"); |
|
1041 QVERIFY(fun.isFunction()); |
|
1042 |
|
1043 spy->clear(); |
|
1044 fun.call(); |
|
1045 QCOMPARE(spy->count(), 2); |
|
1046 |
|
1047 // entry |
|
1048 QCOMPARE(spy->at(0).type, ScriptEngineEvent::FunctionEntry); |
|
1049 QVERIFY(spy->at(0).scriptId != -1); |
|
1050 |
|
1051 // exit |
|
1052 QCOMPARE(spy->at(1).type, ScriptEngineEvent::FunctionExit); |
|
1053 QCOMPARE(spy->at(1).scriptId, spy->at(0).scriptId); |
|
1054 QVERIFY(spy->at(1).value.isNumber()); |
|
1055 QCOMPARE(spy->at(1).value.toNumber(), qsreal(123)); |
|
1056 } |
|
1057 delete spy; |
|
1058 } |
|
1059 |
|
1060 /** check behaiviour of native function returnning arg*/ |
|
1061 void tst_QScriptEngineAgent::functionEntryAndExit_functionReturn_call() |
|
1062 { |
|
1063 QScriptEngine eng; |
|
1064 ScriptEngineSpy *spy = new ScriptEngineSpy(&eng, ~(ScriptEngineSpy::IgnoreFunctionEntry |
|
1065 | ScriptEngineSpy::IgnoreFunctionExit)); |
|
1066 { |
|
1067 QScriptValue fun = eng.newFunction(nativeFunctionReturningArg); |
|
1068 |
|
1069 spy->clear(); |
|
1070 QScriptValueList args; |
|
1071 args << QScriptValue(&eng, 123); |
|
1072 fun.call(QScriptValue(), args); |
|
1073 QCOMPARE(spy->count(), 2); |
|
1074 |
|
1075 // entry |
|
1076 QCOMPARE(spy->at(0).type, ScriptEngineEvent::FunctionEntry); |
|
1077 QVERIFY(spy->at(0).scriptId == -1); |
|
1078 |
|
1079 // exit |
|
1080 QCOMPARE(spy->at(1).type, ScriptEngineEvent::FunctionExit); |
|
1081 QCOMPARE(spy->at(1).scriptId, spy->at(0).scriptId); |
|
1082 QVERIFY(spy->at(1).value.strictlyEquals(args.at(0))); |
|
1083 } |
|
1084 delete spy; |
|
1085 } |
|
1086 |
|
1087 void tst_QScriptEngineAgent::functionEntryAndExit_functionReturn_construct() |
|
1088 { |
|
1089 QScriptEngine eng; |
|
1090 ScriptEngineSpy *spy = new ScriptEngineSpy(&eng, ~(ScriptEngineSpy::IgnoreFunctionEntry |
|
1091 | ScriptEngineSpy::IgnoreFunctionExit)); |
|
1092 { |
|
1093 QScriptValue fun = eng.newFunction(nativeFunctionReturningArg); |
|
1094 |
|
1095 spy->clear(); |
|
1096 QScriptValueList args; |
|
1097 args << QScriptValue(&eng, 123); |
|
1098 QScriptValue obj = fun.construct(args); |
|
1099 |
|
1100 QVERIFY(args.at(0).isValid()); |
|
1101 QVERIFY(args.at(0).isNumber()); |
|
1102 QVERIFY(args.at(0).toNumber() == 123); |
|
1103 |
|
1104 QCOMPARE(spy->count(), 2); |
|
1105 |
|
1106 // entry |
|
1107 QCOMPARE(spy->at(0).type, ScriptEngineEvent::FunctionEntry); |
|
1108 QVERIFY(spy->at(0).scriptId == -1); |
|
1109 |
|
1110 // exit |
|
1111 QCOMPARE(spy->at(1).type, ScriptEngineEvent::FunctionExit); |
|
1112 QCOMPARE(spy->at(1).scriptId, spy->at(0).scriptId); |
|
1113 |
|
1114 QVERIFY(spy->at(1).value.strictlyEquals(args.at(0))); |
|
1115 } |
|
1116 |
|
1117 delete spy; |
|
1118 } |
|
1119 |
|
1120 /** check behaiviour of object creation with args (?)*/ |
|
1121 void tst_QScriptEngineAgent::functionEntryAndExit_objectCall() |
|
1122 { |
|
1123 QScriptEngine eng; |
|
1124 ScriptEngineSpy *spy = new ScriptEngineSpy(&eng, ~(ScriptEngineSpy::IgnoreFunctionEntry |
|
1125 | ScriptEngineSpy::IgnoreFunctionExit)); |
|
1126 for (int x = 0; x < 2; ++x) { |
|
1127 QScriptValue fun = eng.evaluate("Boolean"); |
|
1128 |
|
1129 QVERIFY(!fun.isError()); |
|
1130 |
|
1131 spy->clear(); |
|
1132 QScriptValueList args; |
|
1133 args << QScriptValue(&eng, true); |
|
1134 if (x) |
|
1135 fun.construct(args); |
|
1136 else |
|
1137 fun.call(QScriptValue(), args); |
|
1138 QCOMPARE(spy->count(), 2); |
|
1139 |
|
1140 // entry |
|
1141 QCOMPARE(spy->at(0).type, ScriptEngineEvent::FunctionEntry); |
|
1142 QVERIFY(spy->at(0).scriptId == -1); |
|
1143 |
|
1144 // exit |
|
1145 QCOMPARE(spy->at(1).type, ScriptEngineEvent::FunctionExit); |
|
1146 QCOMPARE(spy->at(1).scriptId, spy->at(0).scriptId); |
|
1147 QVERIFY(spy->at(1).value.equals(args.at(0))); |
|
1148 } |
|
1149 delete spy; |
|
1150 } |
|
1151 |
|
1152 void tst_QScriptEngineAgent::positionChange_1() |
|
1153 { |
|
1154 QScriptEngine eng; |
|
1155 ScriptEngineSpy *spy = new ScriptEngineSpy(&eng, ~(ScriptEngineSpy::IgnorePositionChange)); |
|
1156 { |
|
1157 spy->clear(); |
|
1158 eng.evaluate(";"); |
|
1159 QEXPECT_FAIL("","JSC do not evaluate ';' to statemant",Continue); |
|
1160 QCOMPARE(spy->count(), 1); |
|
1161 if (spy->count()) { |
|
1162 QEXPECT_FAIL("","JSC do not evaluate ';' to statemant",Continue); |
|
1163 QCOMPARE(spy->at(0).type, ScriptEngineEvent::PositionChange); |
|
1164 QEXPECT_FAIL("","JSC do not evaluate ';' to statemant",Continue); |
|
1165 QVERIFY(spy->at(0).scriptId != -1); |
|
1166 QEXPECT_FAIL("","JSC do not evaluate ';' to statemant",Continue); |
|
1167 QCOMPARE(spy->at(0).lineNumber, 1); |
|
1168 QEXPECT_FAIL("","JSC do not evaluate ';' to statemant",Continue); |
|
1169 QCOMPARE(spy->at(0).columnNumber, 1); |
|
1170 } |
|
1171 } |
|
1172 |
|
1173 { |
|
1174 spy->clear(); |
|
1175 int lineNumber = 123; |
|
1176 eng.evaluate("1 + 2", "foo.qs", lineNumber); |
|
1177 QCOMPARE(spy->count(), 1); |
|
1178 |
|
1179 QCOMPARE(spy->at(0).type, ScriptEngineEvent::PositionChange); |
|
1180 QVERIFY(spy->at(0).scriptId != -1); |
|
1181 QCOMPARE(spy->at(0).lineNumber, lineNumber); |
|
1182 QCOMPARE(spy->at(0).columnNumber, 1); |
|
1183 } |
|
1184 |
|
1185 { |
|
1186 spy->clear(); |
|
1187 int lineNumber = 123; |
|
1188 eng.evaluate("var i = 0", "foo.qs", lineNumber); |
|
1189 QCOMPARE(spy->count(), 1); |
|
1190 |
|
1191 QCOMPARE(spy->at(0).type, ScriptEngineEvent::PositionChange); |
|
1192 QVERIFY(spy->at(0).scriptId != -1); |
|
1193 QCOMPARE(spy->at(0).lineNumber, lineNumber); |
|
1194 QCOMPARE(spy->at(0).columnNumber, 1); |
|
1195 } |
|
1196 |
|
1197 QStringList lineTerminators; |
|
1198 lineTerminators << "\n" << "\r" << "\n\r" << "\r\n"; |
|
1199 for (int i = 0; i < lineTerminators.size(); ++i) { |
|
1200 spy->clear(); |
|
1201 int lineNumber = 456; |
|
1202 QString code = "1 + 2; 3 + 4;"; |
|
1203 code.append(lineTerminators.at(i)); |
|
1204 code.append("5 + 6"); |
|
1205 eng.evaluate(code, "foo.qs", lineNumber); |
|
1206 QCOMPARE(spy->count(), 3); |
|
1207 |
|
1208 // 1 + 2 |
|
1209 QCOMPARE(spy->at(0).type, ScriptEngineEvent::PositionChange); |
|
1210 QVERIFY(spy->at(0).scriptId != -1); |
|
1211 QCOMPARE(spy->at(0).lineNumber, lineNumber); |
|
1212 QCOMPARE(spy->at(0).columnNumber, 1); |
|
1213 |
|
1214 // 3 + 4 |
|
1215 QCOMPARE(spy->at(1).type, ScriptEngineEvent::PositionChange); |
|
1216 QCOMPARE(spy->at(1).scriptId, spy->at(0).scriptId); |
|
1217 QCOMPARE(spy->at(1).lineNumber, lineNumber); |
|
1218 QCOMPARE(spy->at(1).columnNumber, 8); |
|
1219 |
|
1220 // 5 + 6 |
|
1221 QCOMPARE(spy->at(2).type, ScriptEngineEvent::PositionChange); |
|
1222 QCOMPARE(spy->at(2).scriptId, spy->at(0).scriptId); |
|
1223 QCOMPARE(spy->at(2).lineNumber, lineNumber + 1); |
|
1224 QCOMPARE(spy->at(2).columnNumber, 1); |
|
1225 } |
|
1226 delete spy; |
|
1227 } |
|
1228 |
|
1229 void tst_QScriptEngineAgent::positionChange_2() |
|
1230 { |
|
1231 QScriptEngine eng; |
|
1232 ScriptEngineSpy *spy = new ScriptEngineSpy(&eng, ~(ScriptEngineSpy::IgnorePositionChange)); |
|
1233 { |
|
1234 spy->clear(); |
|
1235 int lineNumber = 789; |
|
1236 eng.evaluate("function foo() { return 123; }", "foo.qs", lineNumber); |
|
1237 QCOMPARE(spy->count(), 0); |
|
1238 |
|
1239 eng.evaluate("foo()"); |
|
1240 QCOMPARE(spy->count(), 2); |
|
1241 |
|
1242 // foo() |
|
1243 QCOMPARE(spy->at(0).type, ScriptEngineEvent::PositionChange); |
|
1244 QVERIFY(spy->at(0).scriptId != -1); |
|
1245 QCOMPARE(spy->at(0).lineNumber, 1); |
|
1246 QCOMPARE(spy->at(0).columnNumber, 1); |
|
1247 |
|
1248 // return 123 |
|
1249 QCOMPARE(spy->at(1).type, ScriptEngineEvent::PositionChange); |
|
1250 QVERIFY(spy->at(1).scriptId != spy->at(0).scriptId); |
|
1251 QCOMPARE(spy->at(1).lineNumber, lineNumber); |
|
1252 QCOMPARE(spy->at(1).columnNumber, 18); |
|
1253 } |
|
1254 |
|
1255 { |
|
1256 spy->clear(); |
|
1257 eng.evaluate("if (true) i = 1; else i = 0;"); |
|
1258 QCOMPARE(spy->count(), 2); |
|
1259 |
|
1260 // if |
|
1261 QCOMPARE(spy->at(0).type, ScriptEngineEvent::PositionChange); |
|
1262 QVERIFY(spy->at(0).scriptId != -1); |
|
1263 QCOMPARE(spy->at(0).lineNumber, 1); |
|
1264 QCOMPARE(spy->at(0).columnNumber, 1); |
|
1265 |
|
1266 // i = 1 |
|
1267 QCOMPARE(spy->at(1).type, ScriptEngineEvent::PositionChange); |
|
1268 QCOMPARE(spy->at(1).scriptId, spy->at(0).scriptId); |
|
1269 QCOMPARE(spy->at(1).lineNumber, 1); |
|
1270 QCOMPARE(spy->at(1).columnNumber, 11); |
|
1271 } |
|
1272 |
|
1273 { |
|
1274 spy->clear(); |
|
1275 eng.evaluate("for (var i = 0; i < 2; ++i) { }"); |
|
1276 QCOMPARE(spy->count(), 1); |
|
1277 |
|
1278 // for |
|
1279 QCOMPARE(spy->at(0).type, ScriptEngineEvent::PositionChange); |
|
1280 QVERIFY(spy->at(0).scriptId != -1); |
|
1281 QCOMPARE(spy->at(0).lineNumber, 1); |
|
1282 QCOMPARE(spy->at(0).columnNumber, 1); |
|
1283 } |
|
1284 |
|
1285 { |
|
1286 spy->clear(); |
|
1287 eng.evaluate("for (var i = 0; i < 2; ++i) { void(i); }"); |
|
1288 QCOMPARE(spy->count(), 3); |
|
1289 |
|
1290 // for |
|
1291 QCOMPARE(spy->at(0).type, ScriptEngineEvent::PositionChange); |
|
1292 QVERIFY(spy->at(0).scriptId != -1); |
|
1293 QCOMPARE(spy->at(0).lineNumber, 1); |
|
1294 QCOMPARE(spy->at(0).columnNumber, 1); |
|
1295 |
|
1296 // void(i) |
|
1297 QCOMPARE(spy->at(1).type, ScriptEngineEvent::PositionChange); |
|
1298 QCOMPARE(spy->at(1).scriptId, spy->at(0).scriptId); |
|
1299 QCOMPARE(spy->at(1).lineNumber, 1); |
|
1300 QCOMPARE(spy->at(1).columnNumber, 31); |
|
1301 |
|
1302 // void(i) |
|
1303 QCOMPARE(spy->at(2).type, ScriptEngineEvent::PositionChange); |
|
1304 QCOMPARE(spy->at(2).scriptId, spy->at(0).scriptId); |
|
1305 QCOMPARE(spy->at(2).lineNumber, 1); |
|
1306 QCOMPARE(spy->at(2).columnNumber, 31); |
|
1307 } |
|
1308 |
|
1309 { |
|
1310 spy->clear(); |
|
1311 eng.evaluate("var i = 0; while (i < 2) { ++i; }"); |
|
1312 QCOMPARE(spy->count(), 4); |
|
1313 |
|
1314 // i = 0 |
|
1315 QCOMPARE(spy->at(0).type, ScriptEngineEvent::PositionChange); |
|
1316 QVERIFY(spy->at(0).scriptId != -1); |
|
1317 QCOMPARE(spy->at(0).lineNumber, 1); |
|
1318 QCOMPARE(spy->at(0).columnNumber, 1); |
|
1319 |
|
1320 // while |
|
1321 QCOMPARE(spy->at(1).type, ScriptEngineEvent::PositionChange); |
|
1322 QCOMPARE(spy->at(1).scriptId, spy->at(0).scriptId); |
|
1323 QCOMPARE(spy->at(1).lineNumber, 1); |
|
1324 QCOMPARE(spy->at(1).columnNumber, 12); |
|
1325 |
|
1326 // ++i |
|
1327 QCOMPARE(spy->at(2).type, ScriptEngineEvent::PositionChange); |
|
1328 QCOMPARE(spy->at(2).scriptId, spy->at(0).scriptId); |
|
1329 QCOMPARE(spy->at(2).lineNumber, 1); |
|
1330 QCOMPARE(spy->at(2).columnNumber, 28); |
|
1331 |
|
1332 // ++i |
|
1333 QCOMPARE(spy->at(3).type, ScriptEngineEvent::PositionChange); |
|
1334 QCOMPARE(spy->at(3).scriptId, spy->at(0).scriptId); |
|
1335 QCOMPARE(spy->at(3).lineNumber, 1); |
|
1336 QCOMPARE(spy->at(3).columnNumber, 28); |
|
1337 } |
|
1338 |
|
1339 { |
|
1340 spy->clear(); |
|
1341 eng.evaluate("var i = 0; do { ++i; } while (i < 2)"); |
|
1342 QCOMPARE(spy->count(), 5); |
|
1343 |
|
1344 // i = 0 |
|
1345 QCOMPARE(spy->at(0).type, ScriptEngineEvent::PositionChange); |
|
1346 QVERIFY(spy->at(0).scriptId != -1); |
|
1347 QCOMPARE(spy->at(0).lineNumber, 1); |
|
1348 QCOMPARE(spy->at(0).columnNumber, 1); |
|
1349 |
|
1350 // do |
|
1351 QCOMPARE(spy->at(1).type, ScriptEngineEvent::PositionChange); |
|
1352 QCOMPARE(spy->at(1).scriptId, spy->at(0).scriptId); |
|
1353 QCOMPARE(spy->at(1).lineNumber, 1); |
|
1354 QCOMPARE(spy->at(1).columnNumber, 12); |
|
1355 |
|
1356 // ++i |
|
1357 QCOMPARE(spy->at(2).type, ScriptEngineEvent::PositionChange); |
|
1358 QCOMPARE(spy->at(2).scriptId, spy->at(0).scriptId); |
|
1359 QCOMPARE(spy->at(2).lineNumber, 1); |
|
1360 QCOMPARE(spy->at(2).columnNumber, 17); |
|
1361 |
|
1362 // do |
|
1363 QCOMPARE(spy->at(3).type, ScriptEngineEvent::PositionChange); |
|
1364 QCOMPARE(spy->at(3).scriptId, spy->at(0).scriptId); |
|
1365 QCOMPARE(spy->at(3).lineNumber, 1); |
|
1366 QCOMPARE(spy->at(3).columnNumber, 12); |
|
1367 |
|
1368 // ++i |
|
1369 QCOMPARE(spy->at(4).type, ScriptEngineEvent::PositionChange); |
|
1370 QCOMPARE(spy->at(4).scriptId, spy->at(0).scriptId); |
|
1371 QCOMPARE(spy->at(4).lineNumber, 1); |
|
1372 QCOMPARE(spy->at(4).columnNumber, 17); |
|
1373 } |
|
1374 |
|
1375 { |
|
1376 spy->clear(); |
|
1377 eng.evaluate("for (var i in { }) { void(i); }"); |
|
1378 QCOMPARE(spy->count(), 1); |
|
1379 |
|
1380 // for |
|
1381 QCOMPARE(spy->at(0).type, ScriptEngineEvent::PositionChange); |
|
1382 QVERIFY(spy->at(0).scriptId != -1); |
|
1383 QCOMPARE(spy->at(0).lineNumber, 1); |
|
1384 QCOMPARE(spy->at(0).columnNumber, 1); |
|
1385 } |
|
1386 |
|
1387 { |
|
1388 spy->clear(); |
|
1389 eng.evaluate("for ( ; ; ) { break; }"); |
|
1390 QCOMPARE(spy->count(), 2); |
|
1391 |
|
1392 // for |
|
1393 QCOMPARE(spy->at(0).type, ScriptEngineEvent::PositionChange); |
|
1394 QVERIFY(spy->at(0).scriptId != -1); |
|
1395 QCOMPARE(spy->at(0).lineNumber, 1); |
|
1396 QCOMPARE(spy->at(0).columnNumber, 1); |
|
1397 |
|
1398 // break |
|
1399 QCOMPARE(spy->at(1).type, ScriptEngineEvent::PositionChange); |
|
1400 QCOMPARE(spy->at(1).scriptId, spy->at(0).scriptId); |
|
1401 QCOMPARE(spy->at(1).lineNumber, 1); |
|
1402 QCOMPARE(spy->at(1).columnNumber, 15); |
|
1403 } |
|
1404 |
|
1405 { |
|
1406 spy->clear(); |
|
1407 eng.evaluate("for (var i = 0 ; i < 2; ++i) { continue; }"); |
|
1408 QCOMPARE(spy->count(), 3); |
|
1409 |
|
1410 // for |
|
1411 QCOMPARE(spy->at(0).type, ScriptEngineEvent::PositionChange); |
|
1412 QVERIFY(spy->at(0).scriptId != -1); |
|
1413 QCOMPARE(spy->at(0).lineNumber, 1); |
|
1414 QCOMPARE(spy->at(0).columnNumber, 1); |
|
1415 |
|
1416 // continue |
|
1417 QCOMPARE(spy->at(1).type, ScriptEngineEvent::PositionChange); |
|
1418 QCOMPARE(spy->at(1).scriptId, spy->at(0).scriptId); |
|
1419 QCOMPARE(spy->at(1).lineNumber, 1); |
|
1420 QCOMPARE(spy->at(1).columnNumber, 32); |
|
1421 |
|
1422 // continue |
|
1423 QCOMPARE(spy->at(2).type, ScriptEngineEvent::PositionChange); |
|
1424 QCOMPARE(spy->at(2).scriptId, spy->at(0).scriptId); |
|
1425 QCOMPARE(spy->at(2).lineNumber, 1); |
|
1426 QCOMPARE(spy->at(2).columnNumber, 32); |
|
1427 } |
|
1428 |
|
1429 { |
|
1430 spy->clear(); |
|
1431 eng.evaluate("with (this) { }"); |
|
1432 QCOMPARE(spy->count(), 1); |
|
1433 |
|
1434 // with |
|
1435 QCOMPARE(spy->at(0).type, ScriptEngineEvent::PositionChange); |
|
1436 QVERIFY(spy->at(0).scriptId != -1); |
|
1437 QCOMPARE(spy->at(0).lineNumber, 1); |
|
1438 QCOMPARE(spy->at(0).columnNumber, 1); |
|
1439 } |
|
1440 |
|
1441 { |
|
1442 spy->clear(); |
|
1443 eng.evaluate("switch (undefined) { }"); |
|
1444 QCOMPARE(spy->count(), 1); |
|
1445 |
|
1446 // switch |
|
1447 QCOMPARE(spy->at(0).type, ScriptEngineEvent::PositionChange); |
|
1448 QVERIFY(spy->at(0).scriptId != -1); |
|
1449 QCOMPARE(spy->at(0).lineNumber, 1); |
|
1450 QCOMPARE(spy->at(0).columnNumber, 1); |
|
1451 } |
|
1452 |
|
1453 { |
|
1454 spy->clear(); |
|
1455 eng.evaluate("switch (undefined) { default: i = 5; }"); |
|
1456 QCOMPARE(spy->count(), 2); |
|
1457 |
|
1458 // switch |
|
1459 QCOMPARE(spy->at(0).type, ScriptEngineEvent::PositionChange); |
|
1460 QVERIFY(spy->at(0).scriptId != -1); |
|
1461 QCOMPARE(spy->at(0).lineNumber, 1); |
|
1462 QCOMPARE(spy->at(0).columnNumber, 1); |
|
1463 |
|
1464 // i = 5 |
|
1465 QCOMPARE(spy->at(1).type, ScriptEngineEvent::PositionChange); |
|
1466 QCOMPARE(spy->at(1).scriptId, spy->at(0).scriptId); |
|
1467 QCOMPARE(spy->at(1).lineNumber, 1); |
|
1468 QCOMPARE(spy->at(1).columnNumber, 31); |
|
1469 } |
|
1470 |
|
1471 { |
|
1472 spy->clear(); |
|
1473 eng.evaluate("switch (undefined) { case undefined: i = 5; break; }"); |
|
1474 QCOMPARE(spy->count(), 3); |
|
1475 |
|
1476 // switch |
|
1477 QCOMPARE(spy->at(0).type, ScriptEngineEvent::PositionChange); |
|
1478 QVERIFY(spy->at(0).scriptId != -1); |
|
1479 QCOMPARE(spy->at(0).lineNumber, 1); |
|
1480 QCOMPARE(spy->at(0).columnNumber, 1); |
|
1481 |
|
1482 // i = 5 |
|
1483 QCOMPARE(spy->at(1).type, ScriptEngineEvent::PositionChange); |
|
1484 QCOMPARE(spy->at(1).scriptId, spy->at(0).scriptId); |
|
1485 QCOMPARE(spy->at(1).lineNumber, 1); |
|
1486 QCOMPARE(spy->at(1).columnNumber, 38); |
|
1487 |
|
1488 // break |
|
1489 QCOMPARE(spy->at(2).type, ScriptEngineEvent::PositionChange); |
|
1490 QCOMPARE(spy->at(2).scriptId, spy->at(0).scriptId); |
|
1491 QCOMPARE(spy->at(2).lineNumber, 1); |
|
1492 QCOMPARE(spy->at(2).columnNumber, 45); |
|
1493 } |
|
1494 |
|
1495 { |
|
1496 spy->clear(); |
|
1497 eng.evaluate("throw 1"); |
|
1498 QCOMPARE(spy->count(), 1); |
|
1499 |
|
1500 // throw |
|
1501 QCOMPARE(spy->at(0).type, ScriptEngineEvent::PositionChange); |
|
1502 QVERIFY(spy->at(0).scriptId != -1); |
|
1503 QCOMPARE(spy->at(0).lineNumber, 1); |
|
1504 QCOMPARE(spy->at(0).columnNumber, 1); |
|
1505 } |
|
1506 |
|
1507 { |
|
1508 spy->clear(); |
|
1509 eng.evaluate("try { throw 1; } catch(e) { i = e; } finally { i = 2; }"); |
|
1510 QCOMPARE(spy->count(), 3); |
|
1511 |
|
1512 // throw 1 |
|
1513 QCOMPARE(spy->at(0).type, ScriptEngineEvent::PositionChange); |
|
1514 QVERIFY(spy->at(0).scriptId != -1); |
|
1515 QCOMPARE(spy->at(0).lineNumber, 1); |
|
1516 QCOMPARE(spy->at(0).columnNumber, 7); |
|
1517 |
|
1518 // i = e |
|
1519 QCOMPARE(spy->at(1).type, ScriptEngineEvent::PositionChange); |
|
1520 QCOMPARE(spy->at(1).scriptId, spy->at(0).scriptId); |
|
1521 QCOMPARE(spy->at(1).lineNumber, 1); |
|
1522 QCOMPARE(spy->at(1).columnNumber, 29); |
|
1523 |
|
1524 // i = 2 |
|
1525 QCOMPARE(spy->at(2).type, ScriptEngineEvent::PositionChange); |
|
1526 QCOMPARE(spy->at(2).scriptId, spy->at(0).scriptId); |
|
1527 QCOMPARE(spy->at(2).lineNumber, 1); |
|
1528 QCOMPARE(spy->at(2).columnNumber, 48); |
|
1529 } |
|
1530 |
|
1531 { |
|
1532 spy->clear(); |
|
1533 eng.evaluate("try { i = 1; } catch(e) { i = 2; } finally { i = 3; }"); |
|
1534 QCOMPARE(spy->count(), 2); |
|
1535 |
|
1536 // i = 1 |
|
1537 QCOMPARE(spy->at(0).type, ScriptEngineEvent::PositionChange); |
|
1538 QVERIFY(spy->at(0).scriptId != -1); |
|
1539 QCOMPARE(spy->at(0).lineNumber, 1); |
|
1540 QCOMPARE(spy->at(0).columnNumber, 7); |
|
1541 |
|
1542 // i = 3 |
|
1543 QCOMPARE(spy->at(1).type, ScriptEngineEvent::PositionChange); |
|
1544 QCOMPARE(spy->at(1).scriptId, spy->at(0).scriptId); |
|
1545 QCOMPARE(spy->at(1).lineNumber, 1); |
|
1546 QCOMPARE(spy->at(1).columnNumber, 46); |
|
1547 } |
|
1548 |
|
1549 { |
|
1550 QEXPECT_FAIL("","I believe the test is wrong. Expressions shouldn't call positionChange " |
|
1551 "because statement '1+2' will call it at least twice, why debugger have to " |
|
1552 "stop here so many times?", Abort); |
|
1553 spy->clear(); |
|
1554 eng.evaluate("c = {a: 10, b: 20}"); |
|
1555 QCOMPARE(spy->count(), 2); |
|
1556 |
|
1557 // a: 10 |
|
1558 QCOMPARE(spy->at(0).type, ScriptEngineEvent::PositionChange); |
|
1559 QVERIFY(spy->at(0).scriptId != -1); |
|
1560 QCOMPARE(spy->at(0).lineNumber, 1); |
|
1561 QCOMPARE(spy->at(0).columnNumber, 1); |
|
1562 |
|
1563 // b: 20 |
|
1564 QCOMPARE(spy->at(1).type, ScriptEngineEvent::PositionChange); |
|
1565 QCOMPARE(spy->at(1).scriptId, spy->at(0).scriptId); |
|
1566 QCOMPARE(spy->at(1).lineNumber, 1); |
|
1567 QCOMPARE(spy->at(1).columnNumber, 20); |
|
1568 } |
|
1569 delete spy; |
|
1570 } |
|
1571 |
|
1572 void tst_QScriptEngineAgent::exceptionThrowAndCatch() |
|
1573 { |
|
1574 QScriptEngine eng; |
|
1575 ScriptEngineSpy *spy = new ScriptEngineSpy(&eng, ~(ScriptEngineSpy::IgnoreExceptionThrow |
|
1576 | ScriptEngineSpy::IgnoreExceptionCatch)); |
|
1577 { |
|
1578 spy->clear(); |
|
1579 eng.evaluate(";"); |
|
1580 QCOMPARE(spy->count(), 0); |
|
1581 } |
|
1582 |
|
1583 { |
|
1584 spy->clear(); |
|
1585 eng.evaluate("try { i = 5; } catch (e) { }"); |
|
1586 QCOMPARE(spy->count(), 0); |
|
1587 } |
|
1588 |
|
1589 { |
|
1590 spy->clear(); |
|
1591 eng.evaluate("throw new Error('ciao');"); |
|
1592 QCOMPARE(spy->count(), 1); |
|
1593 |
|
1594 QCOMPARE(spy->at(0).type, ScriptEngineEvent::ExceptionThrow); |
|
1595 QVERIFY(spy->at(0).scriptId != -1); |
|
1596 QVERIFY(!spy->at(0).hasExceptionHandler); |
|
1597 QVERIFY(spy->at(0).value.isError()); |
|
1598 QCOMPARE(spy->at(0).value.toString(), QString("Error: ciao")); |
|
1599 } |
|
1600 |
|
1601 { |
|
1602 spy->clear(); |
|
1603 eng.evaluate("try { throw new Error('ciao'); } catch (e) { }"); |
|
1604 QCOMPARE(spy->count(), 2); |
|
1605 |
|
1606 QCOMPARE(spy->at(0).type, ScriptEngineEvent::ExceptionThrow); |
|
1607 QVERIFY(spy->at(0).scriptId != -1); |
|
1608 QVERIFY(spy->at(0).hasExceptionHandler); |
|
1609 QVERIFY(spy->at(0).value.isError()); |
|
1610 QCOMPARE(spy->at(0).value.toString(), QString("Error: ciao")); |
|
1611 QVERIFY(spy->at(0).scriptId != -1); |
|
1612 |
|
1613 QCOMPARE(spy->at(1).type, ScriptEngineEvent::ExceptionCatch); |
|
1614 QCOMPARE(spy->at(1).scriptId, spy->at(0).scriptId); |
|
1615 QVERIFY(spy->at(1).value.strictlyEquals(spy->at(0).value)); |
|
1616 } |
|
1617 } |
|
1618 |
|
1619 void tst_QScriptEngineAgent::eventOrder_assigment() |
|
1620 { |
|
1621 QScriptEngine eng; |
|
1622 ScriptEngineSpy *spy = new ScriptEngineSpy(&eng); |
|
1623 { |
|
1624 spy->clear(); |
|
1625 eng.evaluate("i = 3; i = 5"); |
|
1626 QCOMPARE(spy->count(), 6); |
|
1627 // load |
|
1628 QCOMPARE(spy->at(0).type, ScriptEngineEvent::ScriptLoad); |
|
1629 // evaluate() entry |
|
1630 QCOMPARE(spy->at(1).type, ScriptEngineEvent::FunctionEntry); |
|
1631 QCOMPARE(spy->at(1).scriptId, spy->at(0).scriptId); |
|
1632 // i = 3 |
|
1633 QCOMPARE(spy->at(2).type, ScriptEngineEvent::PositionChange); |
|
1634 QCOMPARE(spy->at(2).scriptId, spy->at(0).scriptId); |
|
1635 // i = 5 |
|
1636 QCOMPARE(spy->at(3).type, ScriptEngineEvent::PositionChange); |
|
1637 QCOMPARE(spy->at(3).scriptId, spy->at(0).scriptId); |
|
1638 // evaluate() exit |
|
1639 QCOMPARE(spy->at(4).type, ScriptEngineEvent::FunctionExit); |
|
1640 QCOMPARE(spy->at(4).scriptId, spy->at(0).scriptId); |
|
1641 // unload |
|
1642 QCOMPARE(spy->at(5).type, ScriptEngineEvent::ScriptUnload); |
|
1643 QCOMPARE(spy->at(5).scriptId, spy->at(0).scriptId); |
|
1644 } |
|
1645 delete spy; |
|
1646 } |
|
1647 |
|
1648 void tst_QScriptEngineAgent::eventOrder_functionDefinition() |
|
1649 { |
|
1650 QScriptEngine eng; |
|
1651 ScriptEngineSpy *spy = new ScriptEngineSpy(&eng); |
|
1652 { |
|
1653 spy->clear(); |
|
1654 eng.evaluate("function foo(arg) { void(arg); }"); |
|
1655 QCOMPARE(spy->count(), 3); |
|
1656 QCOMPARE(spy->at(0).type, ScriptEngineEvent::ScriptLoad); |
|
1657 QCOMPARE(spy->at(1).type, ScriptEngineEvent::FunctionEntry); |
|
1658 QCOMPARE(spy->at(2).type, ScriptEngineEvent::FunctionExit); |
|
1659 |
|
1660 eng.evaluate("foo(123)"); |
|
1661 QCOMPARE(spy->count(), 13); |
|
1662 // load |
|
1663 QCOMPARE(spy->at(3).type, ScriptEngineEvent::ScriptLoad); |
|
1664 QVERIFY(spy->at(3).scriptId != spy->at(0).scriptId); |
|
1665 // evaluate() entry |
|
1666 QCOMPARE(spy->at(4).type, ScriptEngineEvent::FunctionEntry); |
|
1667 QCOMPARE(spy->at(4).scriptId, spy->at(3).scriptId); |
|
1668 // foo() |
|
1669 QCOMPARE(spy->at(5).type, ScriptEngineEvent::PositionChange); |
|
1670 QCOMPARE(spy->at(5).scriptId, spy->at(3).scriptId); |
|
1671 // new context |
|
1672 QCOMPARE(spy->at(6).type, ScriptEngineEvent::ContextPush); |
|
1673 // foo() entry |
|
1674 QCOMPARE(spy->at(7).type, ScriptEngineEvent::FunctionEntry); |
|
1675 QCOMPARE(spy->at(7).scriptId, spy->at(0).scriptId); |
|
1676 // void(arg) |
|
1677 QCOMPARE(spy->at(8).type, ScriptEngineEvent::PositionChange); |
|
1678 QCOMPARE(spy->at(8).scriptId, spy->at(0).scriptId); |
|
1679 // foo() exit |
|
1680 QCOMPARE(spy->at(9).type, ScriptEngineEvent::FunctionExit); |
|
1681 QCOMPARE(spy->at(9).scriptId, spy->at(0).scriptId); |
|
1682 // restore context |
|
1683 QCOMPARE(spy->at(10).type, ScriptEngineEvent::ContextPop); |
|
1684 // evaluate() exit |
|
1685 QCOMPARE(spy->at(11).type, ScriptEngineEvent::FunctionExit); |
|
1686 QCOMPARE(spy->at(11).scriptId, spy->at(3).scriptId); |
|
1687 // unload |
|
1688 QCOMPARE(spy->at(12).type, ScriptEngineEvent::ScriptUnload); |
|
1689 QCOMPARE(spy->at(12).scriptId, spy->at(3).scriptId); |
|
1690 |
|
1691 eng.evaluate("foo = null"); |
|
1692 eng.collectGarbage(); |
|
1693 } |
|
1694 delete spy; |
|
1695 } |
|
1696 |
|
1697 void tst_QScriptEngineAgent::eventOrder_throwError() |
|
1698 { |
|
1699 QScriptEngine eng; |
|
1700 ScriptEngineSpy *spy = new ScriptEngineSpy(&eng); |
|
1701 { |
|
1702 spy->clear(); |
|
1703 eng.evaluate("throw new Error('ciao')"); |
|
1704 QCOMPARE(spy->count(), 10); |
|
1705 // load |
|
1706 QCOMPARE(spy->at(0).type, ScriptEngineEvent::ScriptLoad); |
|
1707 // evaluate() entry |
|
1708 QCOMPARE(spy->at(1).type, ScriptEngineEvent::FunctionEntry); |
|
1709 // throw |
|
1710 QCOMPARE(spy->at(2).type, ScriptEngineEvent::PositionChange); |
|
1711 // new context |
|
1712 QCOMPARE(spy->at(3).type, ScriptEngineEvent::ContextPush); |
|
1713 // Error constructor entry |
|
1714 QCOMPARE(spy->at(4).type, ScriptEngineEvent::FunctionEntry); |
|
1715 // Error constructor exit |
|
1716 QCOMPARE(spy->at(5).type, ScriptEngineEvent::FunctionExit); |
|
1717 // restore context |
|
1718 QCOMPARE(spy->at(6).type, ScriptEngineEvent::ContextPop); |
|
1719 // exception |
|
1720 QCOMPARE(spy->at(7).type, ScriptEngineEvent::ExceptionThrow); |
|
1721 QVERIFY(!spy->at(7).hasExceptionHandler); |
|
1722 // evaluate() exit |
|
1723 QCOMPARE(spy->at(8).type, ScriptEngineEvent::FunctionExit); |
|
1724 // unload |
|
1725 QCOMPARE(spy->at(9).type, ScriptEngineEvent::ScriptUnload); |
|
1726 } |
|
1727 delete spy; |
|
1728 } |
|
1729 |
|
1730 void tst_QScriptEngineAgent::eventOrder_throwAndCatch() |
|
1731 { |
|
1732 QScriptEngine eng; |
|
1733 ScriptEngineSpy *spy = new ScriptEngineSpy(&eng); |
|
1734 { |
|
1735 spy->clear(); |
|
1736 eng.evaluate("try { throw new Error('ciao') } catch (e) { void(e); }"); |
|
1737 QCOMPARE(spy->count(), 12); |
|
1738 // load |
|
1739 QCOMPARE(spy->at(0).type, ScriptEngineEvent::ScriptLoad); |
|
1740 // evaluate() entry |
|
1741 QCOMPARE(spy->at(1).type, ScriptEngineEvent::FunctionEntry); |
|
1742 // throw |
|
1743 QCOMPARE(spy->at(2).type, ScriptEngineEvent::PositionChange); |
|
1744 // new context |
|
1745 QCOMPARE(spy->at(3).type, ScriptEngineEvent::ContextPush); |
|
1746 // Error constructor entry |
|
1747 QCOMPARE(spy->at(4).type, ScriptEngineEvent::FunctionEntry); |
|
1748 // Error constructor exit |
|
1749 QCOMPARE(spy->at(5).type, ScriptEngineEvent::FunctionExit); |
|
1750 // restore context |
|
1751 QCOMPARE(spy->at(6).type, ScriptEngineEvent::ContextPop); |
|
1752 // exception |
|
1753 QCOMPARE(spy->at(7).type, ScriptEngineEvent::ExceptionThrow); |
|
1754 QVERIFY(spy->at(7).value.isError()); |
|
1755 QVERIFY(spy->at(7).hasExceptionHandler); |
|
1756 // catch |
|
1757 QCOMPARE(spy->at(8).type, ScriptEngineEvent::ExceptionCatch); |
|
1758 QVERIFY(spy->at(8).value.isError()); |
|
1759 // void(e) |
|
1760 QCOMPARE(spy->at(9).type, ScriptEngineEvent::PositionChange); |
|
1761 // evaluate() exit |
|
1762 QCOMPARE(spy->at(10).type, ScriptEngineEvent::FunctionExit); |
|
1763 QVERIFY(spy->at(10).value.isUndefined()); |
|
1764 // unload |
|
1765 QCOMPARE(spy->at(11).type, ScriptEngineEvent::ScriptUnload); |
|
1766 } |
|
1767 delete spy; |
|
1768 } |
|
1769 |
|
1770 void tst_QScriptEngineAgent::eventOrder_functions() |
|
1771 { |
|
1772 QScriptEngine eng; |
|
1773 ScriptEngineSpy *spy = new ScriptEngineSpy(&eng); |
|
1774 { |
|
1775 spy->clear(); |
|
1776 eng.evaluate("function foo(arg) { return bar(arg); }"); |
|
1777 eng.evaluate("function bar(arg) { return arg; }"); |
|
1778 QCOMPARE(spy->count(), 6); |
|
1779 |
|
1780 eng.evaluate("foo(123)"); |
|
1781 QCOMPARE(spy->count(), 21); |
|
1782 |
|
1783 // load |
|
1784 QCOMPARE(spy->at(6).type, ScriptEngineEvent::ScriptLoad); |
|
1785 // evaluate() entry |
|
1786 QCOMPARE(spy->at(7).type, ScriptEngineEvent::FunctionEntry); |
|
1787 // foo(123) |
|
1788 QCOMPARE(spy->at(8).type, ScriptEngineEvent::PositionChange); |
|
1789 // new context |
|
1790 QCOMPARE(spy->at(9).type, ScriptEngineEvent::ContextPush); |
|
1791 // foo() entry |
|
1792 QCOMPARE(spy->at(10).type, ScriptEngineEvent::FunctionEntry); |
|
1793 QCOMPARE(spy->at(10).scriptId, spy->at(0).scriptId); |
|
1794 // return bar(arg) |
|
1795 QCOMPARE(spy->at(11).type, ScriptEngineEvent::PositionChange); |
|
1796 QCOMPARE(spy->at(11).scriptId, spy->at(0).scriptId); |
|
1797 // new context |
|
1798 QCOMPARE(spy->at(12).type, ScriptEngineEvent::ContextPush); |
|
1799 // bar() entry |
|
1800 QCOMPARE(spy->at(13).type, ScriptEngineEvent::FunctionEntry); |
|
1801 QCOMPARE(spy->at(13).scriptId, spy->at(3).scriptId); |
|
1802 // return arg |
|
1803 QCOMPARE(spy->at(14).type, ScriptEngineEvent::PositionChange); |
|
1804 QCOMPARE(spy->at(14).scriptId, spy->at(3).scriptId); |
|
1805 // bar() exit |
|
1806 QCOMPARE(spy->at(15).type, ScriptEngineEvent::FunctionExit); |
|
1807 QCOMPARE(spy->at(15).scriptId, spy->at(3).scriptId); |
|
1808 QVERIFY(spy->at(15).value.isNumber()); |
|
1809 // restore context |
|
1810 QCOMPARE(spy->at(16).type, ScriptEngineEvent::ContextPop); |
|
1811 // foo() exit |
|
1812 QCOMPARE(spy->at(17).type, ScriptEngineEvent::FunctionExit); |
|
1813 QCOMPARE(spy->at(17).scriptId, spy->at(0).scriptId); |
|
1814 QVERIFY(spy->at(17).value.isNumber()); |
|
1815 // restore context |
|
1816 QCOMPARE(spy->at(18).type, ScriptEngineEvent::ContextPop); |
|
1817 // evaluate() exit |
|
1818 QCOMPARE(spy->at(19).type, ScriptEngineEvent::FunctionExit); |
|
1819 QCOMPARE(spy->at(19).scriptId, spy->at(6).scriptId); |
|
1820 QVERIFY(spy->at(19).value.isNumber()); |
|
1821 // unload |
|
1822 QCOMPARE(spy->at(20).type, ScriptEngineEvent::ScriptUnload); |
|
1823 QCOMPARE(spy->at(20).scriptId, spy->at(6).scriptId); |
|
1824 |
|
1825 // redefine bar() |
|
1826 eng.evaluate("function bar(arg) { throw new Error(arg); }"); |
|
1827 eng.collectGarbage(); |
|
1828 QCOMPARE(spy->count(), 25); |
|
1829 QCOMPARE(spy->at(21).type, ScriptEngineEvent::ScriptLoad); |
|
1830 QCOMPARE(spy->at(22).type, ScriptEngineEvent::FunctionEntry); |
|
1831 QCOMPARE(spy->at(23).type, ScriptEngineEvent::FunctionExit); |
|
1832 QCOMPARE(spy->at(24).type, ScriptEngineEvent::ScriptUnload); |
|
1833 QCOMPARE(spy->at(24).scriptId, spy->at(3).scriptId); |
|
1834 |
|
1835 eng.evaluate("foo('ciao')"); |
|
1836 |
|
1837 QCOMPARE(spy->count(), 45); |
|
1838 |
|
1839 // load |
|
1840 QCOMPARE(spy->at(25).type, ScriptEngineEvent::ScriptLoad); |
|
1841 // evaluate() entry |
|
1842 QCOMPARE(spy->at(26).type, ScriptEngineEvent::FunctionEntry); |
|
1843 // foo('ciao') |
|
1844 QCOMPARE(spy->at(27).type, ScriptEngineEvent::PositionChange); |
|
1845 // new context |
|
1846 QCOMPARE(spy->at(28).type, ScriptEngineEvent::ContextPush); |
|
1847 // foo() entry |
|
1848 QCOMPARE(spy->at(29).type, ScriptEngineEvent::FunctionEntry); |
|
1849 QCOMPARE(spy->at(29).scriptId, spy->at(0).scriptId); |
|
1850 // return bar(arg) |
|
1851 QCOMPARE(spy->at(30).type, ScriptEngineEvent::PositionChange); |
|
1852 QCOMPARE(spy->at(30).scriptId, spy->at(0).scriptId); |
|
1853 // new context |
|
1854 QCOMPARE(spy->at(31).type, ScriptEngineEvent::ContextPush); |
|
1855 // bar() entry |
|
1856 QCOMPARE(spy->at(32).type, ScriptEngineEvent::FunctionEntry); |
|
1857 QCOMPARE(spy->at(32).scriptId, spy->at(21).scriptId); |
|
1858 // throw |
|
1859 QCOMPARE(spy->at(33).type, ScriptEngineEvent::PositionChange); |
|
1860 QCOMPARE(spy->at(33).scriptId, spy->at(21).scriptId); |
|
1861 // new context |
|
1862 QCOMPARE(spy->at(34).type, ScriptEngineEvent::ContextPush); |
|
1863 // Error constructor entry |
|
1864 QCOMPARE(spy->at(35).type, ScriptEngineEvent::FunctionEntry); |
|
1865 QCOMPARE(spy->at(35).scriptId, qint64(-1)); |
|
1866 // Error constructor exit |
|
1867 QCOMPARE(spy->at(36).type, ScriptEngineEvent::FunctionExit); |
|
1868 QCOMPARE(spy->at(36).scriptId, qint64(-1)); |
|
1869 // restore context |
|
1870 QCOMPARE(spy->at(37).type, ScriptEngineEvent::ContextPop); |
|
1871 // exception |
|
1872 QCOMPARE(spy->at(38).type, ScriptEngineEvent::ExceptionThrow); |
|
1873 QCOMPARE(spy->at(38).scriptId, spy->at(21).scriptId); |
|
1874 QVERIFY(!spy->at(38).hasExceptionHandler); |
|
1875 // bar() exit |
|
1876 QCOMPARE(spy->at(39).type, ScriptEngineEvent::FunctionExit); |
|
1877 QCOMPARE(spy->at(39).scriptId, spy->at(21).scriptId); |
|
1878 QVERIFY(spy->at(39).value.isError()); |
|
1879 // restore context |
|
1880 QCOMPARE(spy->at(40).type, ScriptEngineEvent::ContextPop); |
|
1881 // foo() exit |
|
1882 QCOMPARE(spy->at(41).type, ScriptEngineEvent::FunctionExit); |
|
1883 QCOMPARE(spy->at(41).scriptId, spy->at(0).scriptId); |
|
1884 QVERIFY(spy->at(41).value.isError()); |
|
1885 // restore context |
|
1886 QCOMPARE(spy->at(42).type, ScriptEngineEvent::ContextPop); |
|
1887 // evaluate() exit |
|
1888 QCOMPARE(spy->at(43).type, ScriptEngineEvent::FunctionExit); |
|
1889 QCOMPARE(spy->at(43).scriptId, spy->at(26).scriptId); |
|
1890 QVERIFY(spy->at(43).value.isError()); |
|
1891 // unload |
|
1892 QCOMPARE(spy->at(44).type, ScriptEngineEvent::ScriptUnload); |
|
1893 QCOMPARE(spy->at(44).scriptId, spy->at(25).scriptId); |
|
1894 } |
|
1895 delete spy; |
|
1896 } |
|
1897 |
|
1898 void tst_QScriptEngineAgent::eventOrder_throwCatchFinally() |
|
1899 { |
|
1900 QScriptEngine eng; |
|
1901 ScriptEngineSpy *spy = new ScriptEngineSpy(&eng); |
|
1902 { |
|
1903 spy->clear(); |
|
1904 eng.evaluate("try { throw 1; } catch(e) { i = e; } finally { i = 2; }"); |
|
1905 QCOMPARE(spy->count(), 9); |
|
1906 |
|
1907 // load |
|
1908 QCOMPARE(spy->at(0).type, ScriptEngineEvent::ScriptLoad); |
|
1909 // evaluate() entry |
|
1910 QCOMPARE(spy->at(1).type, ScriptEngineEvent::FunctionEntry); |
|
1911 // throw 1 |
|
1912 QCOMPARE(spy->at(2).type, ScriptEngineEvent::PositionChange); |
|
1913 // i = e |
|
1914 QCOMPARE(spy->at(3).type, ScriptEngineEvent::ExceptionThrow); |
|
1915 // catch |
|
1916 QCOMPARE(spy->at(4).type, ScriptEngineEvent::ExceptionCatch); |
|
1917 // i = e |
|
1918 QCOMPARE(spy->at(5).type, ScriptEngineEvent::PositionChange); |
|
1919 // i = 2 |
|
1920 QCOMPARE(spy->at(6).type, ScriptEngineEvent::PositionChange); |
|
1921 // evaluate() exit |
|
1922 QCOMPARE(spy->at(7).type, ScriptEngineEvent::FunctionExit); |
|
1923 // unload |
|
1924 QCOMPARE(spy->at(8).type, ScriptEngineEvent::ScriptUnload); |
|
1925 } |
|
1926 delete spy; |
|
1927 } |
|
1928 |
|
1929 void tst_QScriptEngineAgent::eventOrder_signalsHandling() |
|
1930 { |
|
1931 QScriptEngine eng; |
|
1932 ScriptEngineSpy *spy = new ScriptEngineSpy(&eng); |
|
1933 // signal handling |
|
1934 { |
|
1935 spy->clear(); |
|
1936 QScriptValue fun = eng.evaluate("(function(arg) { throw Error(arg); })"); |
|
1937 QVERIFY(fun.isFunction()); |
|
1938 QCOMPARE(spy->count(), 4); |
|
1939 QCOMPARE(spy->at(0).type, ScriptEngineEvent::ScriptLoad); |
|
1940 QCOMPARE(spy->at(1).type, ScriptEngineEvent::FunctionEntry); |
|
1941 QCOMPARE(spy->at(2).type, ScriptEngineEvent::PositionChange); |
|
1942 QCOMPARE(spy->at(3).type, ScriptEngineEvent::FunctionExit); |
|
1943 |
|
1944 qScriptConnect(this, SIGNAL(testSignal(double)), |
|
1945 QScriptValue(), fun); |
|
1946 |
|
1947 emit testSignal(123); |
|
1948 |
|
1949 QCOMPARE(spy->count(), 14); |
|
1950 // new context |
|
1951 QCOMPARE(spy->at(4).type, ScriptEngineEvent::ContextPush); |
|
1952 // anonymous function entry |
|
1953 QCOMPARE(spy->at(5).type, ScriptEngineEvent::FunctionEntry); |
|
1954 QCOMPARE(spy->at(5).scriptId, spy->at(0).scriptId); |
|
1955 // throw statement |
|
1956 QCOMPARE(spy->at(6).type, ScriptEngineEvent::PositionChange); |
|
1957 QCOMPARE(spy->at(6).scriptId, spy->at(0).scriptId); |
|
1958 // new context |
|
1959 QCOMPARE(spy->at(7).type, ScriptEngineEvent::ContextPush); |
|
1960 // Error constructor entry |
|
1961 QCOMPARE(spy->at(8).type, ScriptEngineEvent::FunctionEntry); |
|
1962 QCOMPARE(spy->at(8).scriptId, qint64(-1)); |
|
1963 // Error constructor exit |
|
1964 QCOMPARE(spy->at(9).type, ScriptEngineEvent::FunctionExit); |
|
1965 QCOMPARE(spy->at(9).scriptId, qint64(-1)); |
|
1966 // restore context |
|
1967 QCOMPARE(spy->at(10).type, ScriptEngineEvent::ContextPop); |
|
1968 // exception |
|
1969 QCOMPARE(spy->at(11).type, ScriptEngineEvent::ExceptionThrow); |
|
1970 QCOMPARE(spy->at(11).scriptId, spy->at(0).scriptId); |
|
1971 QVERIFY(spy->at(11).value.isError()); |
|
1972 QVERIFY(!spy->at(11).hasExceptionHandler); |
|
1973 // anonymous function exit |
|
1974 QCOMPARE(spy->at(12).type, ScriptEngineEvent::FunctionExit); |
|
1975 QCOMPARE(spy->at(12).scriptId, spy->at(0).scriptId); |
|
1976 QVERIFY(spy->at(12).value.isError()); |
|
1977 // restore context |
|
1978 QCOMPARE(spy->at(13).type, ScriptEngineEvent::ContextPop); |
|
1979 } |
|
1980 delete spy; |
|
1981 } |
|
1982 |
|
1983 class DoubleAgent : public ScriptEngineSpy |
|
1984 { |
|
1985 public: |
|
1986 DoubleAgent(QScriptEngine *engine) : ScriptEngineSpy(engine) { } |
|
1987 ~DoubleAgent() { } |
|
1988 |
|
1989 void positionChange(qint64 scriptId, int lineNumber, int columnNumber) |
|
1990 { |
|
1991 if (lineNumber == 123) |
|
1992 engine()->evaluate("1 + 2"); |
|
1993 ScriptEngineSpy::positionChange(scriptId, lineNumber, columnNumber); |
|
1994 } |
|
1995 }; |
|
1996 |
|
1997 void tst_QScriptEngineAgent::recursiveObserve() |
|
1998 { |
|
1999 QScriptEngine eng; |
|
2000 DoubleAgent *spy = new DoubleAgent(&eng); |
|
2001 |
|
2002 eng.evaluate("3 + 4", "foo.qs", 123); |
|
2003 |
|
2004 QCOMPARE(spy->count(), 10); |
|
2005 |
|
2006 int i = 0; |
|
2007 // load "3 + 4" |
|
2008 QCOMPARE(spy->at(i).type, ScriptEngineEvent::ScriptLoad); |
|
2009 i++; |
|
2010 // evaluate() entry |
|
2011 QCOMPARE(spy->at(i).type, ScriptEngineEvent::FunctionEntry); |
|
2012 i++; |
|
2013 // load "1 + 2" |
|
2014 QCOMPARE(spy->at(i).type, ScriptEngineEvent::ScriptLoad); |
|
2015 i++; |
|
2016 // evaluate() entry |
|
2017 QCOMPARE(spy->at(i).type, ScriptEngineEvent::FunctionEntry); |
|
2018 i++; |
|
2019 // 1 + 2 |
|
2020 QCOMPARE(spy->at(i).type, ScriptEngineEvent::PositionChange); |
|
2021 QCOMPARE(spy->at(i).scriptId, spy->at(2).scriptId); |
|
2022 i++; |
|
2023 // evaluate() exit |
|
2024 QCOMPARE(spy->at(i).type, ScriptEngineEvent::FunctionExit); |
|
2025 i++; |
|
2026 // unload "1 + 2" |
|
2027 QCOMPARE(spy->at(i).type, ScriptEngineEvent::ScriptUnload); |
|
2028 QCOMPARE(spy->at(i).scriptId, spy->at(2).scriptId); |
|
2029 i++; |
|
2030 // 3 + 4 |
|
2031 QCOMPARE(spy->at(i).type, ScriptEngineEvent::PositionChange); |
|
2032 QCOMPARE(spy->at(i).scriptId, spy->at(0).scriptId); |
|
2033 i++; |
|
2034 // evaluate() exit |
|
2035 QCOMPARE(spy->at(i).type, ScriptEngineEvent::FunctionExit); |
|
2036 i++; |
|
2037 // unload "3 + 4" |
|
2038 QCOMPARE(spy->at(i).type, ScriptEngineEvent::ScriptUnload); |
|
2039 QCOMPARE(spy->at(i).scriptId, spy->at(0).scriptId); |
|
2040 } |
|
2041 |
|
2042 |
|
2043 /** When second agent is attached to Engine the first one should be deatached */ |
|
2044 void tst_QScriptEngineAgent::multipleAgents() |
|
2045 { |
|
2046 QScriptEngine eng; |
|
2047 QCOMPARE(eng.agent(), (QScriptEngineAgent *)0); |
|
2048 ScriptEngineSpy *spy1 = new ScriptEngineSpy(&eng); |
|
2049 QCOMPARE(eng.agent(), (QScriptEngineAgent*)spy1); |
|
2050 ScriptEngineSpy *spy2 = new ScriptEngineSpy(&eng); |
|
2051 QCOMPARE(eng.agent(), (QScriptEngineAgent*)spy2); |
|
2052 |
|
2053 eng.evaluate("1 + 2"); |
|
2054 QCOMPARE(spy1->count(), 0); |
|
2055 QCOMPARE(spy2->count(), 5); |
|
2056 |
|
2057 spy2->clear(); |
|
2058 eng.setAgent(spy1); |
|
2059 eng.evaluate("1 + 2"); |
|
2060 QCOMPARE(spy2->count(), 0); |
|
2061 QCOMPARE(spy1->count(), 5); |
|
2062 } |
|
2063 |
|
2064 void tst_QScriptEngineAgent::syntaxError() |
|
2065 { |
|
2066 /* This test was changed. Old backend didn't generate events in exception objects creation time |
|
2067 JSC does */ |
|
2068 QScriptEngine eng; |
|
2069 ScriptEngineSpy *spy = new ScriptEngineSpy(&eng); |
|
2070 { |
|
2071 int i = 0; |
|
2072 spy->clear(); |
|
2073 eng.evaluate("{"); |
|
2074 |
|
2075 QCOMPARE(spy->count(), 9); |
|
2076 |
|
2077 QCOMPARE(spy->at(i).type, ScriptEngineEvent::ScriptLoad); |
|
2078 QVERIFY(spy->at(i).scriptId != -1); |
|
2079 i = 1; |
|
2080 QCOMPARE(spy->at(i).type, ScriptEngineEvent::FunctionEntry); |
|
2081 QCOMPARE(spy->at(i).scriptId, spy->at(0).scriptId); |
|
2082 |
|
2083 //create exception |
|
2084 |
|
2085 i = 2; |
|
2086 QCOMPARE(spy->at(i).type, ScriptEngineEvent::ContextPush); |
|
2087 QEXPECT_FAIL("","The test is broken, contextPush event do not provide scriptId", Continue); |
|
2088 QVERIFY(spy->at(i).scriptId == -1); |
|
2089 i = 3; |
|
2090 QCOMPARE(spy->at(i).type, ScriptEngineEvent::FunctionEntry); |
|
2091 QVERIFY(spy->at(i).scriptId == -1); |
|
2092 i = 4; |
|
2093 QCOMPARE(spy->at(i).type, ScriptEngineEvent::FunctionExit); |
|
2094 QVERIFY(spy->at(i).scriptId == -1); |
|
2095 i = 5; |
|
2096 QCOMPARE(spy->at(i).type, ScriptEngineEvent::ContextPop); |
|
2097 QEXPECT_FAIL("","The test is broken, contextPop event do not provide scriptId", Continue); |
|
2098 QVERIFY(spy->at(i).scriptId == -1); |
|
2099 i = 6; |
|
2100 QCOMPARE(spy->at(i).type, ScriptEngineEvent::ExceptionThrow); |
|
2101 QCOMPARE(spy->at(i).scriptId, spy->at(0).scriptId); |
|
2102 QVERIFY(!spy->at(i).hasExceptionHandler); |
|
2103 QVERIFY(spy->at(i).value.isError()); |
|
2104 QEXPECT_FAIL("","There are other messages in JSC",Continue); |
|
2105 QCOMPARE(spy->at(i).value.toString(), QString("SyntaxError: Expected `}'")); |
|
2106 QCOMPARE(spy->at(i).scriptId, spy->at(0).scriptId); |
|
2107 i = 7; |
|
2108 //exit script |
|
2109 QCOMPARE(spy->at(i).type, ScriptEngineEvent::FunctionExit); |
|
2110 QCOMPARE(spy->at(i).scriptId, spy->at(0).scriptId); |
|
2111 i = 8; |
|
2112 QCOMPARE(spy->at(i).type, ScriptEngineEvent::ScriptUnload); |
|
2113 QCOMPARE(spy->at(i).scriptId, spy->at(0).scriptId); |
|
2114 } |
|
2115 } |
|
2116 |
|
2117 void tst_QScriptEngineAgent::extension_invoctaion() |
|
2118 { |
|
2119 QScriptEngine eng; |
|
2120 ScriptEngineSpy *spy = new ScriptEngineSpy(&eng, ~(ScriptEngineSpy::IgnoreDebuggerInvocationRequest |
|
2121 | ScriptEngineSpy::IgnoreScriptLoad)); |
|
2122 // DebuggerInvocationRequest |
|
2123 { |
|
2124 spy->clear(); |
|
2125 |
|
2126 QString fileName = "foo.qs"; |
|
2127 int lineNumber = 123; |
|
2128 QScriptValue ret = eng.evaluate("debugger", fileName, lineNumber); |
|
2129 |
|
2130 QCOMPARE(spy->count(), 2); |
|
2131 QCOMPARE(spy->at(0).type, ScriptEngineEvent::ScriptLoad); |
|
2132 QCOMPARE(spy->at(1).type, ScriptEngineEvent::DebuggerInvocationRequest); |
|
2133 QCOMPARE(spy->at(1).scriptId, spy->at(0).scriptId); |
|
2134 QCOMPARE(spy->at(1).lineNumber, lineNumber); |
|
2135 QCOMPARE(spy->at(1).columnNumber, 1); |
|
2136 |
|
2137 QEXPECT_FAIL("","In JSC Eval('debugger') returns undefined",Abort); |
|
2138 QVERIFY(ret.isString()); |
|
2139 QCOMPARE(ret.toString(), QString::fromLatin1("extension(DebuggerInvocationRequest)")); |
|
2140 } |
|
2141 delete spy; |
|
2142 } |
|
2143 |
|
2144 void tst_QScriptEngineAgent::extension() |
|
2145 { |
|
2146 QScriptEngine eng; |
|
2147 ScriptEngineSpy *spy = new ScriptEngineSpy(&eng, ~(ScriptEngineSpy::IgnoreDebuggerInvocationRequest |
|
2148 | ScriptEngineSpy::IgnoreScriptLoad)); |
|
2149 |
|
2150 { |
|
2151 spy->clear(); |
|
2152 spy->enableIgnoreFlags(ScriptEngineSpy::IgnoreDebuggerInvocationRequest); |
|
2153 |
|
2154 QScriptValue ret = eng.evaluate("debugger"); |
|
2155 |
|
2156 QCOMPARE(spy->count(), 1); |
|
2157 QCOMPARE(spy->at(0).type, ScriptEngineEvent::ScriptLoad); |
|
2158 QVERIFY(ret.isUndefined()); |
|
2159 } |
|
2160 delete spy; |
|
2161 } |
|
2162 |
|
2163 class TestIsEvaluatingAgent : public QScriptEngineAgent |
|
2164 { |
|
2165 public: |
|
2166 TestIsEvaluatingAgent(QScriptEngine *engine) |
|
2167 : QScriptEngineAgent(engine), wasEvaluating(false) |
|
2168 { engine->setAgent(this); } |
|
2169 bool supportsExtension(Extension ext) const |
|
2170 { return ext == DebuggerInvocationRequest; } |
|
2171 QVariant extension(Extension, const QVariant &) |
|
2172 { wasEvaluating = engine()->isEvaluating(); return QVariant(); } |
|
2173 |
|
2174 bool wasEvaluating; |
|
2175 }; |
|
2176 |
|
2177 void tst_QScriptEngineAgent::isEvaluatingInExtension() |
|
2178 { |
|
2179 QScriptEngine eng; |
|
2180 TestIsEvaluatingAgent *spy = new TestIsEvaluatingAgent(&eng); |
|
2181 QVERIFY(!spy->wasEvaluating); |
|
2182 eng.evaluate("debugger"); |
|
2183 QVERIFY(spy->wasEvaluating); |
|
2184 } |
|
2185 |
|
2186 class NewSpy :public QScriptEngineAgent |
|
2187 { |
|
2188 bool m_result; |
|
2189 public: |
|
2190 NewSpy(QScriptEngine* eng) : QScriptEngineAgent(eng), m_result(false) {} |
|
2191 void functionExit (qint64, const QScriptValue &scriptValue) |
|
2192 { |
|
2193 if (engine()->hasUncaughtException()) m_result = true; |
|
2194 } |
|
2195 |
|
2196 bool isPass() { return m_result; } |
|
2197 void reset() { m_result = false; } |
|
2198 }; |
|
2199 |
|
2200 void tst_QScriptEngineAgent::hasUncaughtException() |
|
2201 { |
|
2202 QScriptEngine eng; |
|
2203 NewSpy* spy = new NewSpy(&eng); |
|
2204 eng.setAgent(spy); |
|
2205 QScriptValue scriptValue; |
|
2206 |
|
2207 // Check unhandled exception. |
|
2208 eng.evaluate("function init () {Unknown.doSth ();}"); |
|
2209 scriptValue = QScriptValue(eng.globalObject().property("init")).call(); |
|
2210 QVERIFY(eng.hasUncaughtException()); |
|
2211 QVERIFY2(spy->isPass(), "At least one of a functionExit event should set hasUncaughtException flag."); |
|
2212 spy->reset(); |
|
2213 |
|
2214 // Check catched exception. |
|
2215 eng.evaluate("function innerFoo() { throw new Error('ciao') }"); |
|
2216 eng.evaluate("function foo() {try { innerFoo() } catch (e) {} }"); |
|
2217 scriptValue = QScriptValue(eng.globalObject().property("foo")).call(); |
|
2218 QVERIFY(!eng.hasUncaughtException()); |
|
2219 QVERIFY2(spy->isPass(), "At least one of a functionExit event should set hasUncaughtException flag."); |
|
2220 } |
|
2221 |
|
2222 |
|
2223 QTEST_MAIN(tst_QScriptEngineAgent) |
|
2224 #include "tst_qscriptengineagent.moc" |