tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp
changeset 30 5dc02b23752f
child 33 3e2da88830cd
equal deleted inserted replaced
29:b72c6db6890b 30:5dc02b23752f
       
     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"