|
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 #include <qtest.h> |
|
42 #include <QtDeclarative/qdeclarativecomponent.h> |
|
43 #include <QtDeclarative/qdeclarativeengine.h> |
|
44 #include <QtDeclarative/qdeclarativeexpression.h> |
|
45 #include <QtDeclarative/qdeclarativecontext.h> |
|
46 #include <QtCore/qfileinfo.h> |
|
47 #include <QtCore/qdebug.h> |
|
48 #include <QtDeclarative/private/qdeclarativeguard_p.h> |
|
49 #include <QtCore/qdir.h> |
|
50 #include <QtCore/qnumeric.h> |
|
51 #include <private/qdeclarativeengine_p.h> |
|
52 #include <private/qdeclarativeglobalscriptclass_p.h> |
|
53 #include "testtypes.h" |
|
54 #include "testhttpserver.h" |
|
55 |
|
56 /* |
|
57 This test covers evaluation of ECMAScript expressions and bindings from within |
|
58 QML. This does not include static QML language issues. |
|
59 |
|
60 Static QML language issues are covered in qmllanguage |
|
61 */ |
|
62 inline QUrl TEST_FILE(const QString &filename) |
|
63 { |
|
64 QFileInfo fileInfo(__FILE__); |
|
65 return QUrl::fromLocalFile(fileInfo.absoluteDir().filePath("data/" + filename)); |
|
66 } |
|
67 |
|
68 inline QUrl TEST_FILE(const char *filename) |
|
69 { |
|
70 return TEST_FILE(QLatin1String(filename)); |
|
71 } |
|
72 |
|
73 class tst_qdeclarativeecmascript : public QObject |
|
74 { |
|
75 Q_OBJECT |
|
76 public: |
|
77 tst_qdeclarativeecmascript() {} |
|
78 |
|
79 private slots: |
|
80 void initTestCase(); |
|
81 void assignBasicTypes(); |
|
82 void idShortcutInvalidates(); |
|
83 void boolPropertiesEvaluateAsBool(); |
|
84 void methods(); |
|
85 void signalAssignment(); |
|
86 void bindingLoop(); |
|
87 void basicExpressions(); |
|
88 void basicExpressions_data(); |
|
89 void arrayExpressions(); |
|
90 void contextPropertiesTriggerReeval(); |
|
91 void objectPropertiesTriggerReeval(); |
|
92 void deferredProperties(); |
|
93 void deferredPropertiesErrors(); |
|
94 void extensionObjects(); |
|
95 void overrideExtensionProperties(); |
|
96 void attachedProperties(); |
|
97 void enums(); |
|
98 void valueTypeFunctions(); |
|
99 void constantsOverrideBindings(); |
|
100 void outerBindingOverridesInnerBinding(); |
|
101 void aliasPropertyAndBinding(); |
|
102 void nonExistantAttachedObject(); |
|
103 void scope(); |
|
104 void signalParameterTypes(); |
|
105 void objectsCompareAsEqual(); |
|
106 void dynamicCreation_data(); |
|
107 void dynamicCreation(); |
|
108 void dynamicDestruction(); |
|
109 void objectToString(); |
|
110 void selfDeletingBinding(); |
|
111 void extendedObjectPropertyLookup(); |
|
112 void scriptErrors(); |
|
113 void functionErrors(); |
|
114 void propertyAssignmentErrors(); |
|
115 void signalTriggeredBindings(); |
|
116 void listProperties(); |
|
117 void exceptionClearsOnReeval(); |
|
118 void exceptionSlotProducesWarning(); |
|
119 void exceptionBindingProducesWarning(); |
|
120 void transientErrors(); |
|
121 void shutdownErrors(); |
|
122 void compositePropertyType(); |
|
123 void jsObject(); |
|
124 void undefinedResetsProperty(); |
|
125 void listToVariant(); |
|
126 void multiEngineObject(); |
|
127 void deletedObject(); |
|
128 void attachedPropertyScope(); |
|
129 void scriptConnect(); |
|
130 void scriptDisconnect(); |
|
131 void ownership(); |
|
132 void qlistqobjectMethods(); |
|
133 void strictlyEquals(); |
|
134 void compiled(); |
|
135 void numberAssignment(); |
|
136 |
|
137 void bug1(); |
|
138 void bug2(); |
|
139 void dynamicCreationCrash(); |
|
140 void regExpBug(); |
|
141 void nullObjectBinding(); |
|
142 void deletedEngine(); |
|
143 void libraryScriptAssert(); |
|
144 void variantsAssignedUndefined(); |
|
145 void qtbug_9792(); |
|
146 void qtcreatorbug_1289(); |
|
147 void noSpuriousWarningsAtShutdown(); |
|
148 void canAssignNullToQObject(); |
|
149 void functionAssignment(); |
|
150 void eval(); |
|
151 void function(); |
|
152 void qtbug_10696(); |
|
153 |
|
154 void include(); |
|
155 |
|
156 void callQtInvokables(); |
|
157 private: |
|
158 QDeclarativeEngine engine; |
|
159 }; |
|
160 |
|
161 void tst_qdeclarativeecmascript::initTestCase() { registerTypes(); } |
|
162 |
|
163 void tst_qdeclarativeecmascript::assignBasicTypes() |
|
164 { |
|
165 { |
|
166 QDeclarativeComponent component(&engine, TEST_FILE("assignBasicTypes.qml")); |
|
167 MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create()); |
|
168 QVERIFY(object != 0); |
|
169 QCOMPARE(object->flagProperty(), MyTypeObject::FlagVal1 | MyTypeObject::FlagVal3); |
|
170 QCOMPARE(object->enumProperty(), MyTypeObject::EnumVal2); |
|
171 QCOMPARE(object->stringProperty(), QString("Hello World!")); |
|
172 QCOMPARE(object->uintProperty(), uint(10)); |
|
173 QCOMPARE(object->intProperty(), -19); |
|
174 QCOMPARE((float)object->realProperty(), float(23.2)); |
|
175 QCOMPARE((float)object->doubleProperty(), float(-19.7)); |
|
176 QCOMPARE((float)object->floatProperty(), float(8.5)); |
|
177 QCOMPARE(object->colorProperty(), QColor("red")); |
|
178 QCOMPARE(object->dateProperty(), QDate(1982, 11, 25)); |
|
179 QCOMPARE(object->timeProperty(), QTime(11, 11, 32)); |
|
180 QCOMPARE(object->dateTimeProperty(), QDateTime(QDate(2009, 5, 12), QTime(13, 22, 1))); |
|
181 QCOMPARE(object->pointProperty(), QPoint(99,13)); |
|
182 QCOMPARE(object->pointFProperty(), QPointF(-10.1, 12.3)); |
|
183 QCOMPARE(object->sizeProperty(), QSize(99, 13)); |
|
184 QCOMPARE(object->sizeFProperty(), QSizeF(0.1, 0.2)); |
|
185 QCOMPARE(object->rectProperty(), QRect(9, 7, 100, 200)); |
|
186 QCOMPARE(object->rectFProperty(), QRectF(1000.1, -10.9, 400, 90.99)); |
|
187 QCOMPARE(object->boolProperty(), true); |
|
188 QCOMPARE(object->variantProperty(), QVariant("Hello World!")); |
|
189 QCOMPARE(object->vectorProperty(), QVector3D(10, 1, 2.2)); |
|
190 QCOMPARE(object->urlProperty(), component.url().resolved(QUrl("main.qml"))); |
|
191 delete object; |
|
192 } |
|
193 { |
|
194 QDeclarativeComponent component(&engine, TEST_FILE("assignBasicTypes.2.qml")); |
|
195 MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create()); |
|
196 QVERIFY(object != 0); |
|
197 QCOMPARE(object->flagProperty(), MyTypeObject::FlagVal1 | MyTypeObject::FlagVal3); |
|
198 QCOMPARE(object->enumProperty(), MyTypeObject::EnumVal2); |
|
199 QCOMPARE(object->stringProperty(), QString("Hello World!")); |
|
200 QCOMPARE(object->uintProperty(), uint(10)); |
|
201 QCOMPARE(object->intProperty(), -19); |
|
202 QCOMPARE((float)object->realProperty(), float(23.2)); |
|
203 QCOMPARE((float)object->doubleProperty(), float(-19.7)); |
|
204 QCOMPARE((float)object->floatProperty(), float(8.5)); |
|
205 QCOMPARE(object->colorProperty(), QColor("red")); |
|
206 QCOMPARE(object->dateProperty(), QDate(1982, 11, 25)); |
|
207 QCOMPARE(object->timeProperty(), QTime(11, 11, 32)); |
|
208 QCOMPARE(object->dateTimeProperty(), QDateTime(QDate(2009, 5, 12), QTime(13, 22, 1))); |
|
209 QCOMPARE(object->pointProperty(), QPoint(99,13)); |
|
210 QCOMPARE(object->pointFProperty(), QPointF(-10.1, 12.3)); |
|
211 QCOMPARE(object->sizeProperty(), QSize(99, 13)); |
|
212 QCOMPARE(object->sizeFProperty(), QSizeF(0.1, 0.2)); |
|
213 QCOMPARE(object->rectProperty(), QRect(9, 7, 100, 200)); |
|
214 QCOMPARE(object->rectFProperty(), QRectF(1000.1, -10.9, 400, 90.99)); |
|
215 QCOMPARE(object->boolProperty(), true); |
|
216 QCOMPARE(object->variantProperty(), QVariant("Hello World!")); |
|
217 QCOMPARE(object->vectorProperty(), QVector3D(10, 1, 2.2)); |
|
218 QCOMPARE(object->urlProperty(), component.url().resolved(QUrl("main.qml"))); |
|
219 delete object; |
|
220 } |
|
221 } |
|
222 |
|
223 void tst_qdeclarativeecmascript::idShortcutInvalidates() |
|
224 { |
|
225 { |
|
226 QDeclarativeComponent component(&engine, TEST_FILE("idShortcutInvalidates.qml")); |
|
227 MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create()); |
|
228 QVERIFY(object != 0); |
|
229 QVERIFY(object->objectProperty() != 0); |
|
230 delete object->objectProperty(); |
|
231 QVERIFY(object->objectProperty() == 0); |
|
232 } |
|
233 |
|
234 { |
|
235 QDeclarativeComponent component(&engine, TEST_FILE("idShortcutInvalidates.1.qml")); |
|
236 MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create()); |
|
237 QVERIFY(object != 0); |
|
238 QVERIFY(object->objectProperty() != 0); |
|
239 delete object->objectProperty(); |
|
240 QVERIFY(object->objectProperty() == 0); |
|
241 } |
|
242 } |
|
243 |
|
244 void tst_qdeclarativeecmascript::boolPropertiesEvaluateAsBool() |
|
245 { |
|
246 { |
|
247 QDeclarativeComponent component(&engine, TEST_FILE("boolPropertiesEvaluateAsBool.1.qml")); |
|
248 MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create()); |
|
249 QVERIFY(object != 0); |
|
250 QCOMPARE(object->stringProperty(), QLatin1String("pass")); |
|
251 } |
|
252 { |
|
253 QDeclarativeComponent component(&engine, TEST_FILE("boolPropertiesEvaluateAsBool.2.qml")); |
|
254 MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create()); |
|
255 QVERIFY(object != 0); |
|
256 QCOMPARE(object->stringProperty(), QLatin1String("pass")); |
|
257 } |
|
258 } |
|
259 |
|
260 void tst_qdeclarativeecmascript::signalAssignment() |
|
261 { |
|
262 { |
|
263 QDeclarativeComponent component(&engine, TEST_FILE("signalAssignment.1.qml")); |
|
264 MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create()); |
|
265 QVERIFY(object != 0); |
|
266 QCOMPARE(object->string(), QString()); |
|
267 emit object->basicSignal(); |
|
268 QCOMPARE(object->string(), QString("pass")); |
|
269 } |
|
270 |
|
271 { |
|
272 QDeclarativeComponent component(&engine, TEST_FILE("signalAssignment.2.qml")); |
|
273 MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create()); |
|
274 QVERIFY(object != 0); |
|
275 QCOMPARE(object->string(), QString()); |
|
276 emit object->argumentSignal(19, "Hello world!", 10.3); |
|
277 QCOMPARE(object->string(), QString("pass 19 Hello world! 10.3")); |
|
278 } |
|
279 } |
|
280 |
|
281 void tst_qdeclarativeecmascript::methods() |
|
282 { |
|
283 { |
|
284 QDeclarativeComponent component(&engine, TEST_FILE("methods.1.qml")); |
|
285 MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create()); |
|
286 QVERIFY(object != 0); |
|
287 QCOMPARE(object->methodCalled(), false); |
|
288 QCOMPARE(object->methodIntCalled(), false); |
|
289 emit object->basicSignal(); |
|
290 QCOMPARE(object->methodCalled(), true); |
|
291 QCOMPARE(object->methodIntCalled(), false); |
|
292 } |
|
293 |
|
294 { |
|
295 QDeclarativeComponent component(&engine, TEST_FILE("methods.2.qml")); |
|
296 MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create()); |
|
297 QVERIFY(object != 0); |
|
298 QCOMPARE(object->methodCalled(), false); |
|
299 QCOMPARE(object->methodIntCalled(), false); |
|
300 emit object->basicSignal(); |
|
301 QCOMPARE(object->methodCalled(), false); |
|
302 QCOMPARE(object->methodIntCalled(), true); |
|
303 } |
|
304 |
|
305 { |
|
306 QDeclarativeComponent component(&engine, TEST_FILE("methods.3.qml")); |
|
307 QObject *object = component.create(); |
|
308 QVERIFY(object != 0); |
|
309 QCOMPARE(object->property("test").toInt(), 19); |
|
310 } |
|
311 |
|
312 { |
|
313 QDeclarativeComponent component(&engine, TEST_FILE("methods.4.qml")); |
|
314 QObject *object = component.create(); |
|
315 QVERIFY(object != 0); |
|
316 QCOMPARE(object->property("test").toInt(), 19); |
|
317 QCOMPARE(object->property("test2").toInt(), 17); |
|
318 QCOMPARE(object->property("test3").toInt(), 16); |
|
319 } |
|
320 |
|
321 { |
|
322 QDeclarativeComponent component(&engine, TEST_FILE("methods.5.qml")); |
|
323 QObject *object = component.create(); |
|
324 QVERIFY(object != 0); |
|
325 QCOMPARE(object->property("test").toInt(), 9); |
|
326 } |
|
327 } |
|
328 |
|
329 void tst_qdeclarativeecmascript::bindingLoop() |
|
330 { |
|
331 QDeclarativeComponent component(&engine, TEST_FILE("bindingLoop.qml")); |
|
332 QString warning = component.url().toString() + ":9:9: QML MyQmlObject: Binding loop detected for property \"stringProperty\""; |
|
333 QTest::ignoreMessage(QtWarningMsg, warning.toLatin1().constData()); |
|
334 QObject *object = component.create(); |
|
335 QVERIFY(object != 0); |
|
336 } |
|
337 |
|
338 void tst_qdeclarativeecmascript::basicExpressions_data() |
|
339 { |
|
340 QTest::addColumn<QString>("expression"); |
|
341 QTest::addColumn<QVariant>("result"); |
|
342 QTest::addColumn<bool>("nest"); |
|
343 |
|
344 QTest::newRow("Syntax error (self test)") << "{console.log({'a':1'}.a)}" << QVariant() << false; |
|
345 QTest::newRow("Context property") << "a" << QVariant(1944) << false; |
|
346 QTest::newRow("Context property") << "a" << QVariant(1944) << true; |
|
347 QTest::newRow("Context property expression") << "a * 2" << QVariant(3888) << false; |
|
348 QTest::newRow("Context property expression") << "a * 2" << QVariant(3888) << true; |
|
349 QTest::newRow("Overridden context property") << "b" << QVariant("Milk") << false; |
|
350 QTest::newRow("Overridden context property") << "b" << QVariant("Cow") << true; |
|
351 QTest::newRow("Object property") << "object.stringProperty" << QVariant("Object1") << false; |
|
352 QTest::newRow("Object property") << "object.stringProperty" << QVariant("Object1") << true; |
|
353 QTest::newRow("Overridden object property") << "objectOverride.stringProperty" << QVariant("Object2") << false; |
|
354 QTest::newRow("Overridden object property") << "objectOverride.stringProperty" << QVariant("Object3") << true; |
|
355 QTest::newRow("Default object property") << "horseLegs" << QVariant(4) << false; |
|
356 QTest::newRow("Default object property") << "antLegs" << QVariant(6) << false; |
|
357 QTest::newRow("Default object property") << "emuLegs" << QVariant(2) << false; |
|
358 QTest::newRow("Nested default object property") << "horseLegs" << QVariant(4) << true; |
|
359 QTest::newRow("Nested default object property") << "antLegs" << QVariant(7) << true; |
|
360 QTest::newRow("Nested default object property") << "emuLegs" << QVariant(2) << true; |
|
361 QTest::newRow("Nested default object property") << "humanLegs" << QVariant(2) << true; |
|
362 QTest::newRow("Context property override default object property") << "millipedeLegs" << QVariant(100) << true; |
|
363 } |
|
364 |
|
365 void tst_qdeclarativeecmascript::basicExpressions() |
|
366 { |
|
367 QFETCH(QString, expression); |
|
368 QFETCH(QVariant, result); |
|
369 QFETCH(bool, nest); |
|
370 |
|
371 MyQmlObject object1; |
|
372 MyQmlObject object2; |
|
373 MyQmlObject object3; |
|
374 MyDefaultObject1 default1; |
|
375 MyDefaultObject3 default3; |
|
376 object1.setStringProperty("Object1"); |
|
377 object2.setStringProperty("Object2"); |
|
378 object3.setStringProperty("Object3"); |
|
379 |
|
380 QDeclarativeContext context(engine.rootContext()); |
|
381 QDeclarativeContext nestedContext(&context); |
|
382 |
|
383 context.setContextObject(&default1); |
|
384 context.setContextProperty("a", QVariant(1944)); |
|
385 context.setContextProperty("b", QVariant("Milk")); |
|
386 context.setContextProperty("object", &object1); |
|
387 context.setContextProperty("objectOverride", &object2); |
|
388 nestedContext.setContextObject(&default3); |
|
389 nestedContext.setContextProperty("b", QVariant("Cow")); |
|
390 nestedContext.setContextProperty("objectOverride", &object3); |
|
391 nestedContext.setContextProperty("millipedeLegs", QVariant(100)); |
|
392 |
|
393 MyExpression expr(nest?&nestedContext:&context, expression); |
|
394 QCOMPARE(expr.evaluate(), result); |
|
395 } |
|
396 |
|
397 void tst_qdeclarativeecmascript::arrayExpressions() |
|
398 { |
|
399 QObject obj1; |
|
400 QObject obj2; |
|
401 QObject obj3; |
|
402 |
|
403 QDeclarativeContext context(engine.rootContext()); |
|
404 context.setContextProperty("a", &obj1); |
|
405 context.setContextProperty("b", &obj2); |
|
406 context.setContextProperty("c", &obj3); |
|
407 |
|
408 MyExpression expr(&context, "[a, b, c, 10]"); |
|
409 QVariant result = expr.evaluate(); |
|
410 QCOMPARE(result.userType(), qMetaTypeId<QList<QObject *> >()); |
|
411 QList<QObject *> list = qvariant_cast<QList<QObject *> >(result); |
|
412 QCOMPARE(list.count(), 4); |
|
413 QCOMPARE(list.at(0), &obj1); |
|
414 QCOMPARE(list.at(1), &obj2); |
|
415 QCOMPARE(list.at(2), &obj3); |
|
416 QCOMPARE(list.at(3), (QObject *)0); |
|
417 } |
|
418 |
|
419 // Tests that modifying a context property will reevaluate expressions |
|
420 void tst_qdeclarativeecmascript::contextPropertiesTriggerReeval() |
|
421 { |
|
422 QDeclarativeContext context(engine.rootContext()); |
|
423 MyQmlObject object1; |
|
424 MyQmlObject object2; |
|
425 MyQmlObject *object3 = new MyQmlObject; |
|
426 |
|
427 object1.setStringProperty("Hello"); |
|
428 object2.setStringProperty("World"); |
|
429 |
|
430 context.setContextProperty("testProp", QVariant(1)); |
|
431 context.setContextProperty("testObj", &object1); |
|
432 context.setContextProperty("testObj2", object3); |
|
433 |
|
434 { |
|
435 MyExpression expr(&context, "testProp + 1"); |
|
436 QCOMPARE(expr.changed, false); |
|
437 QCOMPARE(expr.evaluate(), QVariant(2)); |
|
438 |
|
439 context.setContextProperty("testProp", QVariant(2)); |
|
440 QCOMPARE(expr.changed, true); |
|
441 QCOMPARE(expr.evaluate(), QVariant(3)); |
|
442 } |
|
443 |
|
444 { |
|
445 MyExpression expr(&context, "testProp + testProp + testProp"); |
|
446 QCOMPARE(expr.changed, false); |
|
447 QCOMPARE(expr.evaluate(), QVariant(6)); |
|
448 |
|
449 context.setContextProperty("testProp", QVariant(4)); |
|
450 QCOMPARE(expr.changed, true); |
|
451 QCOMPARE(expr.evaluate(), QVariant(12)); |
|
452 } |
|
453 |
|
454 { |
|
455 MyExpression expr(&context, "testObj.stringProperty"); |
|
456 QCOMPARE(expr.changed, false); |
|
457 QCOMPARE(expr.evaluate(), QVariant("Hello")); |
|
458 |
|
459 context.setContextProperty("testObj", &object2); |
|
460 QCOMPARE(expr.changed, true); |
|
461 QCOMPARE(expr.evaluate(), QVariant("World")); |
|
462 } |
|
463 |
|
464 { |
|
465 MyExpression expr(&context, "testObj.stringProperty /**/"); |
|
466 QCOMPARE(expr.changed, false); |
|
467 QCOMPARE(expr.evaluate(), QVariant("World")); |
|
468 |
|
469 context.setContextProperty("testObj", &object1); |
|
470 QCOMPARE(expr.changed, true); |
|
471 QCOMPARE(expr.evaluate(), QVariant("Hello")); |
|
472 } |
|
473 |
|
474 { |
|
475 MyExpression expr(&context, "testObj2"); |
|
476 QCOMPARE(expr.changed, false); |
|
477 QCOMPARE(expr.evaluate(), QVariant::fromValue((QObject *)object3)); |
|
478 } |
|
479 |
|
480 } |
|
481 |
|
482 void tst_qdeclarativeecmascript::objectPropertiesTriggerReeval() |
|
483 { |
|
484 QDeclarativeContext context(engine.rootContext()); |
|
485 MyQmlObject object1; |
|
486 MyQmlObject object2; |
|
487 MyQmlObject object3; |
|
488 context.setContextProperty("testObj", &object1); |
|
489 |
|
490 object1.setStringProperty(QLatin1String("Hello")); |
|
491 object2.setStringProperty(QLatin1String("Dog")); |
|
492 object3.setStringProperty(QLatin1String("Cat")); |
|
493 |
|
494 { |
|
495 MyExpression expr(&context, "testObj.stringProperty"); |
|
496 QCOMPARE(expr.changed, false); |
|
497 QCOMPARE(expr.evaluate(), QVariant("Hello")); |
|
498 |
|
499 object1.setStringProperty(QLatin1String("World")); |
|
500 QCOMPARE(expr.changed, true); |
|
501 QCOMPARE(expr.evaluate(), QVariant("World")); |
|
502 } |
|
503 |
|
504 { |
|
505 MyExpression expr(&context, "testObj.objectProperty.stringProperty"); |
|
506 QCOMPARE(expr.changed, false); |
|
507 QCOMPARE(expr.evaluate(), QVariant()); |
|
508 |
|
509 object1.setObjectProperty(&object2); |
|
510 QCOMPARE(expr.changed, true); |
|
511 expr.changed = false; |
|
512 QCOMPARE(expr.evaluate(), QVariant("Dog")); |
|
513 |
|
514 object1.setObjectProperty(&object3); |
|
515 QCOMPARE(expr.changed, true); |
|
516 expr.changed = false; |
|
517 QCOMPARE(expr.evaluate(), QVariant("Cat")); |
|
518 |
|
519 object1.setObjectProperty(0); |
|
520 QCOMPARE(expr.changed, true); |
|
521 expr.changed = false; |
|
522 QCOMPARE(expr.evaluate(), QVariant()); |
|
523 |
|
524 object1.setObjectProperty(&object3); |
|
525 QCOMPARE(expr.changed, true); |
|
526 expr.changed = false; |
|
527 QCOMPARE(expr.evaluate(), QVariant("Cat")); |
|
528 |
|
529 object3.setStringProperty("Donkey"); |
|
530 QCOMPARE(expr.changed, true); |
|
531 expr.changed = false; |
|
532 QCOMPARE(expr.evaluate(), QVariant("Donkey")); |
|
533 } |
|
534 } |
|
535 |
|
536 void tst_qdeclarativeecmascript::deferredProperties() |
|
537 { |
|
538 QDeclarativeComponent component(&engine, TEST_FILE("deferredProperties.qml")); |
|
539 MyDeferredObject *object = |
|
540 qobject_cast<MyDeferredObject *>(component.create()); |
|
541 QVERIFY(object != 0); |
|
542 QCOMPARE(object->value(), 0); |
|
543 QVERIFY(object->objectProperty() == 0); |
|
544 QVERIFY(object->objectProperty2() != 0); |
|
545 qmlExecuteDeferred(object); |
|
546 QCOMPARE(object->value(), 10); |
|
547 QVERIFY(object->objectProperty() != 0); |
|
548 MyQmlObject *qmlObject = |
|
549 qobject_cast<MyQmlObject *>(object->objectProperty()); |
|
550 QVERIFY(qmlObject != 0); |
|
551 QCOMPARE(qmlObject->value(), 10); |
|
552 object->setValue(19); |
|
553 QCOMPARE(qmlObject->value(), 19); |
|
554 } |
|
555 |
|
556 // Check errors on deferred properties are correctly emitted |
|
557 void tst_qdeclarativeecmascript::deferredPropertiesErrors() |
|
558 { |
|
559 QDeclarativeComponent component(&engine, TEST_FILE("deferredPropertiesErrors.qml")); |
|
560 MyDeferredObject *object = |
|
561 qobject_cast<MyDeferredObject *>(component.create()); |
|
562 QVERIFY(object != 0); |
|
563 QCOMPARE(object->value(), 0); |
|
564 QVERIFY(object->objectProperty() == 0); |
|
565 QVERIFY(object->objectProperty2() == 0); |
|
566 |
|
567 QString warning = component.url().toString() + ":6: Unable to assign [undefined] to QObject* objectProperty"; |
|
568 QTest::ignoreMessage(QtWarningMsg, qPrintable(warning)); |
|
569 |
|
570 qmlExecuteDeferred(object); |
|
571 |
|
572 delete object; |
|
573 } |
|
574 |
|
575 void tst_qdeclarativeecmascript::extensionObjects() |
|
576 { |
|
577 QDeclarativeComponent component(&engine, TEST_FILE("extensionObjects.qml")); |
|
578 MyExtendedObject *object = |
|
579 qobject_cast<MyExtendedObject *>(component.create()); |
|
580 QVERIFY(object != 0); |
|
581 QCOMPARE(object->baseProperty(), 13); |
|
582 QCOMPARE(object->coreProperty(), 9); |
|
583 object->setProperty("extendedProperty", QVariant(11)); |
|
584 object->setProperty("baseExtendedProperty", QVariant(92)); |
|
585 QCOMPARE(object->coreProperty(), 11); |
|
586 QCOMPARE(object->baseProperty(), 92); |
|
587 |
|
588 MyExtendedObject *nested = qobject_cast<MyExtendedObject*>(qvariant_cast<QObject *>(object->property("nested"))); |
|
589 QVERIFY(nested); |
|
590 QCOMPARE(nested->baseProperty(), 13); |
|
591 QCOMPARE(nested->coreProperty(), 9); |
|
592 nested->setProperty("extendedProperty", QVariant(11)); |
|
593 nested->setProperty("baseExtendedProperty", QVariant(92)); |
|
594 QCOMPARE(nested->coreProperty(), 11); |
|
595 QCOMPARE(nested->baseProperty(), 92); |
|
596 |
|
597 } |
|
598 |
|
599 void tst_qdeclarativeecmascript::overrideExtensionProperties() |
|
600 { |
|
601 QDeclarativeComponent component(&engine, TEST_FILE("extensionObjectsPropertyOverride.qml")); |
|
602 OverrideDefaultPropertyObject *object = |
|
603 qobject_cast<OverrideDefaultPropertyObject *>(component.create()); |
|
604 QVERIFY(object != 0); |
|
605 QVERIFY(object->secondProperty() != 0); |
|
606 QVERIFY(object->firstProperty() == 0); |
|
607 } |
|
608 |
|
609 void tst_qdeclarativeecmascript::attachedProperties() |
|
610 { |
|
611 QDeclarativeComponent component(&engine, TEST_FILE("attachedProperty.qml")); |
|
612 QObject *object = component.create(); |
|
613 QVERIFY(object != 0); |
|
614 QCOMPARE(object->property("a").toInt(), 19); |
|
615 QCOMPARE(object->property("b").toInt(), 19); |
|
616 QCOMPARE(object->property("c").toInt(), 19); |
|
617 QCOMPARE(object->property("d").toInt(), 19); |
|
618 |
|
619 // ### Need to test attached property assignment |
|
620 } |
|
621 |
|
622 void tst_qdeclarativeecmascript::enums() |
|
623 { |
|
624 // Existant enums |
|
625 { |
|
626 QDeclarativeComponent component(&engine, TEST_FILE("enums.1.qml")); |
|
627 QObject *object = component.create(); |
|
628 QVERIFY(object != 0); |
|
629 |
|
630 QCOMPARE(object->property("a").toInt(), 0); |
|
631 QCOMPARE(object->property("b").toInt(), 1); |
|
632 QCOMPARE(object->property("c").toInt(), 2); |
|
633 QCOMPARE(object->property("d").toInt(), 3); |
|
634 QCOMPARE(object->property("e").toInt(), 0); |
|
635 QCOMPARE(object->property("f").toInt(), 1); |
|
636 QCOMPARE(object->property("g").toInt(), 2); |
|
637 QCOMPARE(object->property("h").toInt(), 3); |
|
638 QCOMPARE(object->property("i").toInt(), 19); |
|
639 QCOMPARE(object->property("j").toInt(), 19); |
|
640 } |
|
641 // Non-existent enums |
|
642 { |
|
643 QDeclarativeComponent component(&engine, TEST_FILE("enums.2.qml")); |
|
644 |
|
645 QString warning1 = component.url().toString() + ":5: Unable to assign [undefined] to int a"; |
|
646 QString warning2 = component.url().toString() + ":6: Unable to assign [undefined] to int b"; |
|
647 QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1)); |
|
648 QTest::ignoreMessage(QtWarningMsg, qPrintable(warning2)); |
|
649 |
|
650 QObject *object = component.create(); |
|
651 QVERIFY(object != 0); |
|
652 QCOMPARE(object->property("a").toInt(), 0); |
|
653 QCOMPARE(object->property("b").toInt(), 0); |
|
654 } |
|
655 } |
|
656 |
|
657 void tst_qdeclarativeecmascript::valueTypeFunctions() |
|
658 { |
|
659 QDeclarativeComponent component(&engine, TEST_FILE("valueTypeFunctions.qml")); |
|
660 MyTypeObject *obj = qobject_cast<MyTypeObject*>(component.create()); |
|
661 QVERIFY(obj != 0); |
|
662 QCOMPARE(obj->rectProperty(), QRect(0,0,100,100)); |
|
663 QCOMPARE(obj->rectFProperty(), QRectF(0,0.5,100,99.5)); |
|
664 } |
|
665 |
|
666 /* |
|
667 Tests that writing a constant to a property with a binding on it disables the |
|
668 binding. |
|
669 */ |
|
670 void tst_qdeclarativeecmascript::constantsOverrideBindings() |
|
671 { |
|
672 // From ECMAScript |
|
673 { |
|
674 QDeclarativeComponent component(&engine, TEST_FILE("constantsOverrideBindings.1.qml")); |
|
675 MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create()); |
|
676 QVERIFY(object != 0); |
|
677 |
|
678 QCOMPARE(object->property("c2").toInt(), 0); |
|
679 object->setProperty("c1", QVariant(9)); |
|
680 QCOMPARE(object->property("c2").toInt(), 9); |
|
681 |
|
682 emit object->basicSignal(); |
|
683 |
|
684 QCOMPARE(object->property("c2").toInt(), 13); |
|
685 object->setProperty("c1", QVariant(8)); |
|
686 QCOMPARE(object->property("c2").toInt(), 13); |
|
687 } |
|
688 |
|
689 // During construction |
|
690 { |
|
691 QDeclarativeComponent component(&engine, TEST_FILE("constantsOverrideBindings.2.qml")); |
|
692 MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create()); |
|
693 QVERIFY(object != 0); |
|
694 |
|
695 QCOMPARE(object->property("c1").toInt(), 0); |
|
696 QCOMPARE(object->property("c2").toInt(), 10); |
|
697 object->setProperty("c1", QVariant(9)); |
|
698 QCOMPARE(object->property("c1").toInt(), 9); |
|
699 QCOMPARE(object->property("c2").toInt(), 10); |
|
700 } |
|
701 |
|
702 #if 0 |
|
703 // From C++ |
|
704 { |
|
705 QDeclarativeComponent component(&engine, TEST_FILE("constantsOverrideBindings.3.qml")); |
|
706 MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create()); |
|
707 QVERIFY(object != 0); |
|
708 |
|
709 QCOMPARE(object->property("c2").toInt(), 0); |
|
710 object->setProperty("c1", QVariant(9)); |
|
711 QCOMPARE(object->property("c2").toInt(), 9); |
|
712 |
|
713 object->setProperty("c2", QVariant(13)); |
|
714 QCOMPARE(object->property("c2").toInt(), 13); |
|
715 object->setProperty("c1", QVariant(7)); |
|
716 QCOMPARE(object->property("c1").toInt(), 7); |
|
717 QCOMPARE(object->property("c2").toInt(), 13); |
|
718 } |
|
719 #endif |
|
720 } |
|
721 |
|
722 /* |
|
723 Tests that assigning a binding to a property that already has a binding causes |
|
724 the original binding to be disabled. |
|
725 */ |
|
726 void tst_qdeclarativeecmascript::outerBindingOverridesInnerBinding() |
|
727 { |
|
728 QDeclarativeComponent component(&engine, |
|
729 TEST_FILE("outerBindingOverridesInnerBinding.qml")); |
|
730 MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create()); |
|
731 QVERIFY(object != 0); |
|
732 |
|
733 QCOMPARE(object->property("c1").toInt(), 0); |
|
734 QCOMPARE(object->property("c2").toInt(), 0); |
|
735 QCOMPARE(object->property("c3").toInt(), 0); |
|
736 |
|
737 object->setProperty("c1", QVariant(9)); |
|
738 QCOMPARE(object->property("c1").toInt(), 9); |
|
739 QCOMPARE(object->property("c2").toInt(), 0); |
|
740 QCOMPARE(object->property("c3").toInt(), 0); |
|
741 |
|
742 object->setProperty("c3", QVariant(8)); |
|
743 QCOMPARE(object->property("c1").toInt(), 9); |
|
744 QCOMPARE(object->property("c2").toInt(), 8); |
|
745 QCOMPARE(object->property("c3").toInt(), 8); |
|
746 } |
|
747 |
|
748 /* |
|
749 Access a non-existent attached object. |
|
750 |
|
751 Tests for a regression where this used to crash. |
|
752 */ |
|
753 void tst_qdeclarativeecmascript::nonExistantAttachedObject() |
|
754 { |
|
755 QDeclarativeComponent component(&engine, TEST_FILE("nonExistantAttachedObject.qml")); |
|
756 |
|
757 QString warning = component.url().toString() + ":4: Unable to assign [undefined] to QString stringProperty"; |
|
758 QTest::ignoreMessage(QtWarningMsg, qPrintable(warning)); |
|
759 |
|
760 QObject *object = component.create(); |
|
761 QVERIFY(object != 0); |
|
762 } |
|
763 |
|
764 void tst_qdeclarativeecmascript::scope() |
|
765 { |
|
766 { |
|
767 QDeclarativeComponent component(&engine, TEST_FILE("scope.qml")); |
|
768 QObject *object = component.create(); |
|
769 QVERIFY(object != 0); |
|
770 |
|
771 QCOMPARE(object->property("test1").toInt(), 1); |
|
772 QCOMPARE(object->property("test2").toInt(), 2); |
|
773 QCOMPARE(object->property("test3").toString(), QString("1Test")); |
|
774 QCOMPARE(object->property("test4").toString(), QString("2Test")); |
|
775 QCOMPARE(object->property("test5").toInt(), 1); |
|
776 QCOMPARE(object->property("test6").toInt(), 1); |
|
777 QCOMPARE(object->property("test7").toInt(), 2); |
|
778 QCOMPARE(object->property("test8").toInt(), 2); |
|
779 QCOMPARE(object->property("test9").toInt(), 1); |
|
780 QCOMPARE(object->property("test10").toInt(), 3); |
|
781 } |
|
782 |
|
783 { |
|
784 QDeclarativeComponent component(&engine, TEST_FILE("scope.2.qml")); |
|
785 QObject *object = component.create(); |
|
786 QVERIFY(object != 0); |
|
787 |
|
788 QCOMPARE(object->property("test1").toInt(), 19); |
|
789 QCOMPARE(object->property("test2").toInt(), 19); |
|
790 QCOMPARE(object->property("test3").toInt(), 11); |
|
791 QCOMPARE(object->property("test4").toInt(), 11); |
|
792 QCOMPARE(object->property("test5").toInt(), 24); |
|
793 QCOMPARE(object->property("test6").toInt(), 24); |
|
794 } |
|
795 |
|
796 { |
|
797 QDeclarativeComponent component(&engine, TEST_FILE("scope.3.qml")); |
|
798 QObject *object = component.create(); |
|
799 QVERIFY(object != 0); |
|
800 |
|
801 QCOMPARE(object->property("test1").toBool(), true); |
|
802 QCOMPARE(object->property("test2").toBool(), true); |
|
803 QCOMPARE(object->property("test3").toBool(), true); |
|
804 } |
|
805 |
|
806 // Signal argument scope |
|
807 { |
|
808 QDeclarativeComponent component(&engine, TEST_FILE("scope.4.qml")); |
|
809 MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create()); |
|
810 QVERIFY(object != 0); |
|
811 |
|
812 QCOMPARE(object->property("test").toInt(), 0); |
|
813 QCOMPARE(object->property("test2").toString(), QString()); |
|
814 |
|
815 emit object->argumentSignal(13, "Argument Scope", 9); |
|
816 |
|
817 QCOMPARE(object->property("test").toInt(), 13); |
|
818 QCOMPARE(object->property("test2").toString(), QString("Argument Scope")); |
|
819 |
|
820 delete object; |
|
821 } |
|
822 } |
|
823 |
|
824 /* |
|
825 Tests that "any" type passes through a synthesized signal parameter. This |
|
826 is essentially a test of QDeclarativeMetaType::copy() |
|
827 */ |
|
828 void tst_qdeclarativeecmascript::signalParameterTypes() |
|
829 { |
|
830 QDeclarativeComponent component(&engine, TEST_FILE("signalParameterTypes.qml")); |
|
831 MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create()); |
|
832 QVERIFY(object != 0); |
|
833 |
|
834 emit object->basicSignal(); |
|
835 |
|
836 QCOMPARE(object->property("intProperty").toInt(), 10); |
|
837 QCOMPARE(object->property("realProperty").toReal(), 19.2); |
|
838 QVERIFY(object->property("colorProperty").value<QColor>() == QColor(255, 255, 0, 255)); |
|
839 QVERIFY(object->property("variantProperty") == QVariant::fromValue(QColor(255, 0, 255, 255))); |
|
840 } |
|
841 |
|
842 /* |
|
843 Test that two JS objects for the same QObject compare as equal. |
|
844 */ |
|
845 void tst_qdeclarativeecmascript::objectsCompareAsEqual() |
|
846 { |
|
847 QDeclarativeComponent component(&engine, TEST_FILE("objectsCompareAsEqual.qml")); |
|
848 QObject *object = component.create(); |
|
849 QVERIFY(object != 0); |
|
850 |
|
851 QCOMPARE(object->property("test1").toBool(), true); |
|
852 QCOMPARE(object->property("test2").toBool(), true); |
|
853 QCOMPARE(object->property("test3").toBool(), true); |
|
854 QCOMPARE(object->property("test4").toBool(), true); |
|
855 QCOMPARE(object->property("test5").toBool(), true); |
|
856 } |
|
857 |
|
858 /* |
|
859 Confirm bindings and alias properties can coexist. |
|
860 |
|
861 Tests for a regression where the binding would not reevaluate. |
|
862 */ |
|
863 void tst_qdeclarativeecmascript::aliasPropertyAndBinding() |
|
864 { |
|
865 QDeclarativeComponent component(&engine, TEST_FILE("aliasPropertyAndBinding.qml")); |
|
866 QObject *object = component.create(); |
|
867 QVERIFY(object != 0); |
|
868 |
|
869 QCOMPARE(object->property("c2").toInt(), 3); |
|
870 QCOMPARE(object->property("c3").toInt(), 3); |
|
871 |
|
872 object->setProperty("c2", QVariant(19)); |
|
873 |
|
874 QCOMPARE(object->property("c2").toInt(), 19); |
|
875 QCOMPARE(object->property("c3").toInt(), 19); |
|
876 } |
|
877 |
|
878 void tst_qdeclarativeecmascript::dynamicCreation_data() |
|
879 { |
|
880 QTest::addColumn<QString>("method"); |
|
881 QTest::addColumn<QString>("createdName"); |
|
882 |
|
883 QTest::newRow("One") << "createOne" << "objectOne"; |
|
884 QTest::newRow("Two") << "createTwo" << "objectTwo"; |
|
885 QTest::newRow("Three") << "createThree" << "objectThree"; |
|
886 } |
|
887 |
|
888 /* |
|
889 Test using createQmlObject to dynamically generate an item |
|
890 Also using createComponent is tested. |
|
891 */ |
|
892 void tst_qdeclarativeecmascript::dynamicCreation() |
|
893 { |
|
894 QFETCH(QString, method); |
|
895 QFETCH(QString, createdName); |
|
896 |
|
897 QDeclarativeComponent component(&engine, TEST_FILE("dynamicCreation.qml")); |
|
898 MyQmlObject *object = qobject_cast<MyQmlObject*>(component.create()); |
|
899 QVERIFY(object != 0); |
|
900 |
|
901 QMetaObject::invokeMethod(object, method.toUtf8()); |
|
902 QObject *created = object->objectProperty(); |
|
903 QVERIFY(created); |
|
904 QCOMPARE(created->objectName(), createdName); |
|
905 } |
|
906 |
|
907 /* |
|
908 Tests the destroy function |
|
909 */ |
|
910 void tst_qdeclarativeecmascript::dynamicDestruction() |
|
911 { |
|
912 QDeclarativeComponent component(&engine, TEST_FILE("dynamicDeletion.qml")); |
|
913 QDeclarativeGuard<MyQmlObject> object = qobject_cast<MyQmlObject*>(component.create()); |
|
914 QVERIFY(object != 0); |
|
915 QDeclarativeGuard<QObject> createdQmlObject = 0; |
|
916 |
|
917 QMetaObject::invokeMethod(object, "create"); |
|
918 createdQmlObject = object->objectProperty(); |
|
919 QVERIFY(createdQmlObject); |
|
920 QCOMPARE(createdQmlObject->objectName(), QString("emptyObject")); |
|
921 |
|
922 QMetaObject::invokeMethod(object, "killOther"); |
|
923 QVERIFY(createdQmlObject); |
|
924 QCoreApplication::instance()->processEvents(QEventLoop::DeferredDeletion); |
|
925 QVERIFY(createdQmlObject); |
|
926 for (int ii = 0; createdQmlObject && ii < 50; ++ii) { // After 5 seconds we should give up |
|
927 if (createdQmlObject) { |
|
928 QTest::qWait(100); |
|
929 QCoreApplication::instance()->processEvents(QEventLoop::DeferredDeletion); |
|
930 } |
|
931 } |
|
932 QVERIFY(!createdQmlObject); |
|
933 |
|
934 QDeclarativeEngine::setObjectOwnership(object, QDeclarativeEngine::JavaScriptOwnership); |
|
935 QMetaObject::invokeMethod(object, "killMe"); |
|
936 QVERIFY(object); |
|
937 QTest::qWait(0); |
|
938 QCoreApplication::instance()->processEvents(QEventLoop::DeferredDeletion); |
|
939 QVERIFY(!object); |
|
940 } |
|
941 |
|
942 /* |
|
943 tests that id.toString() works |
|
944 */ |
|
945 void tst_qdeclarativeecmascript::objectToString() |
|
946 { |
|
947 QDeclarativeComponent component(&engine, TEST_FILE("declarativeToString.qml")); |
|
948 MyQmlObject *object = qobject_cast<MyQmlObject*>(component.create()); |
|
949 QVERIFY(object != 0); |
|
950 QMetaObject::invokeMethod(object, "testToString"); |
|
951 QVERIFY(object->stringProperty().startsWith("MyQmlObject_QML_")); |
|
952 QVERIFY(object->stringProperty().endsWith(", \"objName\")")); |
|
953 } |
|
954 |
|
955 /* |
|
956 Tests bindings that indirectly cause their own deletion work. |
|
957 |
|
958 This test is best run under valgrind to ensure no invalid memory access occur. |
|
959 */ |
|
960 void tst_qdeclarativeecmascript::selfDeletingBinding() |
|
961 { |
|
962 { |
|
963 QDeclarativeComponent component(&engine, TEST_FILE("selfDeletingBinding.qml")); |
|
964 QObject *object = component.create(); |
|
965 QVERIFY(object != 0); |
|
966 object->setProperty("triggerDelete", true); |
|
967 } |
|
968 |
|
969 { |
|
970 QDeclarativeComponent component(&engine, TEST_FILE("selfDeletingBinding.2.qml")); |
|
971 QObject *object = component.create(); |
|
972 QVERIFY(object != 0); |
|
973 object->setProperty("triggerDelete", true); |
|
974 } |
|
975 } |
|
976 |
|
977 /* |
|
978 Test that extended object properties can be accessed. |
|
979 |
|
980 This test a regression where this used to crash. The issue was specificially |
|
981 for extended objects that did not include a synthesized meta object (so non-root |
|
982 and no synthesiszed properties). |
|
983 */ |
|
984 void tst_qdeclarativeecmascript::extendedObjectPropertyLookup() |
|
985 { |
|
986 QDeclarativeComponent component(&engine, TEST_FILE("extendedObjectPropertyLookup.qml")); |
|
987 QObject *object = component.create(); |
|
988 QVERIFY(object != 0); |
|
989 } |
|
990 |
|
991 /* |
|
992 Test file/lineNumbers for binding/Script errors. |
|
993 */ |
|
994 void tst_qdeclarativeecmascript::scriptErrors() |
|
995 { |
|
996 QDeclarativeComponent component(&engine, TEST_FILE("scriptErrors.qml")); |
|
997 QString url = component.url().toString(); |
|
998 |
|
999 QString warning1 = url.left(url.length() - 3) + "js:2: Error: Invalid write to global property \"a\""; |
|
1000 QString warning2 = url + ":5: TypeError: Result of expression 'a' [undefined] is not an object."; |
|
1001 QString warning3 = url.left(url.length() - 3) + "js:4: Error: Invalid write to global property \"a\""; |
|
1002 QString warning4 = url + ":10: TypeError: Result of expression 'a' [undefined] is not an object."; |
|
1003 QString warning5 = url + ":8: TypeError: Result of expression 'a' [undefined] is not an object."; |
|
1004 QString warning6 = url + ":7: Unable to assign [undefined] to int x"; |
|
1005 QString warning7 = url + ":12: Error: Cannot assign to read-only property \"trueProperty\""; |
|
1006 QString warning8 = url + ":13: Error: Cannot assign to non-existent property \"fakeProperty\""; |
|
1007 |
|
1008 QTest::ignoreMessage(QtWarningMsg, warning1.toLatin1().constData()); |
|
1009 QTest::ignoreMessage(QtWarningMsg, warning2.toLatin1().constData()); |
|
1010 QTest::ignoreMessage(QtWarningMsg, warning3.toLatin1().constData()); |
|
1011 QTest::ignoreMessage(QtWarningMsg, warning5.toLatin1().constData()); |
|
1012 QTest::ignoreMessage(QtWarningMsg, warning6.toLatin1().constData()); |
|
1013 MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create()); |
|
1014 QVERIFY(object != 0); |
|
1015 |
|
1016 QTest::ignoreMessage(QtWarningMsg, warning4.toLatin1().constData()); |
|
1017 emit object->basicSignal(); |
|
1018 |
|
1019 QTest::ignoreMessage(QtWarningMsg, warning7.toLatin1().constData()); |
|
1020 emit object->anotherBasicSignal(); |
|
1021 |
|
1022 QTest::ignoreMessage(QtWarningMsg, warning8.toLatin1().constData()); |
|
1023 emit object->thirdBasicSignal(); |
|
1024 } |
|
1025 |
|
1026 /* |
|
1027 Test file/lineNumbers for inline functions. |
|
1028 */ |
|
1029 void tst_qdeclarativeecmascript::functionErrors() |
|
1030 { |
|
1031 QDeclarativeComponent component(&engine, TEST_FILE("functionErrors.qml")); |
|
1032 QString url = component.url().toString(); |
|
1033 |
|
1034 QString warning = url + ":5: Error: Invalid write to global property \"a\""; |
|
1035 |
|
1036 QTest::ignoreMessage(QtWarningMsg, warning.toLatin1().constData()); |
|
1037 |
|
1038 QObject *object = component.create(); |
|
1039 QVERIFY(object != 0); |
|
1040 delete object; |
|
1041 } |
|
1042 |
|
1043 /* |
|
1044 Test various errors that can occur when assigning a property from script |
|
1045 */ |
|
1046 void tst_qdeclarativeecmascript::propertyAssignmentErrors() |
|
1047 { |
|
1048 QDeclarativeComponent component(&engine, TEST_FILE("propertyAssignmentErrors.qml")); |
|
1049 |
|
1050 QString url = component.url().toString(); |
|
1051 |
|
1052 QString warning1 = url + ":11:Error: Cannot assign [undefined] to int"; |
|
1053 QString warning2 = url + ":17:Error: Cannot assign QString to int"; |
|
1054 |
|
1055 QTest::ignoreMessage(QtDebugMsg, warning1.toLatin1().constData()); |
|
1056 QTest::ignoreMessage(QtDebugMsg, warning2.toLatin1().constData()); |
|
1057 |
|
1058 QObject *object = component.create(); |
|
1059 QVERIFY(object != 0); |
|
1060 |
|
1061 delete object; |
|
1062 } |
|
1063 |
|
1064 /* |
|
1065 Test bindings still work when the reeval is triggered from within |
|
1066 a signal script. |
|
1067 */ |
|
1068 void tst_qdeclarativeecmascript::signalTriggeredBindings() |
|
1069 { |
|
1070 QDeclarativeComponent component(&engine, TEST_FILE("signalTriggeredBindings.qml")); |
|
1071 MyQmlObject *object = qobject_cast<MyQmlObject*>(component.create()); |
|
1072 QVERIFY(object != 0); |
|
1073 |
|
1074 QCOMPARE(object->property("base").toReal(), 50.); |
|
1075 QCOMPARE(object->property("test1").toReal(), 50.); |
|
1076 QCOMPARE(object->property("test2").toReal(), 50.); |
|
1077 |
|
1078 object->basicSignal(); |
|
1079 |
|
1080 QCOMPARE(object->property("base").toReal(), 200.); |
|
1081 QCOMPARE(object->property("test1").toReal(), 200.); |
|
1082 QCOMPARE(object->property("test2").toReal(), 200.); |
|
1083 |
|
1084 object->argumentSignal(10, QString(), 10); |
|
1085 |
|
1086 QCOMPARE(object->property("base").toReal(), 400.); |
|
1087 QCOMPARE(object->property("test1").toReal(), 400.); |
|
1088 QCOMPARE(object->property("test2").toReal(), 400.); |
|
1089 } |
|
1090 |
|
1091 /* |
|
1092 Test that list properties can be iterated from ECMAScript |
|
1093 */ |
|
1094 void tst_qdeclarativeecmascript::listProperties() |
|
1095 { |
|
1096 QDeclarativeComponent component(&engine, TEST_FILE("listProperties.qml")); |
|
1097 MyQmlObject *object = qobject_cast<MyQmlObject*>(component.create()); |
|
1098 QVERIFY(object != 0); |
|
1099 |
|
1100 QCOMPARE(object->property("test1").toInt(), 21); |
|
1101 QCOMPARE(object->property("test2").toInt(), 2); |
|
1102 QCOMPARE(object->property("test3").toBool(), true); |
|
1103 QCOMPARE(object->property("test4").toBool(), true); |
|
1104 } |
|
1105 |
|
1106 void tst_qdeclarativeecmascript::exceptionClearsOnReeval() |
|
1107 { |
|
1108 QDeclarativeComponent component(&engine, TEST_FILE("exceptionClearsOnReeval.qml")); |
|
1109 QString url = component.url().toString(); |
|
1110 |
|
1111 QString warning = url + ":4: TypeError: Result of expression 'objectProperty' [null] is not an object."; |
|
1112 |
|
1113 QTest::ignoreMessage(QtWarningMsg, warning.toLatin1().constData()); |
|
1114 MyQmlObject *object = qobject_cast<MyQmlObject*>(component.create()); |
|
1115 QVERIFY(object != 0); |
|
1116 |
|
1117 QCOMPARE(object->property("test").toBool(), false); |
|
1118 |
|
1119 MyQmlObject object2; |
|
1120 MyQmlObject object3; |
|
1121 object2.setObjectProperty(&object3); |
|
1122 object->setObjectProperty(&object2); |
|
1123 |
|
1124 QCOMPARE(object->property("test").toBool(), true); |
|
1125 } |
|
1126 |
|
1127 void tst_qdeclarativeecmascript::exceptionSlotProducesWarning() |
|
1128 { |
|
1129 QDeclarativeComponent component(&engine, TEST_FILE("exceptionProducesWarning.qml")); |
|
1130 QString url = component.url().toString(); |
|
1131 |
|
1132 QString warning = component.url().toString() + ":6: Error: JS exception"; |
|
1133 |
|
1134 QTest::ignoreMessage(QtWarningMsg, warning.toLatin1().constData()); |
|
1135 MyQmlObject *object = qobject_cast<MyQmlObject*>(component.create()); |
|
1136 QVERIFY(object != 0); |
|
1137 } |
|
1138 |
|
1139 void tst_qdeclarativeecmascript::exceptionBindingProducesWarning() |
|
1140 { |
|
1141 QDeclarativeComponent component(&engine, TEST_FILE("exceptionProducesWarning2.qml")); |
|
1142 QString url = component.url().toString(); |
|
1143 |
|
1144 QString warning = component.url().toString() + ":5: Error: JS exception"; |
|
1145 |
|
1146 QTest::ignoreMessage(QtWarningMsg, warning.toLatin1().constData()); |
|
1147 MyQmlObject *object = qobject_cast<MyQmlObject*>(component.create()); |
|
1148 QVERIFY(object != 0); |
|
1149 } |
|
1150 |
|
1151 static int transientErrorsMsgCount = 0; |
|
1152 static void transientErrorsMsgHandler(QtMsgType, const char *) |
|
1153 { |
|
1154 ++transientErrorsMsgCount; |
|
1155 } |
|
1156 |
|
1157 // Check that transient binding errors are not displayed |
|
1158 void tst_qdeclarativeecmascript::transientErrors() |
|
1159 { |
|
1160 { |
|
1161 QDeclarativeComponent component(&engine, TEST_FILE("transientErrors.qml")); |
|
1162 |
|
1163 transientErrorsMsgCount = 0; |
|
1164 QtMsgHandler old = qInstallMsgHandler(transientErrorsMsgHandler); |
|
1165 |
|
1166 QObject *object = component.create(); |
|
1167 QVERIFY(object != 0); |
|
1168 |
|
1169 qInstallMsgHandler(old); |
|
1170 |
|
1171 QCOMPARE(transientErrorsMsgCount, 0); |
|
1172 } |
|
1173 |
|
1174 // One binding erroring multiple times, but then resolving |
|
1175 { |
|
1176 QDeclarativeComponent component(&engine, TEST_FILE("transientErrors.2.qml")); |
|
1177 |
|
1178 transientErrorsMsgCount = 0; |
|
1179 QtMsgHandler old = qInstallMsgHandler(transientErrorsMsgHandler); |
|
1180 |
|
1181 QObject *object = component.create(); |
|
1182 QVERIFY(object != 0); |
|
1183 |
|
1184 qInstallMsgHandler(old); |
|
1185 |
|
1186 QCOMPARE(transientErrorsMsgCount, 0); |
|
1187 } |
|
1188 } |
|
1189 |
|
1190 // Check that errors during shutdown are minimized |
|
1191 void tst_qdeclarativeecmascript::shutdownErrors() |
|
1192 { |
|
1193 QDeclarativeComponent component(&engine, TEST_FILE("shutdownErrors.qml")); |
|
1194 QObject *object = component.create(); |
|
1195 QVERIFY(object != 0); |
|
1196 |
|
1197 transientErrorsMsgCount = 0; |
|
1198 QtMsgHandler old = qInstallMsgHandler(transientErrorsMsgHandler); |
|
1199 |
|
1200 delete object; |
|
1201 |
|
1202 qInstallMsgHandler(old); |
|
1203 QCOMPARE(transientErrorsMsgCount, 0); |
|
1204 } |
|
1205 |
|
1206 void tst_qdeclarativeecmascript::compositePropertyType() |
|
1207 { |
|
1208 QDeclarativeComponent component(&engine, TEST_FILE("compositePropertyType.qml")); |
|
1209 QTest::ignoreMessage(QtDebugMsg, "hello world"); |
|
1210 QObject *object = qobject_cast<QObject *>(component.create()); |
|
1211 delete object; |
|
1212 } |
|
1213 |
|
1214 // QTBUG-5759 |
|
1215 void tst_qdeclarativeecmascript::jsObject() |
|
1216 { |
|
1217 QDeclarativeComponent component(&engine, TEST_FILE("jsObject.qml")); |
|
1218 QObject *object = component.create(); |
|
1219 QVERIFY(object != 0); |
|
1220 |
|
1221 QCOMPARE(object->property("test").toInt(), 92); |
|
1222 |
|
1223 delete object; |
|
1224 } |
|
1225 |
|
1226 void tst_qdeclarativeecmascript::undefinedResetsProperty() |
|
1227 { |
|
1228 { |
|
1229 QDeclarativeComponent component(&engine, TEST_FILE("undefinedResetsProperty.qml")); |
|
1230 QObject *object = component.create(); |
|
1231 QVERIFY(object != 0); |
|
1232 |
|
1233 QCOMPARE(object->property("resettableProperty").toInt(), 92); |
|
1234 |
|
1235 object->setProperty("setUndefined", true); |
|
1236 |
|
1237 QCOMPARE(object->property("resettableProperty").toInt(), 13); |
|
1238 |
|
1239 object->setProperty("setUndefined", false); |
|
1240 |
|
1241 QCOMPARE(object->property("resettableProperty").toInt(), 92); |
|
1242 |
|
1243 delete object; |
|
1244 } |
|
1245 { |
|
1246 QDeclarativeComponent component(&engine, TEST_FILE("undefinedResetsProperty.2.qml")); |
|
1247 QObject *object = component.create(); |
|
1248 QVERIFY(object != 0); |
|
1249 |
|
1250 QCOMPARE(object->property("resettableProperty").toInt(), 19); |
|
1251 |
|
1252 QMetaObject::invokeMethod(object, "doReset"); |
|
1253 |
|
1254 QCOMPARE(object->property("resettableProperty").toInt(), 13); |
|
1255 |
|
1256 delete object; |
|
1257 } |
|
1258 } |
|
1259 |
|
1260 // QTBUG-6781 |
|
1261 void tst_qdeclarativeecmascript::bug1() |
|
1262 { |
|
1263 QDeclarativeComponent component(&engine, TEST_FILE("bug.1.qml")); |
|
1264 QObject *object = component.create(); |
|
1265 QVERIFY(object != 0); |
|
1266 |
|
1267 QCOMPARE(object->property("test").toInt(), 14); |
|
1268 |
|
1269 object->setProperty("a", 11); |
|
1270 |
|
1271 QCOMPARE(object->property("test").toInt(), 3); |
|
1272 |
|
1273 object->setProperty("b", true); |
|
1274 |
|
1275 QCOMPARE(object->property("test").toInt(), 9); |
|
1276 |
|
1277 delete object; |
|
1278 } |
|
1279 |
|
1280 void tst_qdeclarativeecmascript::bug2() |
|
1281 { |
|
1282 QDeclarativeComponent component(&engine); |
|
1283 component.setData("import Qt.test 1.0;\nQPlainTextEdit { width: 100 }", QUrl()); |
|
1284 |
|
1285 QObject *object = component.create(); |
|
1286 QVERIFY(object != 0); |
|
1287 |
|
1288 delete object; |
|
1289 } |
|
1290 |
|
1291 // Don't crash in createObject when the component has errors. |
|
1292 void tst_qdeclarativeecmascript::dynamicCreationCrash() |
|
1293 { |
|
1294 QDeclarativeComponent component(&engine, TEST_FILE("dynamicCreation.qml")); |
|
1295 MyQmlObject *object = qobject_cast<MyQmlObject*>(component.create()); |
|
1296 QVERIFY(object != 0); |
|
1297 |
|
1298 QTest::ignoreMessage(QtWarningMsg, "QDeclarativeComponent: Component is not ready"); |
|
1299 QMetaObject::invokeMethod(object, "dontCrash"); |
|
1300 QObject *created = object->objectProperty(); |
|
1301 QVERIFY(created == 0); |
|
1302 } |
|
1303 |
|
1304 //QTBUG-9367 |
|
1305 void tst_qdeclarativeecmascript::regExpBug() |
|
1306 { |
|
1307 QDeclarativeComponent component(&engine, TEST_FILE("regExp.qml")); |
|
1308 MyQmlObject *object = qobject_cast<MyQmlObject*>(component.create()); |
|
1309 QVERIFY(object != 0); |
|
1310 QCOMPARE(object->regExp().pattern(), QLatin1String("[a-zA-z]")); |
|
1311 } |
|
1312 |
|
1313 void tst_qdeclarativeecmascript::callQtInvokables() |
|
1314 { |
|
1315 MyInvokableObject o; |
|
1316 |
|
1317 QDeclarativeEngine qmlengine; |
|
1318 QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(&qmlengine); |
|
1319 QScriptEngine *engine = &ep->scriptEngine; |
|
1320 ep->globalClass->explicitSetProperty("object", ep->objectClass->newQObject(&o)); |
|
1321 |
|
1322 // Non-existent methods |
|
1323 o.reset(); |
|
1324 QCOMPARE(engine->evaluate("object.method_nonexistent()").isError(), true); |
|
1325 QCOMPARE(o.error(), false); |
|
1326 QCOMPARE(o.invoked(), -1); |
|
1327 QCOMPARE(o.actuals().count(), 0); |
|
1328 |
|
1329 o.reset(); |
|
1330 QCOMPARE(engine->evaluate("object.method_nonexistent(10, 11)").isError(), true); |
|
1331 QCOMPARE(o.error(), false); |
|
1332 QCOMPARE(o.invoked(), -1); |
|
1333 QCOMPARE(o.actuals().count(), 0); |
|
1334 |
|
1335 // Insufficient arguments |
|
1336 o.reset(); |
|
1337 QCOMPARE(engine->evaluate("object.method_int()").isError(), true); |
|
1338 QCOMPARE(o.error(), false); |
|
1339 QCOMPARE(o.invoked(), -1); |
|
1340 QCOMPARE(o.actuals().count(), 0); |
|
1341 |
|
1342 o.reset(); |
|
1343 QCOMPARE(engine->evaluate("object.method_intint(10)").isError(), true); |
|
1344 QCOMPARE(o.error(), false); |
|
1345 QCOMPARE(o.invoked(), -1); |
|
1346 QCOMPARE(o.actuals().count(), 0); |
|
1347 |
|
1348 // Excessive arguments |
|
1349 o.reset(); |
|
1350 QCOMPARE(engine->evaluate("object.method_int(10, 11)").isUndefined(), true); |
|
1351 QCOMPARE(o.error(), false); |
|
1352 QCOMPARE(o.invoked(), 8); |
|
1353 QCOMPARE(o.actuals().count(), 1); |
|
1354 QCOMPARE(o.actuals().at(0), QVariant(10)); |
|
1355 |
|
1356 o.reset(); |
|
1357 QCOMPARE(engine->evaluate("object.method_intint(10, 11, 12)").isUndefined(), true); |
|
1358 QCOMPARE(o.error(), false); |
|
1359 QCOMPARE(o.invoked(), 9); |
|
1360 QCOMPARE(o.actuals().count(), 2); |
|
1361 QCOMPARE(o.actuals().at(0), QVariant(10)); |
|
1362 QCOMPARE(o.actuals().at(1), QVariant(11)); |
|
1363 |
|
1364 // Test return types |
|
1365 o.reset(); |
|
1366 QCOMPARE(engine->evaluate("object.method_NoArgs()").isUndefined(), true); |
|
1367 QCOMPARE(o.error(), false); |
|
1368 QCOMPARE(o.invoked(), 0); |
|
1369 QCOMPARE(o.actuals().count(), 0); |
|
1370 |
|
1371 o.reset(); |
|
1372 QVERIFY(engine->evaluate("object.method_NoArgs_int()").strictlyEquals(QScriptValue(engine, 6))); |
|
1373 QCOMPARE(o.error(), false); |
|
1374 QCOMPARE(o.invoked(), 1); |
|
1375 QCOMPARE(o.actuals().count(), 0); |
|
1376 |
|
1377 o.reset(); |
|
1378 QVERIFY(engine->evaluate("object.method_NoArgs_real()").strictlyEquals(QScriptValue(engine, 19.7))); |
|
1379 QCOMPARE(o.error(), false); |
|
1380 QCOMPARE(o.invoked(), 2); |
|
1381 QCOMPARE(o.actuals().count(), 0); |
|
1382 |
|
1383 o.reset(); |
|
1384 { |
|
1385 QScriptValue ret = engine->evaluate("object.method_NoArgs_QPointF()"); |
|
1386 QCOMPARE(ret.toVariant(), QVariant(QPointF(123, 4.5))); |
|
1387 QCOMPARE(o.error(), false); |
|
1388 QCOMPARE(o.invoked(), 3); |
|
1389 QCOMPARE(o.actuals().count(), 0); |
|
1390 } |
|
1391 |
|
1392 o.reset(); |
|
1393 { |
|
1394 QScriptValue ret = engine->evaluate("object.method_NoArgs_QObject()"); |
|
1395 QVERIFY(ret.isQObject()); |
|
1396 QCOMPARE(ret.toQObject(), (QObject *)&o); |
|
1397 QCOMPARE(o.error(), false); |
|
1398 QCOMPARE(o.invoked(), 4); |
|
1399 QCOMPARE(o.actuals().count(), 0); |
|
1400 } |
|
1401 |
|
1402 o.reset(); |
|
1403 QCOMPARE(engine->evaluate("object.method_NoArgs_unknown()").isUndefined(), true); |
|
1404 QCOMPARE(o.error(), false); |
|
1405 QCOMPARE(o.invoked(), 5); |
|
1406 QCOMPARE(o.actuals().count(), 0); |
|
1407 |
|
1408 o.reset(); |
|
1409 { |
|
1410 QScriptValue ret = engine->evaluate("object.method_NoArgs_QScriptValue()"); |
|
1411 QVERIFY(ret.isString()); |
|
1412 QCOMPARE(ret.toString(), QString("Hello world")); |
|
1413 QCOMPARE(o.error(), false); |
|
1414 QCOMPARE(o.invoked(), 6); |
|
1415 QCOMPARE(o.actuals().count(), 0); |
|
1416 } |
|
1417 |
|
1418 o.reset(); |
|
1419 QVERIFY(engine->evaluate("object.method_NoArgs_QVariant()").strictlyEquals(QScriptValue(engine, "QML rocks"))); |
|
1420 QCOMPARE(o.error(), false); |
|
1421 QCOMPARE(o.invoked(), 7); |
|
1422 QCOMPARE(o.actuals().count(), 0); |
|
1423 |
|
1424 // Test arg types |
|
1425 o.reset(); |
|
1426 QCOMPARE(engine->evaluate("object.method_int(94)").isUndefined(), true); |
|
1427 QCOMPARE(o.error(), false); |
|
1428 QCOMPARE(o.invoked(), 8); |
|
1429 QCOMPARE(o.actuals().count(), 1); |
|
1430 QCOMPARE(o.actuals().at(0), QVariant(94)); |
|
1431 |
|
1432 o.reset(); |
|
1433 QCOMPARE(engine->evaluate("object.method_int(\"94\")").isUndefined(), true); |
|
1434 QCOMPARE(o.error(), false); |
|
1435 QCOMPARE(o.invoked(), 8); |
|
1436 QCOMPARE(o.actuals().count(), 1); |
|
1437 QCOMPARE(o.actuals().at(0), QVariant(94)); |
|
1438 |
|
1439 o.reset(); |
|
1440 QCOMPARE(engine->evaluate("object.method_int(\"not a number\")").isUndefined(), true); |
|
1441 QCOMPARE(o.error(), false); |
|
1442 QCOMPARE(o.invoked(), 8); |
|
1443 QCOMPARE(o.actuals().count(), 1); |
|
1444 QCOMPARE(o.actuals().at(0), QVariant(0)); |
|
1445 |
|
1446 o.reset(); |
|
1447 QCOMPARE(engine->evaluate("object.method_int(null)").isUndefined(), true); |
|
1448 QCOMPARE(o.error(), false); |
|
1449 QCOMPARE(o.invoked(), 8); |
|
1450 QCOMPARE(o.actuals().count(), 1); |
|
1451 QCOMPARE(o.actuals().at(0), QVariant(0)); |
|
1452 |
|
1453 o.reset(); |
|
1454 QCOMPARE(engine->evaluate("object.method_int(undefined)").isUndefined(), true); |
|
1455 QCOMPARE(o.error(), false); |
|
1456 QCOMPARE(o.invoked(), 8); |
|
1457 QCOMPARE(o.actuals().count(), 1); |
|
1458 QCOMPARE(o.actuals().at(0), QVariant(0)); |
|
1459 |
|
1460 o.reset(); |
|
1461 QCOMPARE(engine->evaluate("object.method_int(object)").isUndefined(), true); |
|
1462 QCOMPARE(o.error(), false); |
|
1463 QCOMPARE(o.invoked(), 8); |
|
1464 QCOMPARE(o.actuals().count(), 1); |
|
1465 QCOMPARE(o.actuals().at(0), QVariant(0)); |
|
1466 |
|
1467 o.reset(); |
|
1468 QCOMPARE(engine->evaluate("object.method_intint(122, 9)").isUndefined(), true); |
|
1469 QCOMPARE(o.error(), false); |
|
1470 QCOMPARE(o.invoked(), 9); |
|
1471 QCOMPARE(o.actuals().count(), 2); |
|
1472 QCOMPARE(o.actuals().at(0), QVariant(122)); |
|
1473 QCOMPARE(o.actuals().at(1), QVariant(9)); |
|
1474 |
|
1475 o.reset(); |
|
1476 QCOMPARE(engine->evaluate("object.method_real(94.3)").isUndefined(), true); |
|
1477 QCOMPARE(o.error(), false); |
|
1478 QCOMPARE(o.invoked(), 10); |
|
1479 QCOMPARE(o.actuals().count(), 1); |
|
1480 QCOMPARE(o.actuals().at(0), QVariant(94.3)); |
|
1481 |
|
1482 o.reset(); |
|
1483 QCOMPARE(engine->evaluate("object.method_real(\"94.3\")").isUndefined(), true); |
|
1484 QCOMPARE(o.error(), false); |
|
1485 QCOMPARE(o.invoked(), 10); |
|
1486 QCOMPARE(o.actuals().count(), 1); |
|
1487 QCOMPARE(o.actuals().at(0), QVariant(94.3)); |
|
1488 |
|
1489 o.reset(); |
|
1490 QCOMPARE(engine->evaluate("object.method_real(\"not a number\")").isUndefined(), true); |
|
1491 QCOMPARE(o.error(), false); |
|
1492 QCOMPARE(o.invoked(), 10); |
|
1493 QCOMPARE(o.actuals().count(), 1); |
|
1494 QVERIFY(qIsNaN(o.actuals().at(0).toDouble())); |
|
1495 |
|
1496 o.reset(); |
|
1497 QCOMPARE(engine->evaluate("object.method_real(null)").isUndefined(), true); |
|
1498 QCOMPARE(o.error(), false); |
|
1499 QCOMPARE(o.invoked(), 10); |
|
1500 QCOMPARE(o.actuals().count(), 1); |
|
1501 QCOMPARE(o.actuals().at(0), QVariant(0)); |
|
1502 |
|
1503 o.reset(); |
|
1504 QCOMPARE(engine->evaluate("object.method_real(undefined)").isUndefined(), true); |
|
1505 QCOMPARE(o.error(), false); |
|
1506 QCOMPARE(o.invoked(), 10); |
|
1507 QCOMPARE(o.actuals().count(), 1); |
|
1508 QVERIFY(qIsNaN(o.actuals().at(0).toDouble())); |
|
1509 |
|
1510 o.reset(); |
|
1511 QCOMPARE(engine->evaluate("object.method_real(object)").isUndefined(), true); |
|
1512 QCOMPARE(o.error(), false); |
|
1513 QCOMPARE(o.invoked(), 10); |
|
1514 QCOMPARE(o.actuals().count(), 1); |
|
1515 QVERIFY(qIsNaN(o.actuals().at(0).toDouble())); |
|
1516 |
|
1517 o.reset(); |
|
1518 QCOMPARE(engine->evaluate("object.method_QString(\"Hello world\")").isUndefined(), true); |
|
1519 QCOMPARE(o.error(), false); |
|
1520 QCOMPARE(o.invoked(), 11); |
|
1521 QCOMPARE(o.actuals().count(), 1); |
|
1522 QCOMPARE(o.actuals().at(0), QVariant("Hello world")); |
|
1523 |
|
1524 o.reset(); |
|
1525 QCOMPARE(engine->evaluate("object.method_QString(19)").isUndefined(), true); |
|
1526 QCOMPARE(o.error(), false); |
|
1527 QCOMPARE(o.invoked(), 11); |
|
1528 QCOMPARE(o.actuals().count(), 1); |
|
1529 QCOMPARE(o.actuals().at(0), QVariant("19")); |
|
1530 |
|
1531 o.reset(); |
|
1532 { |
|
1533 QString expected = "MyInvokableObject(0x" + QString::number((intptr_t)&o, 16) + ")"; |
|
1534 QCOMPARE(engine->evaluate("object.method_QString(object)").isUndefined(), true); |
|
1535 QCOMPARE(o.error(), false); |
|
1536 QCOMPARE(o.invoked(), 11); |
|
1537 QCOMPARE(o.actuals().count(), 1); |
|
1538 QCOMPARE(o.actuals().at(0), QVariant(expected)); |
|
1539 } |
|
1540 |
|
1541 o.reset(); |
|
1542 QCOMPARE(engine->evaluate("object.method_QString(null)").isUndefined(), true); |
|
1543 QCOMPARE(o.error(), false); |
|
1544 QCOMPARE(o.invoked(), 11); |
|
1545 QCOMPARE(o.actuals().count(), 1); |
|
1546 QCOMPARE(o.actuals().at(0), QVariant(QString())); |
|
1547 |
|
1548 o.reset(); |
|
1549 QCOMPARE(engine->evaluate("object.method_QString(undefined)").isUndefined(), true); |
|
1550 QCOMPARE(o.error(), false); |
|
1551 QCOMPARE(o.invoked(), 11); |
|
1552 QCOMPARE(o.actuals().count(), 1); |
|
1553 QCOMPARE(o.actuals().at(0), QVariant(QString())); |
|
1554 |
|
1555 o.reset(); |
|
1556 QCOMPARE(engine->evaluate("object.method_QPointF(0)").isUndefined(), true); |
|
1557 QCOMPARE(o.error(), false); |
|
1558 QCOMPARE(o.invoked(), 12); |
|
1559 QCOMPARE(o.actuals().count(), 1); |
|
1560 QCOMPARE(o.actuals().at(0), QVariant(QPointF())); |
|
1561 |
|
1562 o.reset(); |
|
1563 QCOMPARE(engine->evaluate("object.method_QPointF(null)").isUndefined(), true); |
|
1564 QCOMPARE(o.error(), false); |
|
1565 QCOMPARE(o.invoked(), 12); |
|
1566 QCOMPARE(o.actuals().count(), 1); |
|
1567 QCOMPARE(o.actuals().at(0), QVariant(QPointF())); |
|
1568 |
|
1569 o.reset(); |
|
1570 QCOMPARE(engine->evaluate("object.method_QPointF(undefined)").isUndefined(), true); |
|
1571 QCOMPARE(o.error(), false); |
|
1572 QCOMPARE(o.invoked(), 12); |
|
1573 QCOMPARE(o.actuals().count(), 1); |
|
1574 QCOMPARE(o.actuals().at(0), QVariant(QPointF())); |
|
1575 |
|
1576 o.reset(); |
|
1577 QCOMPARE(engine->evaluate("object.method_QPointF(object)").isUndefined(), true); |
|
1578 QCOMPARE(o.error(), false); |
|
1579 QCOMPARE(o.invoked(), 12); |
|
1580 QCOMPARE(o.actuals().count(), 1); |
|
1581 QCOMPARE(o.actuals().at(0), QVariant(QPointF())); |
|
1582 |
|
1583 o.reset(); |
|
1584 QCOMPARE(engine->evaluate("object.method_QPointF(object.method_get_QPointF())").isUndefined(), true); |
|
1585 QCOMPARE(o.error(), false); |
|
1586 QCOMPARE(o.invoked(), 12); |
|
1587 QCOMPARE(o.actuals().count(), 1); |
|
1588 QCOMPARE(o.actuals().at(0), QVariant(QPointF(99.3, -10.2))); |
|
1589 |
|
1590 o.reset(); |
|
1591 QCOMPARE(engine->evaluate("object.method_QPointF(object.method_get_QPoint())").isUndefined(), true); |
|
1592 QCOMPARE(o.error(), false); |
|
1593 QCOMPARE(o.invoked(), 12); |
|
1594 QCOMPARE(o.actuals().count(), 1); |
|
1595 QCOMPARE(o.actuals().at(0), QVariant(QPointF(9, 12))); |
|
1596 |
|
1597 o.reset(); |
|
1598 QCOMPARE(engine->evaluate("object.method_QObject(0)").isUndefined(), true); |
|
1599 QCOMPARE(o.error(), false); |
|
1600 QCOMPARE(o.invoked(), 13); |
|
1601 QCOMPARE(o.actuals().count(), 1); |
|
1602 QCOMPARE(o.actuals().at(0), qVariantFromValue((QObject *)0)); |
|
1603 |
|
1604 o.reset(); |
|
1605 QCOMPARE(engine->evaluate("object.method_QObject(\"Hello world\")").isUndefined(), true); |
|
1606 QCOMPARE(o.error(), false); |
|
1607 QCOMPARE(o.invoked(), 13); |
|
1608 QCOMPARE(o.actuals().count(), 1); |
|
1609 QCOMPARE(o.actuals().at(0), qVariantFromValue((QObject *)0)); |
|
1610 |
|
1611 o.reset(); |
|
1612 QCOMPARE(engine->evaluate("object.method_QObject(null)").isUndefined(), true); |
|
1613 QCOMPARE(o.error(), false); |
|
1614 QCOMPARE(o.invoked(), 13); |
|
1615 QCOMPARE(o.actuals().count(), 1); |
|
1616 QCOMPARE(o.actuals().at(0), qVariantFromValue((QObject *)0)); |
|
1617 |
|
1618 o.reset(); |
|
1619 QCOMPARE(engine->evaluate("object.method_QObject(undefined)").isUndefined(), true); |
|
1620 QCOMPARE(o.error(), false); |
|
1621 QCOMPARE(o.invoked(), 13); |
|
1622 QCOMPARE(o.actuals().count(), 1); |
|
1623 QCOMPARE(o.actuals().at(0), qVariantFromValue((QObject *)0)); |
|
1624 |
|
1625 o.reset(); |
|
1626 QCOMPARE(engine->evaluate("object.method_QObject(object)").isUndefined(), true); |
|
1627 QCOMPARE(o.error(), false); |
|
1628 QCOMPARE(o.invoked(), 13); |
|
1629 QCOMPARE(o.actuals().count(), 1); |
|
1630 QCOMPARE(o.actuals().at(0), qVariantFromValue((QObject *)&o)); |
|
1631 |
|
1632 o.reset(); |
|
1633 QCOMPARE(engine->evaluate("object.method_QScriptValue(null)").isUndefined(), true); |
|
1634 QCOMPARE(o.error(), false); |
|
1635 QCOMPARE(o.invoked(), 14); |
|
1636 QCOMPARE(o.actuals().count(), 1); |
|
1637 QVERIFY(qvariant_cast<QScriptValue>(o.actuals().at(0)).isNull()); |
|
1638 |
|
1639 o.reset(); |
|
1640 QCOMPARE(engine->evaluate("object.method_QScriptValue(undefined)").isUndefined(), true); |
|
1641 QCOMPARE(o.error(), false); |
|
1642 QCOMPARE(o.invoked(), 14); |
|
1643 QCOMPARE(o.actuals().count(), 1); |
|
1644 QVERIFY(qvariant_cast<QScriptValue>(o.actuals().at(0)).isUndefined()); |
|
1645 |
|
1646 o.reset(); |
|
1647 QCOMPARE(engine->evaluate("object.method_QScriptValue(19)").isUndefined(), true); |
|
1648 QCOMPARE(o.error(), false); |
|
1649 QCOMPARE(o.invoked(), 14); |
|
1650 QCOMPARE(o.actuals().count(), 1); |
|
1651 QVERIFY(qvariant_cast<QScriptValue>(o.actuals().at(0)).strictlyEquals(QScriptValue(engine, 19))); |
|
1652 |
|
1653 o.reset(); |
|
1654 QCOMPARE(engine->evaluate("object.method_QScriptValue([19, 20])").isUndefined(), true); |
|
1655 QCOMPARE(o.error(), false); |
|
1656 QCOMPARE(o.invoked(), 14); |
|
1657 QCOMPARE(o.actuals().count(), 1); |
|
1658 QVERIFY(qvariant_cast<QScriptValue>(o.actuals().at(0)).isArray()); |
|
1659 |
|
1660 o.reset(); |
|
1661 QCOMPARE(engine->evaluate("object.method_intQScriptValue(4, null)").isUndefined(), true); |
|
1662 QCOMPARE(o.error(), false); |
|
1663 QCOMPARE(o.invoked(), 15); |
|
1664 QCOMPARE(o.actuals().count(), 2); |
|
1665 QCOMPARE(o.actuals().at(0), QVariant(4)); |
|
1666 QVERIFY(qvariant_cast<QScriptValue>(o.actuals().at(1)).isNull()); |
|
1667 |
|
1668 o.reset(); |
|
1669 QCOMPARE(engine->evaluate("object.method_intQScriptValue(8, undefined)").isUndefined(), true); |
|
1670 QCOMPARE(o.error(), false); |
|
1671 QCOMPARE(o.invoked(), 15); |
|
1672 QCOMPARE(o.actuals().count(), 2); |
|
1673 QCOMPARE(o.actuals().at(0), QVariant(8)); |
|
1674 QVERIFY(qvariant_cast<QScriptValue>(o.actuals().at(1)).isUndefined()); |
|
1675 |
|
1676 o.reset(); |
|
1677 QCOMPARE(engine->evaluate("object.method_intQScriptValue(3, 19)").isUndefined(), true); |
|
1678 QCOMPARE(o.error(), false); |
|
1679 QCOMPARE(o.invoked(), 15); |
|
1680 QCOMPARE(o.actuals().count(), 2); |
|
1681 QCOMPARE(o.actuals().at(0), QVariant(3)); |
|
1682 QVERIFY(qvariant_cast<QScriptValue>(o.actuals().at(1)).strictlyEquals(QScriptValue(engine, 19))); |
|
1683 |
|
1684 o.reset(); |
|
1685 QCOMPARE(engine->evaluate("object.method_intQScriptValue(44, [19, 20])").isUndefined(), true); |
|
1686 QCOMPARE(o.error(), false); |
|
1687 QCOMPARE(o.invoked(), 15); |
|
1688 QCOMPARE(o.actuals().count(), 2); |
|
1689 QCOMPARE(o.actuals().at(0), QVariant(44)); |
|
1690 QVERIFY(qvariant_cast<QScriptValue>(o.actuals().at(1)).isArray()); |
|
1691 |
|
1692 // Test overloads - QML will always invoke the *last* method |
|
1693 o.reset(); |
|
1694 QCOMPARE(engine->evaluate("object.method_overload()").isError(), true); |
|
1695 QCOMPARE(o.error(), false); |
|
1696 QCOMPARE(o.invoked(), -1); |
|
1697 QCOMPARE(o.actuals().count(), 0); |
|
1698 |
|
1699 o.reset(); |
|
1700 QCOMPARE(engine->evaluate("object.method_overload(10)").isError(), true); |
|
1701 QCOMPARE(o.error(), false); |
|
1702 QCOMPARE(o.invoked(), -1); |
|
1703 QCOMPARE(o.actuals().count(), 0); |
|
1704 |
|
1705 o.reset(); |
|
1706 QCOMPARE(engine->evaluate("object.method_overload(10, 11)").isUndefined(), true); |
|
1707 QCOMPARE(o.error(), false); |
|
1708 QCOMPARE(o.invoked(), 17); |
|
1709 QCOMPARE(o.actuals().count(), 2); |
|
1710 QCOMPARE(o.actuals().at(0), QVariant(10)); |
|
1711 QCOMPARE(o.actuals().at(1), QVariant(11)); |
|
1712 } |
|
1713 |
|
1714 // QTBUG-5675 |
|
1715 void tst_qdeclarativeecmascript::listToVariant() |
|
1716 { |
|
1717 QDeclarativeComponent component(&engine, TEST_FILE("listToVariant.qml")); |
|
1718 |
|
1719 MyQmlContainer container; |
|
1720 |
|
1721 QDeclarativeContext context(engine.rootContext()); |
|
1722 context.setContextObject(&container); |
|
1723 |
|
1724 QObject *object = component.create(&context); |
|
1725 QVERIFY(object != 0); |
|
1726 |
|
1727 QVariant v = object->property("test"); |
|
1728 QCOMPARE(v.userType(), qMetaTypeId<QDeclarativeListReference>()); |
|
1729 QVERIFY(qvariant_cast<QDeclarativeListReference>(v).object() == &container); |
|
1730 |
|
1731 delete object; |
|
1732 } |
|
1733 |
|
1734 // QTBUG-7957 |
|
1735 void tst_qdeclarativeecmascript::multiEngineObject() |
|
1736 { |
|
1737 MyQmlObject obj; |
|
1738 obj.setStringProperty("Howdy planet"); |
|
1739 |
|
1740 QDeclarativeEngine e1; |
|
1741 e1.rootContext()->setContextProperty("thing", &obj); |
|
1742 QDeclarativeComponent c1(&e1, TEST_FILE("multiEngineObject.qml")); |
|
1743 |
|
1744 QDeclarativeEngine e2; |
|
1745 e2.rootContext()->setContextProperty("thing", &obj); |
|
1746 QDeclarativeComponent c2(&e2, TEST_FILE("multiEngineObject.qml")); |
|
1747 |
|
1748 QObject *o1 = c1.create(); |
|
1749 QObject *o2 = c2.create(); |
|
1750 |
|
1751 QCOMPARE(o1->property("test").toString(), QString("Howdy planet")); |
|
1752 QCOMPARE(o2->property("test").toString(), QString("Howdy planet")); |
|
1753 |
|
1754 delete o2; |
|
1755 delete o1; |
|
1756 } |
|
1757 |
|
1758 // Test that references to QObjects are cleanup when the object is destroyed |
|
1759 void tst_qdeclarativeecmascript::deletedObject() |
|
1760 { |
|
1761 QDeclarativeComponent component(&engine, TEST_FILE("deletedObject.qml")); |
|
1762 |
|
1763 QObject *object = component.create(); |
|
1764 |
|
1765 QCOMPARE(object->property("test1").toBool(), true); |
|
1766 QCOMPARE(object->property("test2").toBool(), true); |
|
1767 QCOMPARE(object->property("test3").toBool(), true); |
|
1768 QCOMPARE(object->property("test4").toBool(), true); |
|
1769 |
|
1770 delete object; |
|
1771 } |
|
1772 |
|
1773 void tst_qdeclarativeecmascript::attachedPropertyScope() |
|
1774 { |
|
1775 QDeclarativeComponent component(&engine, TEST_FILE("attachedPropertyScope.qml")); |
|
1776 |
|
1777 QObject *object = component.create(); |
|
1778 QVERIFY(object != 0); |
|
1779 |
|
1780 MyQmlAttachedObject *attached = |
|
1781 qobject_cast<MyQmlAttachedObject *>(qmlAttachedPropertiesObject<MyQmlObject>(object)); |
|
1782 QVERIFY(attached != 0); |
|
1783 |
|
1784 QCOMPARE(object->property("value2").toInt(), 0); |
|
1785 |
|
1786 attached->emitMySignal(); |
|
1787 |
|
1788 QCOMPARE(object->property("value2").toInt(), 9); |
|
1789 |
|
1790 delete object; |
|
1791 } |
|
1792 |
|
1793 void tst_qdeclarativeecmascript::scriptConnect() |
|
1794 { |
|
1795 { |
|
1796 QDeclarativeComponent component(&engine, TEST_FILE("scriptConnect.1.qml")); |
|
1797 |
|
1798 MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create()); |
|
1799 QVERIFY(object != 0); |
|
1800 |
|
1801 QCOMPARE(object->property("test").toBool(), false); |
|
1802 emit object->argumentSignal(19, "Hello world!", 10.3); |
|
1803 QCOMPARE(object->property("test").toBool(), true); |
|
1804 |
|
1805 delete object; |
|
1806 } |
|
1807 |
|
1808 { |
|
1809 QDeclarativeComponent component(&engine, TEST_FILE("scriptConnect.2.qml")); |
|
1810 |
|
1811 MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create()); |
|
1812 QVERIFY(object != 0); |
|
1813 |
|
1814 QCOMPARE(object->property("test").toBool(), false); |
|
1815 emit object->argumentSignal(19, "Hello world!", 10.3); |
|
1816 QCOMPARE(object->property("test").toBool(), true); |
|
1817 |
|
1818 delete object; |
|
1819 } |
|
1820 |
|
1821 { |
|
1822 QDeclarativeComponent component(&engine, TEST_FILE("scriptConnect.3.qml")); |
|
1823 |
|
1824 MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create()); |
|
1825 QVERIFY(object != 0); |
|
1826 |
|
1827 QCOMPARE(object->property("test").toBool(), false); |
|
1828 emit object->argumentSignal(19, "Hello world!", 10.3); |
|
1829 QCOMPARE(object->property("test").toBool(), true); |
|
1830 |
|
1831 delete object; |
|
1832 } |
|
1833 |
|
1834 { |
|
1835 QDeclarativeComponent component(&engine, TEST_FILE("scriptConnect.4.qml")); |
|
1836 |
|
1837 MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create()); |
|
1838 QVERIFY(object != 0); |
|
1839 |
|
1840 QCOMPARE(object->methodCalled(), false); |
|
1841 emit object->argumentSignal(19, "Hello world!", 10.3); |
|
1842 QCOMPARE(object->methodCalled(), true); |
|
1843 |
|
1844 delete object; |
|
1845 } |
|
1846 |
|
1847 { |
|
1848 QDeclarativeComponent component(&engine, TEST_FILE("scriptConnect.5.qml")); |
|
1849 |
|
1850 MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create()); |
|
1851 QVERIFY(object != 0); |
|
1852 |
|
1853 QCOMPARE(object->methodCalled(), false); |
|
1854 emit object->argumentSignal(19, "Hello world!", 10.3); |
|
1855 QCOMPARE(object->methodCalled(), true); |
|
1856 |
|
1857 delete object; |
|
1858 } |
|
1859 |
|
1860 { |
|
1861 QDeclarativeComponent component(&engine, TEST_FILE("scriptConnect.6.qml")); |
|
1862 |
|
1863 MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create()); |
|
1864 QVERIFY(object != 0); |
|
1865 |
|
1866 QCOMPARE(object->property("test").toInt(), 0); |
|
1867 emit object->argumentSignal(19, "Hello world!", 10.3); |
|
1868 QCOMPARE(object->property("test").toInt(), 2); |
|
1869 |
|
1870 delete object; |
|
1871 } |
|
1872 } |
|
1873 |
|
1874 void tst_qdeclarativeecmascript::scriptDisconnect() |
|
1875 { |
|
1876 { |
|
1877 QDeclarativeComponent component(&engine, TEST_FILE("scriptDisconnect.1.qml")); |
|
1878 |
|
1879 MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create()); |
|
1880 QVERIFY(object != 0); |
|
1881 |
|
1882 QCOMPARE(object->property("test").toInt(), 0); |
|
1883 emit object->argumentSignal(19, "Hello world!", 10.3); |
|
1884 QCOMPARE(object->property("test").toInt(), 1); |
|
1885 emit object->argumentSignal(19, "Hello world!", 10.3); |
|
1886 QCOMPARE(object->property("test").toInt(), 2); |
|
1887 emit object->basicSignal(); |
|
1888 QCOMPARE(object->property("test").toInt(), 2); |
|
1889 emit object->argumentSignal(19, "Hello world!", 10.3); |
|
1890 QCOMPARE(object->property("test").toInt(), 2); |
|
1891 |
|
1892 delete object; |
|
1893 } |
|
1894 |
|
1895 { |
|
1896 QDeclarativeComponent component(&engine, TEST_FILE("scriptDisconnect.2.qml")); |
|
1897 |
|
1898 MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create()); |
|
1899 QVERIFY(object != 0); |
|
1900 |
|
1901 QCOMPARE(object->property("test").toInt(), 0); |
|
1902 emit object->argumentSignal(19, "Hello world!", 10.3); |
|
1903 QCOMPARE(object->property("test").toInt(), 1); |
|
1904 emit object->argumentSignal(19, "Hello world!", 10.3); |
|
1905 QCOMPARE(object->property("test").toInt(), 2); |
|
1906 emit object->basicSignal(); |
|
1907 QCOMPARE(object->property("test").toInt(), 2); |
|
1908 emit object->argumentSignal(19, "Hello world!", 10.3); |
|
1909 QCOMPARE(object->property("test").toInt(), 2); |
|
1910 |
|
1911 delete object; |
|
1912 } |
|
1913 |
|
1914 { |
|
1915 QDeclarativeComponent component(&engine, TEST_FILE("scriptDisconnect.3.qml")); |
|
1916 |
|
1917 MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create()); |
|
1918 QVERIFY(object != 0); |
|
1919 |
|
1920 QCOMPARE(object->property("test").toInt(), 0); |
|
1921 emit object->argumentSignal(19, "Hello world!", 10.3); |
|
1922 QCOMPARE(object->property("test").toInt(), 1); |
|
1923 emit object->argumentSignal(19, "Hello world!", 10.3); |
|
1924 QCOMPARE(object->property("test").toInt(), 2); |
|
1925 emit object->basicSignal(); |
|
1926 QCOMPARE(object->property("test").toInt(), 2); |
|
1927 emit object->argumentSignal(19, "Hello world!", 10.3); |
|
1928 QCOMPARE(object->property("test").toInt(), 3); |
|
1929 |
|
1930 delete object; |
|
1931 } |
|
1932 { |
|
1933 QDeclarativeComponent component(&engine, TEST_FILE("scriptDisconnect.4.qml")); |
|
1934 |
|
1935 MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create()); |
|
1936 QVERIFY(object != 0); |
|
1937 |
|
1938 QCOMPARE(object->property("test").toInt(), 0); |
|
1939 emit object->argumentSignal(19, "Hello world!", 10.3); |
|
1940 QCOMPARE(object->property("test").toInt(), 1); |
|
1941 emit object->argumentSignal(19, "Hello world!", 10.3); |
|
1942 QCOMPARE(object->property("test").toInt(), 2); |
|
1943 emit object->basicSignal(); |
|
1944 QCOMPARE(object->property("test").toInt(), 2); |
|
1945 emit object->argumentSignal(19, "Hello world!", 10.3); |
|
1946 QCOMPARE(object->property("test").toInt(), 3); |
|
1947 |
|
1948 delete object; |
|
1949 } |
|
1950 } |
|
1951 |
|
1952 class OwnershipObject : public QObject |
|
1953 { |
|
1954 Q_OBJECT |
|
1955 public: |
|
1956 OwnershipObject() { object = new QObject; } |
|
1957 |
|
1958 QPointer<QObject> object; |
|
1959 |
|
1960 public slots: |
|
1961 QObject *getObject() { return object; } |
|
1962 }; |
|
1963 |
|
1964 void tst_qdeclarativeecmascript::ownership() |
|
1965 { |
|
1966 OwnershipObject own; |
|
1967 QDeclarativeContext *context = new QDeclarativeContext(engine.rootContext()); |
|
1968 context->setContextObject(&own); |
|
1969 |
|
1970 { |
|
1971 QDeclarativeComponent component(&engine, TEST_FILE("ownership.qml")); |
|
1972 |
|
1973 QVERIFY(own.object != 0); |
|
1974 |
|
1975 QObject *object = component.create(context); |
|
1976 QDeclarativeEnginePrivate::getScriptEngine(&engine)->collectGarbage(); |
|
1977 |
|
1978 QCoreApplication::processEvents(QEventLoop::DeferredDeletion); |
|
1979 |
|
1980 QVERIFY(own.object == 0); |
|
1981 |
|
1982 delete object; |
|
1983 } |
|
1984 |
|
1985 own.object = new QObject(&own); |
|
1986 |
|
1987 { |
|
1988 QDeclarativeComponent component(&engine, TEST_FILE("ownership.qml")); |
|
1989 |
|
1990 QVERIFY(own.object != 0); |
|
1991 |
|
1992 QObject *object = component.create(context); |
|
1993 QDeclarativeEnginePrivate::getScriptEngine(&engine)->collectGarbage(); |
|
1994 |
|
1995 QCoreApplication::processEvents(QEventLoop::DeferredDeletion); |
|
1996 |
|
1997 QVERIFY(own.object != 0); |
|
1998 |
|
1999 delete object; |
|
2000 } |
|
2001 } |
|
2002 |
|
2003 class QListQObjectMethodsObject : public QObject |
|
2004 { |
|
2005 Q_OBJECT |
|
2006 public: |
|
2007 QListQObjectMethodsObject() { |
|
2008 m_objects.append(new MyQmlObject()); |
|
2009 m_objects.append(new MyQmlObject()); |
|
2010 } |
|
2011 |
|
2012 ~QListQObjectMethodsObject() { |
|
2013 qDeleteAll(m_objects); |
|
2014 } |
|
2015 |
|
2016 public slots: |
|
2017 QList<QObject *> getObjects() { return m_objects; } |
|
2018 |
|
2019 private: |
|
2020 QList<QObject *> m_objects; |
|
2021 }; |
|
2022 |
|
2023 // Tests that returning a QList<QObject*> from a method works |
|
2024 void tst_qdeclarativeecmascript::qlistqobjectMethods() |
|
2025 { |
|
2026 QListQObjectMethodsObject obj; |
|
2027 QDeclarativeContext *context = new QDeclarativeContext(engine.rootContext()); |
|
2028 context->setContextObject(&obj); |
|
2029 |
|
2030 QDeclarativeComponent component(&engine, TEST_FILE("qlistqobjectMethods.qml")); |
|
2031 |
|
2032 QObject *object = component.create(context); |
|
2033 |
|
2034 QCOMPARE(object->property("test").toInt(), 2); |
|
2035 QCOMPARE(object->property("test2").toBool(), true); |
|
2036 |
|
2037 delete object; |
|
2038 } |
|
2039 |
|
2040 // QTBUG-9205 |
|
2041 void tst_qdeclarativeecmascript::strictlyEquals() |
|
2042 { |
|
2043 QDeclarativeComponent component(&engine, TEST_FILE("strictlyEquals.qml")); |
|
2044 |
|
2045 QObject *object = component.create(); |
|
2046 QVERIFY(object != 0); |
|
2047 |
|
2048 QCOMPARE(object->property("test1").toBool(), true); |
|
2049 QCOMPARE(object->property("test2").toBool(), true); |
|
2050 QCOMPARE(object->property("test3").toBool(), true); |
|
2051 QCOMPARE(object->property("test4").toBool(), true); |
|
2052 QCOMPARE(object->property("test5").toBool(), true); |
|
2053 QCOMPARE(object->property("test6").toBool(), true); |
|
2054 QCOMPARE(object->property("test7").toBool(), true); |
|
2055 QCOMPARE(object->property("test8").toBool(), true); |
|
2056 |
|
2057 delete object; |
|
2058 } |
|
2059 |
|
2060 void tst_qdeclarativeecmascript::compiled() |
|
2061 { |
|
2062 QDeclarativeComponent component(&engine, TEST_FILE("compiled.qml")); |
|
2063 |
|
2064 QObject *object = component.create(); |
|
2065 QVERIFY(object != 0); |
|
2066 |
|
2067 QCOMPARE(object->property("test1").toReal(), qreal(15.7)); |
|
2068 QCOMPARE(object->property("test2").toReal(), qreal(-6.7)); |
|
2069 QCOMPARE(object->property("test3").toBool(), true); |
|
2070 QCOMPARE(object->property("test4").toBool(), false); |
|
2071 QCOMPARE(object->property("test5").toBool(), false); |
|
2072 QCOMPARE(object->property("test6").toBool(), true); |
|
2073 |
|
2074 QCOMPARE(object->property("test7").toInt(), 185); |
|
2075 QCOMPARE(object->property("test8").toInt(), 167); |
|
2076 QCOMPARE(object->property("test9").toBool(), true); |
|
2077 QCOMPARE(object->property("test10").toBool(), false); |
|
2078 QCOMPARE(object->property("test11").toBool(), false); |
|
2079 QCOMPARE(object->property("test12").toBool(), true); |
|
2080 |
|
2081 QCOMPARE(object->property("test13").toString(), QLatin1String("HelloWorld")); |
|
2082 QCOMPARE(object->property("test14").toString(), QLatin1String("Hello World")); |
|
2083 QCOMPARE(object->property("test15").toBool(), false); |
|
2084 QCOMPARE(object->property("test16").toBool(), true); |
|
2085 |
|
2086 QCOMPARE(object->property("test17").toInt(), 5); |
|
2087 QCOMPARE(object->property("test18").toReal(), qreal(176)); |
|
2088 QCOMPARE(object->property("test19").toInt(), 7); |
|
2089 QCOMPARE(object->property("test20").toReal(), qreal(6.7)); |
|
2090 QCOMPARE(object->property("test21").toString(), QLatin1String("6.7")); |
|
2091 QCOMPARE(object->property("test22").toString(), QLatin1String("!")); |
|
2092 QCOMPARE(object->property("test23").toBool(), true); |
|
2093 QCOMPARE(qvariant_cast<QColor>(object->property("test24")), QColor(0x11,0x22,0x33)); |
|
2094 QCOMPARE(qvariant_cast<QColor>(object->property("test25")), QColor(0x11,0x22,0x33,0xAA)); |
|
2095 |
|
2096 delete object; |
|
2097 } |
|
2098 |
|
2099 // Test that numbers assigned in bindings as strings work consistently |
|
2100 void tst_qdeclarativeecmascript::numberAssignment() |
|
2101 { |
|
2102 QDeclarativeComponent component(&engine, TEST_FILE("numberAssignment.qml")); |
|
2103 |
|
2104 QObject *object = component.create(); |
|
2105 QVERIFY(object != 0); |
|
2106 |
|
2107 QCOMPARE(object->property("test1"), QVariant((qreal)6.7)); |
|
2108 QCOMPARE(object->property("test2"), QVariant((qreal)6.7)); |
|
2109 QCOMPARE(object->property("test2"), QVariant((qreal)6.7)); |
|
2110 QCOMPARE(object->property("test3"), QVariant((qreal)6)); |
|
2111 QCOMPARE(object->property("test4"), QVariant((qreal)6)); |
|
2112 |
|
2113 QCOMPARE(object->property("test5"), QVariant((int)7)); |
|
2114 QCOMPARE(object->property("test6"), QVariant((int)7)); |
|
2115 QCOMPARE(object->property("test7"), QVariant((int)6)); |
|
2116 QCOMPARE(object->property("test8"), QVariant((int)6)); |
|
2117 |
|
2118 QCOMPARE(object->property("test9"), QVariant((unsigned int)7)); |
|
2119 QCOMPARE(object->property("test10"), QVariant((unsigned int)7)); |
|
2120 QCOMPARE(object->property("test11"), QVariant((unsigned int)6)); |
|
2121 QCOMPARE(object->property("test12"), QVariant((unsigned int)6)); |
|
2122 |
|
2123 delete object; |
|
2124 } |
|
2125 |
|
2126 // Test that assigning a null object works |
|
2127 // Regressed with: df1788b4dbbb2826ae63f26bdf166342595343f4 |
|
2128 void tst_qdeclarativeecmascript::nullObjectBinding() |
|
2129 { |
|
2130 QDeclarativeComponent component(&engine, TEST_FILE("nullObjectBinding.qml")); |
|
2131 |
|
2132 QObject *object = component.create(); |
|
2133 QVERIFY(object != 0); |
|
2134 |
|
2135 QVERIFY(object->property("test") == QVariant::fromValue((QObject *)0)); |
|
2136 |
|
2137 delete object; |
|
2138 } |
|
2139 |
|
2140 // Test that bindings don't evaluate once the engine has been destroyed |
|
2141 void tst_qdeclarativeecmascript::deletedEngine() |
|
2142 { |
|
2143 QDeclarativeEngine *engine = new QDeclarativeEngine; |
|
2144 QDeclarativeComponent component(engine, TEST_FILE("deletedEngine.qml")); |
|
2145 |
|
2146 QObject *object = component.create(); |
|
2147 QVERIFY(object != 0); |
|
2148 |
|
2149 QCOMPARE(object->property("a").toInt(), 39); |
|
2150 object->setProperty("b", QVariant(9)); |
|
2151 QCOMPARE(object->property("a").toInt(), 117); |
|
2152 |
|
2153 delete engine; |
|
2154 |
|
2155 QCOMPARE(object->property("a").toInt(), 117); |
|
2156 object->setProperty("b", QVariant(10)); |
|
2157 QCOMPARE(object->property("a").toInt(), 117); |
|
2158 |
|
2159 delete object; |
|
2160 } |
|
2161 |
|
2162 // Test the crashing part of QTBUG-9705 |
|
2163 void tst_qdeclarativeecmascript::libraryScriptAssert() |
|
2164 { |
|
2165 QDeclarativeComponent component(&engine, TEST_FILE("libraryScriptAssert.qml")); |
|
2166 |
|
2167 QObject *object = component.create(); |
|
2168 QVERIFY(object != 0); |
|
2169 |
|
2170 delete object; |
|
2171 } |
|
2172 |
|
2173 void tst_qdeclarativeecmascript::variantsAssignedUndefined() |
|
2174 { |
|
2175 QDeclarativeComponent component(&engine, TEST_FILE("variantsAssignedUndefined.qml")); |
|
2176 |
|
2177 QObject *object = component.create(); |
|
2178 QVERIFY(object != 0); |
|
2179 |
|
2180 QCOMPARE(object->property("test1").toInt(), 10); |
|
2181 QCOMPARE(object->property("test2").toInt(), 11); |
|
2182 |
|
2183 object->setProperty("runTest", true); |
|
2184 |
|
2185 QCOMPARE(object->property("test1"), QVariant()); |
|
2186 QCOMPARE(object->property("test2"), QVariant()); |
|
2187 |
|
2188 |
|
2189 delete object; |
|
2190 } |
|
2191 |
|
2192 void tst_qdeclarativeecmascript::qtbug_9792() |
|
2193 { |
|
2194 QDeclarativeComponent component(&engine, TEST_FILE("qtbug_9792.qml")); |
|
2195 |
|
2196 QDeclarativeContext *context = new QDeclarativeContext(engine.rootContext()); |
|
2197 |
|
2198 MyQmlObject *object = qobject_cast<MyQmlObject*>(component.create(context)); |
|
2199 QVERIFY(object != 0); |
|
2200 |
|
2201 QTest::ignoreMessage(QtDebugMsg, "Hello world!"); |
|
2202 object->basicSignal(); |
|
2203 |
|
2204 delete context; |
|
2205 |
|
2206 transientErrorsMsgCount = 0; |
|
2207 QtMsgHandler old = qInstallMsgHandler(transientErrorsMsgHandler); |
|
2208 |
|
2209 object->basicSignal(); |
|
2210 |
|
2211 qInstallMsgHandler(old); |
|
2212 |
|
2213 QCOMPARE(transientErrorsMsgCount, 0); |
|
2214 |
|
2215 delete object; |
|
2216 } |
|
2217 |
|
2218 // Verifies that QDeclarativeGuard<>s used in the vmemetaobject are cleaned correctly |
|
2219 void tst_qdeclarativeecmascript::qtcreatorbug_1289() |
|
2220 { |
|
2221 QDeclarativeComponent component(&engine, TEST_FILE("qtcreatorbug_1289.qml")); |
|
2222 |
|
2223 QObject *o = component.create(); |
|
2224 QVERIFY(o != 0); |
|
2225 |
|
2226 QObject *nested = qvariant_cast<QObject *>(o->property("object")); |
|
2227 QVERIFY(nested != 0); |
|
2228 |
|
2229 QVERIFY(qvariant_cast<QObject *>(nested->property("nestedObject")) == o); |
|
2230 |
|
2231 delete nested; |
|
2232 nested = qvariant_cast<QObject *>(o->property("object")); |
|
2233 QVERIFY(nested == 0); |
|
2234 |
|
2235 // If the bug is present, the next line will crash |
|
2236 delete o; |
|
2237 } |
|
2238 |
|
2239 // Test that we shut down without stupid warnings |
|
2240 void tst_qdeclarativeecmascript::noSpuriousWarningsAtShutdown() |
|
2241 { |
|
2242 { |
|
2243 QDeclarativeComponent component(&engine, TEST_FILE("noSpuriousWarningsAtShutdown.qml")); |
|
2244 |
|
2245 QObject *o = component.create(); |
|
2246 |
|
2247 transientErrorsMsgCount = 0; |
|
2248 QtMsgHandler old = qInstallMsgHandler(transientErrorsMsgHandler); |
|
2249 |
|
2250 delete o; |
|
2251 |
|
2252 qInstallMsgHandler(old); |
|
2253 |
|
2254 QCOMPARE(transientErrorsMsgCount, 0); |
|
2255 } |
|
2256 |
|
2257 |
|
2258 { |
|
2259 QDeclarativeComponent component(&engine, TEST_FILE("noSpuriousWarningsAtShutdown.2.qml")); |
|
2260 |
|
2261 QObject *o = component.create(); |
|
2262 |
|
2263 transientErrorsMsgCount = 0; |
|
2264 QtMsgHandler old = qInstallMsgHandler(transientErrorsMsgHandler); |
|
2265 |
|
2266 delete o; |
|
2267 |
|
2268 qInstallMsgHandler(old); |
|
2269 |
|
2270 QCOMPARE(transientErrorsMsgCount, 0); |
|
2271 } |
|
2272 } |
|
2273 |
|
2274 void tst_qdeclarativeecmascript::canAssignNullToQObject() |
|
2275 { |
|
2276 { |
|
2277 QDeclarativeComponent component(&engine, TEST_FILE("canAssignNullToQObject.1.qml")); |
|
2278 |
|
2279 MyQmlObject *o = qobject_cast<MyQmlObject *>(component.create()); |
|
2280 QVERIFY(o != 0); |
|
2281 |
|
2282 QVERIFY(o->objectProperty() != 0); |
|
2283 |
|
2284 o->setProperty("runTest", true); |
|
2285 |
|
2286 QVERIFY(o->objectProperty() == 0); |
|
2287 |
|
2288 delete o; |
|
2289 } |
|
2290 |
|
2291 { |
|
2292 QDeclarativeComponent component(&engine, TEST_FILE("canAssignNullToQObject.2.qml")); |
|
2293 |
|
2294 MyQmlObject *o = qobject_cast<MyQmlObject *>(component.create()); |
|
2295 QVERIFY(o != 0); |
|
2296 |
|
2297 QVERIFY(o->objectProperty() == 0); |
|
2298 |
|
2299 delete o; |
|
2300 } |
|
2301 } |
|
2302 |
|
2303 void tst_qdeclarativeecmascript::functionAssignment() |
|
2304 { |
|
2305 { |
|
2306 QDeclarativeComponent component(&engine, TEST_FILE("functionAssignment.1.qml")); |
|
2307 |
|
2308 QString url = component.url().toString(); |
|
2309 QString warning = url + ":4: Unable to assign a function to a property."; |
|
2310 QTest::ignoreMessage(QtWarningMsg, warning.toLatin1().constData()); |
|
2311 |
|
2312 MyQmlObject *o = qobject_cast<MyQmlObject *>(component.create()); |
|
2313 QVERIFY(o != 0); |
|
2314 |
|
2315 QVERIFY(!o->property("a").isValid()); |
|
2316 |
|
2317 delete o; |
|
2318 } |
|
2319 |
|
2320 { |
|
2321 QDeclarativeComponent component(&engine, TEST_FILE("functionAssignment.2.qml")); |
|
2322 |
|
2323 MyQmlObject *o = qobject_cast<MyQmlObject *>(component.create()); |
|
2324 QVERIFY(o != 0); |
|
2325 |
|
2326 QVERIFY(!o->property("a").isValid()); |
|
2327 |
|
2328 QString url = component.url().toString(); |
|
2329 QString warning = url + ":10: Error: Cannot assign a function to a property."; |
|
2330 QTest::ignoreMessage(QtWarningMsg, warning.toLatin1().constData()); |
|
2331 |
|
2332 o->setProperty("runTest", true); |
|
2333 |
|
2334 QVERIFY(!o->property("a").isValid()); |
|
2335 |
|
2336 delete o; |
|
2337 } |
|
2338 } |
|
2339 |
|
2340 void tst_qdeclarativeecmascript::eval() |
|
2341 { |
|
2342 QDeclarativeComponent component(&engine, TEST_FILE("eval.qml")); |
|
2343 |
|
2344 QObject *o = component.create(); |
|
2345 QVERIFY(o != 0); |
|
2346 |
|
2347 QCOMPARE(o->property("test1").toBool(), true); |
|
2348 QCOMPARE(o->property("test2").toBool(), true); |
|
2349 QCOMPARE(o->property("test3").toBool(), true); |
|
2350 QCOMPARE(o->property("test4").toBool(), true); |
|
2351 QCOMPARE(o->property("test5").toBool(), true); |
|
2352 |
|
2353 delete o; |
|
2354 } |
|
2355 |
|
2356 void tst_qdeclarativeecmascript::function() |
|
2357 { |
|
2358 QDeclarativeComponent component(&engine, TEST_FILE("function.qml")); |
|
2359 |
|
2360 QObject *o = component.create(); |
|
2361 QVERIFY(o != 0); |
|
2362 |
|
2363 QCOMPARE(o->property("test1").toBool(), true); |
|
2364 QCOMPARE(o->property("test2").toBool(), true); |
|
2365 QCOMPARE(o->property("test3").toBool(), true); |
|
2366 |
|
2367 delete o; |
|
2368 } |
|
2369 |
|
2370 #define TRY_WAIT(expr) \ |
|
2371 do { \ |
|
2372 for (int ii = 0; ii < 6; ++ii) { \ |
|
2373 if ((expr)) break; \ |
|
2374 QTest::qWait(50); \ |
|
2375 } \ |
|
2376 QVERIFY((expr)); \ |
|
2377 } while (false) |
|
2378 |
|
2379 // Test the "Qt.include" method |
|
2380 void tst_qdeclarativeecmascript::include() |
|
2381 { |
|
2382 // Non-library relative include |
|
2383 { |
|
2384 QDeclarativeComponent component(&engine, TEST_FILE("include.qml")); |
|
2385 QObject *o = component.create(); |
|
2386 QVERIFY(o != 0); |
|
2387 |
|
2388 QCOMPARE(o->property("test0").toInt(), 99); |
|
2389 QCOMPARE(o->property("test1").toBool(), true); |
|
2390 QCOMPARE(o->property("test2").toBool(), true); |
|
2391 QCOMPARE(o->property("test2_1").toBool(), true); |
|
2392 QCOMPARE(o->property("test3").toBool(), true); |
|
2393 QCOMPARE(o->property("test3_1").toBool(), true); |
|
2394 |
|
2395 delete o; |
|
2396 } |
|
2397 |
|
2398 // Library relative include |
|
2399 { |
|
2400 QDeclarativeComponent component(&engine, TEST_FILE("include_shared.qml")); |
|
2401 QObject *o = component.create(); |
|
2402 QVERIFY(o != 0); |
|
2403 |
|
2404 QCOMPARE(o->property("test0").toInt(), 99); |
|
2405 QCOMPARE(o->property("test1").toBool(), true); |
|
2406 QCOMPARE(o->property("test2").toBool(), true); |
|
2407 QCOMPARE(o->property("test2_1").toBool(), true); |
|
2408 QCOMPARE(o->property("test3").toBool(), true); |
|
2409 QCOMPARE(o->property("test3_1").toBool(), true); |
|
2410 |
|
2411 delete o; |
|
2412 } |
|
2413 |
|
2414 // Callback |
|
2415 { |
|
2416 QDeclarativeComponent component(&engine, TEST_FILE("include_callback.qml")); |
|
2417 QObject *o = component.create(); |
|
2418 QVERIFY(o != 0); |
|
2419 |
|
2420 QCOMPARE(o->property("test1").toBool(), true); |
|
2421 QCOMPARE(o->property("test2").toBool(), true); |
|
2422 QCOMPARE(o->property("test3").toBool(), true); |
|
2423 QCOMPARE(o->property("test4").toBool(), true); |
|
2424 QCOMPARE(o->property("test5").toBool(), true); |
|
2425 QCOMPARE(o->property("test6").toBool(), true); |
|
2426 |
|
2427 delete o; |
|
2428 } |
|
2429 |
|
2430 // Including file with ".pragma library" |
|
2431 { |
|
2432 QDeclarativeComponent component(&engine, TEST_FILE("include_pragma.qml")); |
|
2433 QObject *o = component.create(); |
|
2434 QVERIFY(o != 0); |
|
2435 QCOMPARE(o->property("test1").toInt(), 100); |
|
2436 |
|
2437 delete o; |
|
2438 } |
|
2439 |
|
2440 // Remote - success |
|
2441 { |
|
2442 TestHTTPServer server(8111); |
|
2443 QVERIFY(server.isValid()); |
|
2444 server.serveDirectory(SRCDIR "/data"); |
|
2445 |
|
2446 QDeclarativeComponent component(&engine, TEST_FILE("include_remote.qml")); |
|
2447 QObject *o = component.create(); |
|
2448 QVERIFY(o != 0); |
|
2449 |
|
2450 TRY_WAIT(o->property("done").toBool() == true); |
|
2451 TRY_WAIT(o->property("done2").toBool() == true); |
|
2452 |
|
2453 QCOMPARE(o->property("test1").toBool(), true); |
|
2454 QCOMPARE(o->property("test2").toBool(), true); |
|
2455 QCOMPARE(o->property("test3").toBool(), true); |
|
2456 QCOMPARE(o->property("test4").toBool(), true); |
|
2457 QCOMPARE(o->property("test5").toBool(), true); |
|
2458 |
|
2459 QCOMPARE(o->property("test6").toBool(), true); |
|
2460 QCOMPARE(o->property("test7").toBool(), true); |
|
2461 QCOMPARE(o->property("test8").toBool(), true); |
|
2462 QCOMPARE(o->property("test9").toBool(), true); |
|
2463 QCOMPARE(o->property("test10").toBool(), true); |
|
2464 |
|
2465 delete o; |
|
2466 } |
|
2467 |
|
2468 // Remote - error |
|
2469 { |
|
2470 TestHTTPServer server(8111); |
|
2471 QVERIFY(server.isValid()); |
|
2472 server.serveDirectory(SRCDIR "/data"); |
|
2473 |
|
2474 QDeclarativeComponent component(&engine, TEST_FILE("include_remote_missing.qml")); |
|
2475 QObject *o = component.create(); |
|
2476 QVERIFY(o != 0); |
|
2477 |
|
2478 TRY_WAIT(o->property("done").toBool() == true); |
|
2479 |
|
2480 QCOMPARE(o->property("test1").toBool(), true); |
|
2481 QCOMPARE(o->property("test2").toBool(), true); |
|
2482 QCOMPARE(o->property("test3").toBool(), true); |
|
2483 |
|
2484 delete o; |
|
2485 } |
|
2486 } |
|
2487 |
|
2488 void tst_qdeclarativeecmascript::qtbug_10696() |
|
2489 { |
|
2490 QDeclarativeComponent component(&engine, TEST_FILE("qtbug_10696.qml")); |
|
2491 QObject *o = component.create(); |
|
2492 QVERIFY(o != 0); |
|
2493 delete o; |
|
2494 } |
|
2495 |
|
2496 QTEST_MAIN(tst_qdeclarativeecmascript) |
|
2497 |
|
2498 #include "tst_qdeclarativeecmascript.moc" |