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