Remove "All rights reserved" line from license headers.
[profile/ivi/qtdeclarative.git] / tests / auto / declarative / qdeclarativeecmascript / tst_qdeclarativeecmascript.cpp
index 3fdf1e9..9c84405 100644 (file)
@@ -1,8 +1,7 @@
 /****************************************************************************
 **
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
 **
 ** This file is part of the test suite of the Qt Toolkit.
 **
@@ -35,6 +34,7 @@
 **
 **
 **
+**
 ** $QT_END_LICENSE$
 **
 ****************************************************************************/
 #include <QtCore/qdir.h>
 #include <QtCore/qnumeric.h>
 #include <private/qdeclarativeengine_p.h>
-#include <private/qv8gccallback_p.h>
 #include <private/qdeclarativevmemetaobject_p.h>
 #include <private/qv4compiler_p.h>
 #include "testtypes.h"
 #include "testhttpserver.h"
-#include "../shared/util.h"
+#include "../../shared/util.h"
 
 /*
 This test covers evaluation of ECMAScript expressions and bindings from within
@@ -62,17 +61,8 @@ QML.  This does not include static QML language issues.
 
 Static QML language issues are covered in qmllanguage
 */
-inline QUrl TEST_FILE(const QString &filename)
-{
-    return QUrl::fromLocalFile(TESTDATA(filename));
-}
-
-inline QUrl TEST_FILE(const char *filename)
-{
-    return TEST_FILE(QLatin1String(filename));
-}
 
-class tst_qdeclarativeecmascript : public QObject
+class tst_qdeclarativeecmascript : public QDeclarativeDataTest
 {
     Q_OBJECT
 public:
@@ -114,6 +104,7 @@ private slots:
     void objectHasOwnProperty();
     void selfDeletingBinding();
     void extendedObjectPropertyLookup();
+    void extendedObjectPropertyLookup2();
     void scriptErrors();
     void functionErrors();
     void propertyAssignmentErrors();
@@ -147,11 +138,15 @@ private slots:
     void signalWithJSValueInVariant();
     void signalWithJSValueInVariant_twoEngines_data();
     void signalWithJSValueInVariant_twoEngines();
+    void signalWithQJSValue_data();
+    void signalWithQJSValue();
     void moduleApi_data();
     void moduleApi();
     void importScripts_data();
     void importScripts();
     void scarceResources();
+    void scarceResources_data();
+    void scarceResources_other();
     void propertyChangeSlots();
     void propertyVar_data();
     void propertyVar();
@@ -177,8 +172,10 @@ private slots:
     void sequenceConversionThreads();
     void sequenceConversionBindings();
     void sequenceConversionCopy();
+    void assignSequenceTypes();
     void qtbug_22464();
     void qtbug_21580();
+
     void bug1();
     void bug2();
     void dynamicCreationCrash();
@@ -201,6 +198,8 @@ private slots:
     void qtbug_10696();
     void qtbug_11606();
     void qtbug_11600();
+    void qtbug_21864();
+    void qobjectConnectionListExceptionHandling();
     void nonscriptable();
     void deleteLater();
     void in();
@@ -213,6 +212,9 @@ private slots:
     void aliasWritesOverrideBindings();
     void aliasToCompositeElement();
     void realToInt();
+    void urlProperty();
+    void urlPropertyWithEncoding();
+    void urlListPropertyWithEncoding();
     void dynamicString();
     void include();
     void signalHandlers();
@@ -241,12 +243,16 @@ private:
     QDeclarativeEngine engine;
 };
 
-void tst_qdeclarativeecmascript::initTestCase() { registerTypes(); }
+void tst_qdeclarativeecmascript::initTestCase()
+{
+    QDeclarativeDataTest::initTestCase();
+    registerTypes();
+}
 
 void tst_qdeclarativeecmascript::assignBasicTypes()
 {
     {
-    QDeclarativeComponent component(&engine, TEST_FILE("assignBasicTypes.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("assignBasicTypes.qml"));
     MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
     QVERIFY(object != 0);
     QCOMPARE(object->flagProperty(), MyTypeObject::FlagVal1 | MyTypeObject::FlagVal3);
@@ -274,7 +280,7 @@ void tst_qdeclarativeecmascript::assignBasicTypes()
     delete object;
     }
     {
-    QDeclarativeComponent component(&engine, TEST_FILE("assignBasicTypes.2.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("assignBasicTypes.2.qml"));
     MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
     QVERIFY(object != 0);
     QCOMPARE(object->flagProperty(), MyTypeObject::FlagVal1 | MyTypeObject::FlagVal3);
@@ -306,7 +312,7 @@ void tst_qdeclarativeecmascript::assignBasicTypes()
 void tst_qdeclarativeecmascript::idShortcutInvalidates()
 {
     {
-        QDeclarativeComponent component(&engine, TEST_FILE("idShortcutInvalidates.qml"));
+        QDeclarativeComponent component(&engine, testFileUrl("idShortcutInvalidates.qml"));
         MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
         QVERIFY(object != 0);
         QVERIFY(object->objectProperty() != 0);
@@ -316,7 +322,7 @@ void tst_qdeclarativeecmascript::idShortcutInvalidates()
     }
 
     {
-        QDeclarativeComponent component(&engine, TEST_FILE("idShortcutInvalidates.1.qml"));
+        QDeclarativeComponent component(&engine, testFileUrl("idShortcutInvalidates.1.qml"));
         MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
         QVERIFY(object != 0);
         QVERIFY(object->objectProperty() != 0);
@@ -329,14 +335,14 @@ void tst_qdeclarativeecmascript::idShortcutInvalidates()
 void tst_qdeclarativeecmascript::boolPropertiesEvaluateAsBool()
 {
     {
-        QDeclarativeComponent component(&engine, TEST_FILE("boolPropertiesEvaluateAsBool.1.qml"));
+        QDeclarativeComponent component(&engine, testFileUrl("boolPropertiesEvaluateAsBool.1.qml"));
         MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
         QVERIFY(object != 0);
         QCOMPARE(object->stringProperty(), QLatin1String("pass"));
         delete object;
     }
     {
-        QDeclarativeComponent component(&engine, TEST_FILE("boolPropertiesEvaluateAsBool.2.qml"));
+        QDeclarativeComponent component(&engine, testFileUrl("boolPropertiesEvaluateAsBool.2.qml"));
         MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
         QVERIFY(object != 0);
         QCOMPARE(object->stringProperty(), QLatin1String("pass"));
@@ -347,7 +353,7 @@ void tst_qdeclarativeecmascript::boolPropertiesEvaluateAsBool()
 void tst_qdeclarativeecmascript::signalAssignment()
 {
     {
-        QDeclarativeComponent component(&engine, TEST_FILE("signalAssignment.1.qml"));
+        QDeclarativeComponent component(&engine, testFileUrl("signalAssignment.1.qml"));
         MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
         QVERIFY(object != 0);
         QCOMPARE(object->string(), QString());
@@ -357,7 +363,7 @@ void tst_qdeclarativeecmascript::signalAssignment()
     }
 
     {
-        QDeclarativeComponent component(&engine, TEST_FILE("signalAssignment.2.qml"));
+        QDeclarativeComponent component(&engine, testFileUrl("signalAssignment.2.qml"));
         MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
         QVERIFY(object != 0);
         QCOMPARE(object->string(), QString());
@@ -370,7 +376,7 @@ void tst_qdeclarativeecmascript::signalAssignment()
 void tst_qdeclarativeecmascript::methods()
 {
     {
-        QDeclarativeComponent component(&engine, TEST_FILE("methods.1.qml"));
+        QDeclarativeComponent component(&engine, testFileUrl("methods.1.qml"));
         MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
         QVERIFY(object != 0);
         QCOMPARE(object->methodCalled(), false);
@@ -382,7 +388,7 @@ void tst_qdeclarativeecmascript::methods()
     }
 
     {
-        QDeclarativeComponent component(&engine, TEST_FILE("methods.2.qml"));
+        QDeclarativeComponent component(&engine, testFileUrl("methods.2.qml"));
         MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
         QVERIFY(object != 0);
         QCOMPARE(object->methodCalled(), false);
@@ -394,7 +400,7 @@ void tst_qdeclarativeecmascript::methods()
     }
 
     {
-        QDeclarativeComponent component(&engine, TEST_FILE("methods.3.qml"));
+        QDeclarativeComponent component(&engine, testFileUrl("methods.3.qml"));
         QObject *object = component.create();
         QVERIFY(object != 0);
         QCOMPARE(object->property("test").toInt(), 19);
@@ -402,7 +408,7 @@ void tst_qdeclarativeecmascript::methods()
     }
 
     {
-        QDeclarativeComponent component(&engine, TEST_FILE("methods.4.qml"));
+        QDeclarativeComponent component(&engine, testFileUrl("methods.4.qml"));
         QObject *object = component.create();
         QVERIFY(object != 0);
         QCOMPARE(object->property("test").toInt(), 19);
@@ -412,7 +418,7 @@ void tst_qdeclarativeecmascript::methods()
     }
 
     {
-        QDeclarativeComponent component(&engine, TEST_FILE("methods.5.qml"));
+        QDeclarativeComponent component(&engine, testFileUrl("methods.5.qml"));
         QObject *object = component.create();
         QVERIFY(object != 0);
         QCOMPARE(object->property("test").toInt(), 9);
@@ -422,7 +428,7 @@ void tst_qdeclarativeecmascript::methods()
 
 void tst_qdeclarativeecmascript::bindingLoop()
 {
-    QDeclarativeComponent component(&engine, TEST_FILE("bindingLoop.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("bindingLoop.qml"));
     QString warning = component.url().toString() + ":5:9: QML MyQmlObject: Binding loop detected for property \"stringProperty\"";
     QTest::ignoreMessage(QtWarningMsg, warning.toLatin1().constData());
     QObject *object = component.create();
@@ -631,7 +637,7 @@ void tst_qdeclarativeecmascript::objectPropertiesTriggerReeval()
 
 void tst_qdeclarativeecmascript::deferredProperties()
 {
-    QDeclarativeComponent component(&engine, TEST_FILE("deferredProperties.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("deferredProperties.qml"));
     MyDeferredObject *object = 
         qobject_cast<MyDeferredObject *>(component.create());
     QVERIFY(object != 0);
@@ -654,7 +660,7 @@ void tst_qdeclarativeecmascript::deferredProperties()
 // Check errors on deferred properties are correctly emitted
 void tst_qdeclarativeecmascript::deferredPropertiesErrors()
 {
-    QDeclarativeComponent component(&engine, TEST_FILE("deferredPropertiesErrors.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("deferredPropertiesErrors.qml"));
     MyDeferredObject *object = 
         qobject_cast<MyDeferredObject *>(component.create());
     QVERIFY(object != 0);
@@ -672,7 +678,7 @@ void tst_qdeclarativeecmascript::deferredPropertiesErrors()
 
 void tst_qdeclarativeecmascript::extensionObjects()
 {
-    QDeclarativeComponent component(&engine, TEST_FILE("extensionObjects.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("extensionObjects.qml"));
     MyExtendedObject *object = 
         qobject_cast<MyExtendedObject *>(component.create());
     QVERIFY(object != 0);
@@ -697,7 +703,7 @@ void tst_qdeclarativeecmascript::extensionObjects()
 
 void tst_qdeclarativeecmascript::overrideExtensionProperties()
 {
-    QDeclarativeComponent component(&engine, TEST_FILE("extensionObjectsPropertyOverride.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("extensionObjectsPropertyOverride.qml"));
     OverrideDefaultPropertyObject *object =
         qobject_cast<OverrideDefaultPropertyObject *>(component.create());
     QVERIFY(object != 0);
@@ -710,7 +716,7 @@ void tst_qdeclarativeecmascript::overrideExtensionProperties()
 void tst_qdeclarativeecmascript::attachedProperties()
 {
     {
-        QDeclarativeComponent component(&engine, TEST_FILE("attachedProperty.qml"));
+        QDeclarativeComponent component(&engine, testFileUrl("attachedProperty.qml"));
         QObject *object = component.create();
         QVERIFY(object != 0);
         QCOMPARE(object->property("a").toInt(), 19);
@@ -721,7 +727,7 @@ void tst_qdeclarativeecmascript::attachedProperties()
     }
 
     {
-        QDeclarativeComponent component(&engine, TEST_FILE("attachedProperty.2.qml"));
+        QDeclarativeComponent component(&engine, testFileUrl("attachedProperty.2.qml"));
         QObject *object = component.create();
         QVERIFY(object != 0);
         QCOMPARE(object->property("a").toInt(), 26);
@@ -733,7 +739,7 @@ void tst_qdeclarativeecmascript::attachedProperties()
     }
 
     {
-        QDeclarativeComponent component(&engine, TEST_FILE("writeAttachedProperty.qml"));
+        QDeclarativeComponent component(&engine, testFileUrl("writeAttachedProperty.qml"));
         QObject *object = component.create();
         QVERIFY(object != 0);
 
@@ -752,7 +758,7 @@ void tst_qdeclarativeecmascript::enums()
 {
     // Existent enums
     {
-    QDeclarativeComponent component(&engine, TEST_FILE("enums.1.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("enums.1.qml"));
     QObject *object = component.create();
     QVERIFY(object != 0);
 
@@ -771,7 +777,7 @@ void tst_qdeclarativeecmascript::enums()
     }
     // Non-existent enums
     {
-    QDeclarativeComponent component(&engine, TEST_FILE("enums.2.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("enums.2.qml"));
 
     QString warning1 = component.url().toString() + ":5: Unable to assign [undefined] to int";
     QString warning2 = component.url().toString() + ":6: Unable to assign [undefined] to int";
@@ -789,7 +795,7 @@ void tst_qdeclarativeecmascript::enums()
 
 void tst_qdeclarativeecmascript::valueTypeFunctions()
 {
-    QDeclarativeComponent component(&engine, TEST_FILE("valueTypeFunctions.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("valueTypeFunctions.qml"));
     MyTypeObject *obj = qobject_cast<MyTypeObject*>(component.create());
     QVERIFY(obj != 0);
     QCOMPARE(obj->rectProperty(), QRect(0,0,100,100));
@@ -806,7 +812,7 @@ void tst_qdeclarativeecmascript::constantsOverrideBindings()
 {
     // From ECMAScript
     {
-        QDeclarativeComponent component(&engine, TEST_FILE("constantsOverrideBindings.1.qml"));
+        QDeclarativeComponent component(&engine, testFileUrl("constantsOverrideBindings.1.qml"));
         MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
         QVERIFY(object != 0);
 
@@ -825,7 +831,7 @@ void tst_qdeclarativeecmascript::constantsOverrideBindings()
 
     // During construction
     {
-        QDeclarativeComponent component(&engine, TEST_FILE("constantsOverrideBindings.2.qml"));
+        QDeclarativeComponent component(&engine, testFileUrl("constantsOverrideBindings.2.qml"));
         MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
         QVERIFY(object != 0);
 
@@ -841,7 +847,7 @@ void tst_qdeclarativeecmascript::constantsOverrideBindings()
 #if 0
     // From C++
     {
-        QDeclarativeComponent component(&engine, TEST_FILE("constantsOverrideBindings.3.qml"));
+        QDeclarativeComponent component(&engine, testFileUrl("constantsOverrideBindings.3.qml"));
         MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
         QVERIFY(object != 0);
 
@@ -861,7 +867,7 @@ void tst_qdeclarativeecmascript::constantsOverrideBindings()
 
     // Using an alias
     {
-        QDeclarativeComponent component(&engine, TEST_FILE("constantsOverrideBindings.4.qml"));
+        QDeclarativeComponent component(&engine, testFileUrl("constantsOverrideBindings.4.qml"));
         MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
         QVERIFY(object != 0);
 
@@ -882,7 +888,7 @@ the original binding to be disabled.
 void tst_qdeclarativeecmascript::outerBindingOverridesInnerBinding()
 {
     QDeclarativeComponent component(&engine, 
-                           TEST_FILE("outerBindingOverridesInnerBinding.qml"));
+                           testFileUrl("outerBindingOverridesInnerBinding.qml"));
     MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
     QVERIFY(object != 0);
 
@@ -910,7 +916,7 @@ Tests for a regression where this used to crash.
 */
 void tst_qdeclarativeecmascript::nonExistentAttachedObject()
 {
-    QDeclarativeComponent component(&engine, TEST_FILE("nonExistentAttachedObject.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("nonExistentAttachedObject.qml"));
 
     QString warning = component.url().toString() + ":4: Unable to assign [undefined] to QString";
     QTest::ignoreMessage(QtWarningMsg, qPrintable(warning));
@@ -924,7 +930,7 @@ void tst_qdeclarativeecmascript::nonExistentAttachedObject()
 void tst_qdeclarativeecmascript::scope()
 {
     {
-        QDeclarativeComponent component(&engine, TEST_FILE("scope.qml"));
+        QDeclarativeComponent component(&engine, testFileUrl("scope.qml"));
         QObject *object = component.create();
         QVERIFY(object != 0);
 
@@ -943,7 +949,7 @@ void tst_qdeclarativeecmascript::scope()
     }
 
     {
-        QDeclarativeComponent component(&engine, TEST_FILE("scope.2.qml"));
+        QDeclarativeComponent component(&engine, testFileUrl("scope.2.qml"));
         QObject *object = component.create();
         QVERIFY(object != 0);
 
@@ -958,7 +964,7 @@ void tst_qdeclarativeecmascript::scope()
     }
 
     {
-        QDeclarativeComponent component(&engine, TEST_FILE("scope.3.qml"));
+        QDeclarativeComponent component(&engine, testFileUrl("scope.3.qml"));
         QObject *object = component.create();
         QVERIFY(object != 0);
 
@@ -971,7 +977,7 @@ void tst_qdeclarativeecmascript::scope()
 
     // Signal argument scope
     {
-        QDeclarativeComponent component(&engine, TEST_FILE("scope.4.qml"));
+        QDeclarativeComponent component(&engine, testFileUrl("scope.4.qml"));
         MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
         QVERIFY(object != 0);
 
@@ -987,7 +993,7 @@ void tst_qdeclarativeecmascript::scope()
     }
 
     {
-        QDeclarativeComponent component(&engine, TEST_FILE("scope.5.qml"));
+        QDeclarativeComponent component(&engine, testFileUrl("scope.5.qml"));
         QObject *object = component.create();
         QVERIFY(object != 0);
 
@@ -998,7 +1004,7 @@ void tst_qdeclarativeecmascript::scope()
     }
 
     {
-        QDeclarativeComponent component(&engine, TEST_FILE("scope.6.qml"));
+        QDeclarativeComponent component(&engine, testFileUrl("scope.6.qml"));
         QObject *object = component.create();
         QVERIFY(object != 0);
 
@@ -1012,7 +1018,7 @@ void tst_qdeclarativeecmascript::scope()
 // importing context
 void tst_qdeclarativeecmascript::importScope()
 {
-    QDeclarativeComponent component(&engine, TEST_FILE("importScope.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("importScope.qml"));
     QObject *o = component.create();
     QVERIFY(o != 0);
 
@@ -1027,7 +1033,7 @@ is essentially a test of QDeclarativeMetaType::copy()
 */
 void tst_qdeclarativeecmascript::signalParameterTypes()
 {
-    QDeclarativeComponent component(&engine, TEST_FILE("signalParameterTypes.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("signalParameterTypes.qml"));
     MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
     QVERIFY(object != 0);
 
@@ -1048,7 +1054,7 @@ Test that two JS objects for the same QObject compare as equal.
 */
 void tst_qdeclarativeecmascript::objectsCompareAsEqual()
 {
-    QDeclarativeComponent component(&engine, TEST_FILE("objectsCompareAsEqual.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("objectsCompareAsEqual.qml"));
     QObject *object = component.create();
     QVERIFY(object != 0);
 
@@ -1068,7 +1074,7 @@ Tests for a regression where the binding would not reevaluate.
 */
 void tst_qdeclarativeecmascript::aliasPropertyAndBinding()
 {
-    QDeclarativeComponent component(&engine, TEST_FILE("aliasPropertyAndBinding.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("aliasPropertyAndBinding.qml"));
     QObject *object = component.create();
     QVERIFY(object != 0);
 
@@ -1092,7 +1098,7 @@ void tst_qdeclarativeecmascript::aliasPropertyReset()
     QObject *object = 0;
 
     // test that a manual write (of undefined) to a resettable aliased property succeeds
-    QDeclarativeComponent c1(&engine, TEST_FILE("aliasreset/aliasPropertyReset.1.qml"));
+    QDeclarativeComponent c1(&engine, testFileUrl("aliasreset/aliasPropertyReset.1.qml"));
     object = c1.create();
     QVERIFY(object != 0);
     QVERIFY(object->property("sourceComponentAlias").value<QDeclarativeComponent*>() != 0);
@@ -1103,7 +1109,7 @@ void tst_qdeclarativeecmascript::aliasPropertyReset()
     delete object;
 
     // test that a manual write (of undefined) to a resettable alias property succeeds
-    QDeclarativeComponent c2(&engine, TEST_FILE("aliasreset/aliasPropertyReset.2.qml"));
+    QDeclarativeComponent c2(&engine, testFileUrl("aliasreset/aliasPropertyReset.2.qml"));
     object = c2.create();
     QVERIFY(object != 0);
     QVERIFY(object->property("sourceComponentAlias").value<QDeclarativeComponent*>() != 0);
@@ -1114,7 +1120,7 @@ void tst_qdeclarativeecmascript::aliasPropertyReset()
     delete object;
 
     // test that an alias to a bound property works correctly
-    QDeclarativeComponent c3(&engine, TEST_FILE("aliasreset/aliasPropertyReset.3.qml"));
+    QDeclarativeComponent c3(&engine, testFileUrl("aliasreset/aliasPropertyReset.3.qml"));
     object = c3.create();
     QVERIFY(object != 0);
     QVERIFY(object->property("sourceComponentAlias").value<QDeclarativeComponent*>() != 0);
@@ -1128,7 +1134,7 @@ void tst_qdeclarativeecmascript::aliasPropertyReset()
 
     // test that a manual write (of undefined) to a resettable alias property
     // whose aliased property's object has been deleted, does not crash.
-    QDeclarativeComponent c4(&engine, TEST_FILE("aliasreset/aliasPropertyReset.4.qml"));
+    QDeclarativeComponent c4(&engine, testFileUrl("aliasreset/aliasPropertyReset.4.qml"));
     object = c4.create();
     QVERIFY(object != 0);
     QVERIFY(object->property("sourceComponentAlias").value<QDeclarativeComponent*>() != 0);
@@ -1143,14 +1149,14 @@ void tst_qdeclarativeecmascript::aliasPropertyReset()
     delete object;
 
     // test that binding an alias property to an undefined value works correctly
-    QDeclarativeComponent c5(&engine, TEST_FILE("aliasreset/aliasPropertyReset.5.qml"));
+    QDeclarativeComponent c5(&engine, testFileUrl("aliasreset/aliasPropertyReset.5.qml"));
     object = c5.create();
     QVERIFY(object != 0);
     QVERIFY(object->property("sourceComponentAlias").value<QDeclarativeComponent*>() == 0); // bound to undefined value.
     delete object;
 
     // test that a manual write (of undefined) to a non-resettable property fails properly
-    QUrl url = TEST_FILE("aliasreset/aliasPropertyReset.error.1.qml");
+    QUrl url = testFileUrl("aliasreset/aliasPropertyReset.error.1.qml");
     QString warning1 = url.toString() + QLatin1String(":15: Error: Cannot assign [undefined] to int");
     QDeclarativeComponent e1(&engine, url);
     object = e1.create();
@@ -1183,7 +1189,7 @@ void tst_qdeclarativeecmascript::dynamicCreation()
     QFETCH(QString, method);
     QFETCH(QString, createdName);
 
-    QDeclarativeComponent component(&engine, TEST_FILE("dynamicCreation.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("dynamicCreation.qml"));
     MyQmlObject *object = qobject_cast<MyQmlObject*>(component.create());
     QVERIFY(object != 0);
 
@@ -1201,7 +1207,7 @@ void tst_qdeclarativeecmascript::dynamicCreation()
 void tst_qdeclarativeecmascript::dynamicDestruction()
 {
     {
-    QDeclarativeComponent component(&engine, TEST_FILE("dynamicDeletion.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("dynamicDeletion.qml"));
     QDeclarativeGuard<MyQmlObject> object = qobject_cast<MyQmlObject*>(component.create());
     QVERIFY(object != 0);
     QDeclarativeGuard<QObject> createdQmlObject = 0;
@@ -1213,12 +1219,15 @@ void tst_qdeclarativeecmascript::dynamicDestruction()
 
     QMetaObject::invokeMethod(object, "killOther");
     QVERIFY(createdQmlObject);
-    QCoreApplication::instance()->processEvents(QEventLoop::DeferredDeletion);
+
+    QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
+    QCoreApplication::processEvents();
     QVERIFY(createdQmlObject);
     for (int ii = 0; createdQmlObject && ii < 50; ++ii) { // After 5 seconds we should give up
         if (createdQmlObject) {
             QTest::qWait(100);
-            QCoreApplication::instance()->processEvents(QEventLoop::DeferredDeletion);
+            QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
+            QCoreApplication::processEvents();
         }
     }
     QVERIFY(!createdQmlObject);
@@ -1226,13 +1235,13 @@ void tst_qdeclarativeecmascript::dynamicDestruction()
     QDeclarativeEngine::setObjectOwnership(object, QDeclarativeEngine::JavaScriptOwnership);
     QMetaObject::invokeMethod(object, "killMe");
     QVERIFY(object);
-    QTest::qWait(0);
-    QCoreApplication::instance()->processEvents(QEventLoop::DeferredDeletion);
+    QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
+    QCoreApplication::processEvents();
     QVERIFY(!object);
     }
 
     {
-    QDeclarativeComponent component(&engine, TEST_FILE("dynamicDeletion.2.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("dynamicDeletion.2.qml"));
     QObject *o = component.create();
     QVERIFY(o != 0);
 
@@ -1244,7 +1253,8 @@ void tst_qdeclarativeecmascript::dynamicDestruction()
 
     QMetaObject::invokeMethod(o, "destroy");
 
-    QCoreApplication::instance()->processEvents(QEventLoop::DeferredDeletion);
+    QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
+    QCoreApplication::processEvents();
 
     QVERIFY(qvariant_cast<QObject*>(o->property("objectProperty")) == 0);
 
@@ -1257,7 +1267,7 @@ void tst_qdeclarativeecmascript::dynamicDestruction()
 */
 void tst_qdeclarativeecmascript::objectToString()
 {
-    QDeclarativeComponent component(&engine, TEST_FILE("declarativeToString.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("declarativeToString.qml"));
     MyQmlObject *object = qobject_cast<MyQmlObject*>(component.create());
     QVERIFY(object != 0);
     QMetaObject::invokeMethod(object, "testToString");
@@ -1272,7 +1282,7 @@ void tst_qdeclarativeecmascript::objectToString()
 */
 void tst_qdeclarativeecmascript::objectHasOwnProperty()
 {
-    QUrl url = TEST_FILE("declarativeHasOwnProperty.qml");
+    QUrl url = testFileUrl("declarativeHasOwnProperty.qml");
     QString warning1 = url.toString() + ":59: TypeError: Cannot call method 'hasOwnProperty' of undefined";
     QString warning2 = url.toString() + ":64: TypeError: Cannot call method 'hasOwnProperty' of undefined";
     QString warning3 = url.toString() + ":69: TypeError: Cannot call method 'hasOwnProperty' of undefined";
@@ -1324,7 +1334,7 @@ This test is best run under valgrind to ensure no invalid memory access occur.
 void tst_qdeclarativeecmascript::selfDeletingBinding()
 {
     {
-        QDeclarativeComponent component(&engine, TEST_FILE("selfDeletingBinding.qml"));
+        QDeclarativeComponent component(&engine, testFileUrl("selfDeletingBinding.qml"));
         QObject *object = component.create();
         QVERIFY(object != 0);
         object->setProperty("triggerDelete", true);
@@ -1332,7 +1342,7 @@ void tst_qdeclarativeecmascript::selfDeletingBinding()
     }
 
     {
-        QDeclarativeComponent component(&engine, TEST_FILE("selfDeletingBinding.2.qml"));
+        QDeclarativeComponent component(&engine, testFileUrl("selfDeletingBinding.2.qml"));
         QObject *object = component.create();
         QVERIFY(object != 0);
         object->setProperty("triggerDelete", true);
@@ -1349,28 +1359,43 @@ and no synthesiszed properties).
 */
 void tst_qdeclarativeecmascript::extendedObjectPropertyLookup()
 {
-    QDeclarativeComponent component(&engine, TEST_FILE("extendedObjectPropertyLookup.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("extendedObjectPropertyLookup.qml"));
     QObject *object = component.create();
     QVERIFY(object != 0);
     delete object;
 }
 
 /*
+Test that extended object properties can be accessed correctly.
+*/
+void tst_qdeclarativeecmascript::extendedObjectPropertyLookup2()
+{
+    QDeclarativeComponent component(&engine, testFileUrl("extendedObjectPropertyLookup2.qml"));
+    QObject *object = component.create();
+    QVERIFY(object != 0);
+
+    QVariant returnValue;
+    QVERIFY(QMetaObject::invokeMethod(object, "getValue", Q_RETURN_ARG(QVariant, returnValue)));
+    QCOMPARE(returnValue.toInt(), 42);
+
+    delete object;
+}
+/*
 Test file/lineNumbers for binding/Script errors.
 */
 void tst_qdeclarativeecmascript::scriptErrors()
 {
-    QDeclarativeComponent component(&engine, TEST_FILE("scriptErrors.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("scriptErrors.qml"));
     QString url = component.url().toString();
 
     QString warning1 = url.left(url.length() - 3) + "js:2: Error: Invalid write to global property \"a\"";
     QString warning2 = url + ":5: ReferenceError: Can't find variable: a";
     QString warning3 = url.left(url.length() - 3) + "js:4: Error: Invalid write to global property \"a\"";
-    QString warning4 = url + ":10: ReferenceError: Can't find variable: a";
-    QString warning5 = url + ":8: ReferenceError: Can't find variable: a";
-    QString warning6 = url + ":7: Unable to assign [undefined] to int";
-    QString warning7 = url + ":12: Error: Cannot assign to read-only property \"trueProperty\"";
-    QString warning8 = url + ":13: Error: Cannot assign to non-existent property \"fakeProperty\"";
+    QString warning4 = url + ":13: ReferenceError: Can't find variable: a";
+    QString warning5 = url + ":11: ReferenceError: Can't find variable: a";
+    QString warning6 = url + ":10: Unable to assign [undefined] to int";
+    QString warning7 = url + ":15: Error: Cannot assign to read-only property \"trueProperty\"";
+    QString warning8 = url + ":16: Error: Cannot assign to non-existent property \"fakeProperty\"";
 
     QTest::ignoreMessage(QtWarningMsg, warning1.toLatin1().constData());
     QTest::ignoreMessage(QtWarningMsg, warning2.toLatin1().constData());
@@ -1397,7 +1422,7 @@ Test file/lineNumbers for inline functions.
 */
 void tst_qdeclarativeecmascript::functionErrors()
 {
-    QDeclarativeComponent component(&engine, TEST_FILE("functionErrors.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("functionErrors.qml"));
     QString url = component.url().toString();
 
     QString warning = url + ":5: Error: Invalid write to global property \"a\"";
@@ -1409,15 +1434,15 @@ void tst_qdeclarativeecmascript::functionErrors()
     delete object;
 
     // test that if an exception occurs while invoking js function from cpp, it is reported as expected.
-    QDeclarativeComponent componentTwo(&engine, TEST_FILE("scarceresources/scarceResourceFunctionFail.qml"));
+    QDeclarativeComponent componentTwo(&engine, testFileUrl("scarceResourceFunctionFail.var.qml"));
     url = componentTwo.url().toString();
     object = componentTwo.create();
     QVERIFY(object != 0);
 
     QString srpname = object->property("srp_name").toString();
     
-    warning = url + QLatin1String(":17: TypeError: Property 'scarceResource' of object ") + srpname + 
-              QLatin1String(" is not a function");
+    warning = url + QLatin1String(":16: TypeError: Property 'scarceResource' of object ") + srpname
+                  + QLatin1String(" is not a function");
     QTest::ignoreMessage(QtWarningMsg, warning.toLatin1().constData()); // we expect a meaningful warning to be printed.
     QMetaObject::invokeMethod(object, "retrieveScarceResource");
     delete object;
@@ -1428,7 +1453,7 @@ Test various errors that can occur when assigning a property from script
 */
 void tst_qdeclarativeecmascript::propertyAssignmentErrors()
 {
-    QDeclarativeComponent component(&engine, TEST_FILE("propertyAssignmentErrors.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("propertyAssignmentErrors.qml"));
 
     QString url = component.url().toString();
 
@@ -1447,7 +1472,7 @@ a signal script.
 */
 void tst_qdeclarativeecmascript::signalTriggeredBindings()
 {
-    QDeclarativeComponent component(&engine, TEST_FILE("signalTriggeredBindings.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("signalTriggeredBindings.qml"));
     MyQmlObject *object = qobject_cast<MyQmlObject*>(component.create());
     QVERIFY(object != 0);
 
@@ -1475,7 +1500,7 @@ Test that list properties can be iterated from ECMAScript
 */
 void tst_qdeclarativeecmascript::listProperties()
 {
-    QDeclarativeComponent component(&engine, TEST_FILE("listProperties.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("listProperties.qml"));
     MyQmlObject *object = qobject_cast<MyQmlObject*>(component.create());
     QVERIFY(object != 0);
 
@@ -1489,7 +1514,7 @@ void tst_qdeclarativeecmascript::listProperties()
 
 void tst_qdeclarativeecmascript::exceptionClearsOnReeval()
 {
-    QDeclarativeComponent component(&engine, TEST_FILE("exceptionClearsOnReeval.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("exceptionClearsOnReeval.qml"));
     QString url = component.url().toString();
 
     QString warning = url + ":4: TypeError: Cannot read property 'objectProperty' of null";
@@ -1512,7 +1537,7 @@ void tst_qdeclarativeecmascript::exceptionClearsOnReeval()
 
 void tst_qdeclarativeecmascript::exceptionSlotProducesWarning()
 {
-    QDeclarativeComponent component(&engine, TEST_FILE("exceptionProducesWarning.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("exceptionProducesWarning.qml"));
     QString url = component.url().toString();
 
     QString warning = component.url().toString() + ":6: Error: JS exception";
@@ -1525,7 +1550,7 @@ void tst_qdeclarativeecmascript::exceptionSlotProducesWarning()
 
 void tst_qdeclarativeecmascript::exceptionBindingProducesWarning()
 {
-    QDeclarativeComponent component(&engine, TEST_FILE("exceptionProducesWarning2.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("exceptionProducesWarning2.qml"));
     QString url = component.url().toString();
 
     QString warning = component.url().toString() + ":5: Error: JS exception";
@@ -1546,7 +1571,7 @@ static void transientErrorsMsgHandler(QtMsgType, const char *)
 void tst_qdeclarativeecmascript::transientErrors()
 {
     {
-    QDeclarativeComponent component(&engine, TEST_FILE("transientErrors.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("transientErrors.qml"));
 
     transientErrorsMsgCount = 0;
     QtMsgHandler old = qInstallMsgHandler(transientErrorsMsgHandler);
@@ -1563,7 +1588,7 @@ void tst_qdeclarativeecmascript::transientErrors()
 
     // One binding erroring multiple times, but then resolving
     {
-    QDeclarativeComponent component(&engine, TEST_FILE("transientErrors.2.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("transientErrors.2.qml"));
 
     transientErrorsMsgCount = 0;
     QtMsgHandler old = qInstallMsgHandler(transientErrorsMsgHandler);
@@ -1582,7 +1607,7 @@ void tst_qdeclarativeecmascript::transientErrors()
 // Check that errors during shutdown are minimized
 void tst_qdeclarativeecmascript::shutdownErrors()
 {
-    QDeclarativeComponent component(&engine, TEST_FILE("shutdownErrors.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("shutdownErrors.qml"));
     QObject *object = component.create();
     QVERIFY(object != 0);
 
@@ -1597,7 +1622,7 @@ void tst_qdeclarativeecmascript::shutdownErrors()
 
 void tst_qdeclarativeecmascript::compositePropertyType()
 {
-    QDeclarativeComponent component(&engine, TEST_FILE("compositePropertyType.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("compositePropertyType.qml"));
 
     QTest::ignoreMessage(QtDebugMsg, "hello world");
     QObject *object = qobject_cast<QObject *>(component.create());
@@ -1607,7 +1632,7 @@ void tst_qdeclarativeecmascript::compositePropertyType()
 // QTBUG-5759
 void tst_qdeclarativeecmascript::jsObject()
 {
-    QDeclarativeComponent component(&engine, TEST_FILE("jsObject.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("jsObject.qml"));
     QObject *object = component.create();
     QVERIFY(object != 0);
 
@@ -1619,7 +1644,7 @@ void tst_qdeclarativeecmascript::jsObject()
 void tst_qdeclarativeecmascript::undefinedResetsProperty()
 {
     {
-    QDeclarativeComponent component(&engine, TEST_FILE("undefinedResetsProperty.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("undefinedResetsProperty.qml"));
     QObject *object = component.create();
     QVERIFY(object != 0);
 
@@ -1636,7 +1661,7 @@ void tst_qdeclarativeecmascript::undefinedResetsProperty()
     delete object;
     }
     {
-    QDeclarativeComponent component(&engine, TEST_FILE("undefinedResetsProperty.2.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("undefinedResetsProperty.2.qml"));
     QObject *object = component.create();
     QVERIFY(object != 0);
 
@@ -1653,7 +1678,7 @@ void tst_qdeclarativeecmascript::undefinedResetsProperty()
 // Aliases to variant properties should work
 void tst_qdeclarativeecmascript::qtbug_22464()
 {
-    QDeclarativeComponent component(&engine, TEST_FILE("qtbug_22464.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("qtbug_22464.qml"));
     QObject *object = component.create();
     QVERIFY(object != 0);
 
@@ -1664,7 +1689,7 @@ void tst_qdeclarativeecmascript::qtbug_22464()
 
 void tst_qdeclarativeecmascript::qtbug_21580()
 {
-    QDeclarativeComponent component(&engine, TEST_FILE("qtbug_21580.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("qtbug_21580.qml"));
 
     QObject *object = component.create();
     QVERIFY(object != 0);
@@ -1677,7 +1702,7 @@ void tst_qdeclarativeecmascript::qtbug_21580()
 // QTBUG-6781
 void tst_qdeclarativeecmascript::bug1()
 {
-    QDeclarativeComponent component(&engine, TEST_FILE("bug.1.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("bug.1.qml"));
     QObject *object = component.create();
     QVERIFY(object != 0);
 
@@ -1708,7 +1733,7 @@ void tst_qdeclarativeecmascript::bug2()
 // Don't crash in createObject when the component has errors.
 void tst_qdeclarativeecmascript::dynamicCreationCrash()
 {
-    QDeclarativeComponent component(&engine, TEST_FILE("dynamicCreation.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("dynamicCreation.qml"));
     MyQmlObject *object = qobject_cast<MyQmlObject*>(component.create());
     QVERIFY(object != 0);
 
@@ -1729,7 +1754,7 @@ void tst_qdeclarativeecmascript::dynamicCreationOwnership()
     // allow the engine to go out of scope too.
     {
         QDeclarativeEngine dcoEngine;
-        QDeclarativeComponent component(&dcoEngine, TEST_FILE("dynamicCreationOwnership.qml"));
+        QDeclarativeComponent component(&dcoEngine, testFileUrl("dynamicCreationOwnership.qml"));
         QObject *object = component.create();
         QVERIFY(object != 0);
         MyDynamicCreationDestructionObject *mdcdo = object->findChild<MyDynamicCreationDestructionObject*>("mdcdo");
@@ -1744,24 +1769,38 @@ void tst_qdeclarativeecmascript::dynamicCreationOwnership()
                 QMetaObject::invokeMethod(object, "performGc");
             }
             if (i % 10 == 0) {
-                QCoreApplication::processEvents(QEventLoop::DeferredDeletion);
+                QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
+                QCoreApplication::processEvents();
             }
         }
 
         delete object;
     }
-    QCoreApplication::processEvents(QEventLoop::DeferredDeletion);
+    QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
+    QCoreApplication::processEvents();
     QCOMPARE(dtorCount, expectedDtorCount);
 }
 
-//QTBUG-9367
 void tst_qdeclarativeecmascript::regExpBug()
 {
-    QDeclarativeComponent component(&engine, TEST_FILE("regExp.qml"));
-    MyQmlObject *object = qobject_cast<MyQmlObject*>(component.create());
-    QVERIFY(object != 0);
-    QCOMPARE(object->regExp().pattern(), QLatin1String("[a-zA-z]"));
-    delete object;
+    //QTBUG-9367
+    {
+        QDeclarativeComponent component(&engine, testFileUrl("regExp.qml"));
+        MyQmlObject *object = qobject_cast<MyQmlObject*>(component.create());
+        QVERIFY(object != 0);
+        QCOMPARE(object->regExp().pattern(), QLatin1String("[a-zA-z]"));
+        delete object;
+    }
+
+    //QTBUG-23068
+    {
+        QString err = QString(QLatin1String("%1:6 Invalid property assignment: regular expression expected; use /pattern/ syntax\n")).arg(testFileUrl("regExp.2.qml").toString());
+        QDeclarativeComponent component(&engine, testFileUrl("regExp.2.qml"));
+        QTest::ignoreMessage(QtWarningMsg, "QDeclarativeComponent: Component is not ready");
+        MyQmlObject *object = qobject_cast<MyQmlObject*>(component.create());
+        QVERIFY(!object);
+        QCOMPARE(component.errorString(), err);
+    }
 }
 
 static inline bool evaluate_error(QV8Engine *engine, v8::Handle<v8::Object> o, const char *source)
@@ -2289,7 +2328,7 @@ void tst_qdeclarativeecmascript::callQtInvokables()
 // QTBUG-13047 (check that you can pass registered object types as args)
 void tst_qdeclarativeecmascript::invokableObjectArg()
 {
-    QDeclarativeComponent component(&engine, TEST_FILE("invokableObjectArg.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("invokableObjectArg.qml"));
 
     QObject *o = component.create();
     QVERIFY(o);
@@ -2303,7 +2342,7 @@ void tst_qdeclarativeecmascript::invokableObjectArg()
 // QTBUG-13047 (check that you can return registered object types from methods)
 void tst_qdeclarativeecmascript::invokableObjectRet()
 {
-    QDeclarativeComponent component(&engine, TEST_FILE("invokableObjectRet.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("invokableObjectRet.qml"));
 
     QObject *o = component.create();
     QVERIFY(o);
@@ -2314,7 +2353,7 @@ void tst_qdeclarativeecmascript::invokableObjectRet()
 // QTBUG-5675
 void tst_qdeclarativeecmascript::listToVariant()
 {
-    QDeclarativeComponent component(&engine, TEST_FILE("listToVariant.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("listToVariant.qml"));
 
     MyQmlContainer container;
 
@@ -2335,7 +2374,7 @@ void tst_qdeclarativeecmascript::listToVariant()
 Q_DECLARE_METATYPE(QDeclarativeListProperty<MyQmlObject>)
 void tst_qdeclarativeecmascript::listAssignment()
 {
-    QDeclarativeComponent component(&engine, TEST_FILE("listAssignment.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("listAssignment.qml"));
     QObject *obj = component.create();
     QCOMPARE(obj->property("list1length").toInt(), 2);
     QDeclarativeListProperty<MyQmlObject> list1 = obj->property("list1").value<QDeclarativeListProperty<MyQmlObject> >();
@@ -2354,11 +2393,11 @@ void tst_qdeclarativeecmascript::multiEngineObject()
 
     QDeclarativeEngine e1;
     e1.rootContext()->setContextProperty("thing", &obj);
-    QDeclarativeComponent c1(&e1, TEST_FILE("multiEngineObject.qml"));
+    QDeclarativeComponent c1(&e1, testFileUrl("multiEngineObject.qml"));
 
     QDeclarativeEngine e2;
     e2.rootContext()->setContextProperty("thing", &obj);
-    QDeclarativeComponent c2(&e2, TEST_FILE("multiEngineObject.qml"));
+    QDeclarativeComponent c2(&e2, testFileUrl("multiEngineObject.qml"));
 
     QObject *o1 = c1.create();
     QObject *o2 = c2.create();
@@ -2373,7 +2412,7 @@ void tst_qdeclarativeecmascript::multiEngineObject()
 // Test that references to QObjects are cleanup when the object is destroyed
 void tst_qdeclarativeecmascript::deletedObject()
 {
-    QDeclarativeComponent component(&engine, TEST_FILE("deletedObject.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("deletedObject.qml"));
 
     QObject *object = component.create();
 
@@ -2387,7 +2426,7 @@ void tst_qdeclarativeecmascript::deletedObject()
 
 void tst_qdeclarativeecmascript::attachedPropertyScope()
 {
-    QDeclarativeComponent component(&engine, TEST_FILE("attachedPropertyScope.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("attachedPropertyScope.qml"));
 
     QObject *object = component.create();
     QVERIFY(object != 0);
@@ -2408,7 +2447,7 @@ void tst_qdeclarativeecmascript::attachedPropertyScope()
 void tst_qdeclarativeecmascript::scriptConnect()
 {
     {
-        QDeclarativeComponent component(&engine, TEST_FILE("scriptConnect.1.qml"));
+        QDeclarativeComponent component(&engine, testFileUrl("scriptConnect.1.qml"));
 
         MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
         QVERIFY(object != 0);
@@ -2421,7 +2460,7 @@ void tst_qdeclarativeecmascript::scriptConnect()
     }
 
     {
-        QDeclarativeComponent component(&engine, TEST_FILE("scriptConnect.2.qml"));
+        QDeclarativeComponent component(&engine, testFileUrl("scriptConnect.2.qml"));
 
         MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
         QVERIFY(object != 0);
@@ -2434,7 +2473,7 @@ void tst_qdeclarativeecmascript::scriptConnect()
     }
 
     {
-        QDeclarativeComponent component(&engine, TEST_FILE("scriptConnect.3.qml"));
+        QDeclarativeComponent component(&engine, testFileUrl("scriptConnect.3.qml"));
 
         MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
         QVERIFY(object != 0);
@@ -2447,7 +2486,7 @@ void tst_qdeclarativeecmascript::scriptConnect()
     }
 
     {
-        QDeclarativeComponent component(&engine, TEST_FILE("scriptConnect.4.qml"));
+        QDeclarativeComponent component(&engine, testFileUrl("scriptConnect.4.qml"));
 
         MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
         QVERIFY(object != 0);
@@ -2460,7 +2499,7 @@ void tst_qdeclarativeecmascript::scriptConnect()
     }
 
     {
-        QDeclarativeComponent component(&engine, TEST_FILE("scriptConnect.5.qml"));
+        QDeclarativeComponent component(&engine, testFileUrl("scriptConnect.5.qml"));
 
         MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
         QVERIFY(object != 0);
@@ -2473,7 +2512,7 @@ void tst_qdeclarativeecmascript::scriptConnect()
     }
 
     {
-        QDeclarativeComponent component(&engine, TEST_FILE("scriptConnect.6.qml"));
+        QDeclarativeComponent component(&engine, testFileUrl("scriptConnect.6.qml"));
 
         MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
         QVERIFY(object != 0);
@@ -2489,7 +2528,7 @@ void tst_qdeclarativeecmascript::scriptConnect()
 void tst_qdeclarativeecmascript::scriptDisconnect()
 {
     {
-        QDeclarativeComponent component(&engine, TEST_FILE("scriptDisconnect.1.qml"));
+        QDeclarativeComponent component(&engine, testFileUrl("scriptDisconnect.1.qml"));
 
         MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
         QVERIFY(object != 0);
@@ -2508,7 +2547,7 @@ void tst_qdeclarativeecmascript::scriptDisconnect()
     }
 
     {
-        QDeclarativeComponent component(&engine, TEST_FILE("scriptDisconnect.2.qml"));
+        QDeclarativeComponent component(&engine, testFileUrl("scriptDisconnect.2.qml"));
 
         MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
         QVERIFY(object != 0);
@@ -2527,7 +2566,7 @@ void tst_qdeclarativeecmascript::scriptDisconnect()
     }
 
     {
-        QDeclarativeComponent component(&engine, TEST_FILE("scriptDisconnect.3.qml"));
+        QDeclarativeComponent component(&engine, testFileUrl("scriptDisconnect.3.qml"));
 
         MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
         QVERIFY(object != 0);
@@ -2545,7 +2584,7 @@ void tst_qdeclarativeecmascript::scriptDisconnect()
         delete object;
     }
     {
-        QDeclarativeComponent component(&engine, TEST_FILE("scriptDisconnect.4.qml"));
+        QDeclarativeComponent component(&engine, testFileUrl("scriptDisconnect.4.qml"));
 
         MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
         QVERIFY(object != 0);
@@ -2583,7 +2622,7 @@ void tst_qdeclarativeecmascript::ownership()
     context->setContextObject(&own);
 
     {
-        QDeclarativeComponent component(&engine, TEST_FILE("ownership.qml"));
+        QDeclarativeComponent component(&engine, testFileUrl("ownership.qml"));
 
         QVERIFY(own.object != 0);
 
@@ -2591,7 +2630,8 @@ void tst_qdeclarativeecmascript::ownership()
 
         engine.collectGarbage();
 
-        QCoreApplication::processEvents(QEventLoop::DeferredDeletion);
+        QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
+        QCoreApplication::processEvents();
 
         QVERIFY(own.object == 0);
 
@@ -2601,7 +2641,7 @@ void tst_qdeclarativeecmascript::ownership()
     own.object = new QObject(&own);
 
     {
-        QDeclarativeComponent component(&engine, TEST_FILE("ownership.qml"));
+        QDeclarativeComponent component(&engine, testFileUrl("ownership.qml"));
 
         QVERIFY(own.object != 0);
 
@@ -2609,7 +2649,8 @@ void tst_qdeclarativeecmascript::ownership()
         
         engine.collectGarbage();
 
-        QCoreApplication::processEvents(QEventLoop::DeferredDeletion);
+        QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
+        QCoreApplication::processEvents();
 
         QVERIFY(own.object != 0);
 
@@ -2664,7 +2705,8 @@ void tst_qdeclarativeecmascript::cppOwnershipReturnValue()
     delete object;
     }
 
-    QCoreApplication::instance()->processEvents(QEventLoop::DeferredDeletion);
+    QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
+    QCoreApplication::processEvents();
 
     QVERIFY(source.value != 0);
 }
@@ -2692,7 +2734,8 @@ void tst_qdeclarativeecmascript::ownershipCustomReturnValue()
     }
 
     engine.collectGarbage();
-    QCoreApplication::instance()->processEvents(QEventLoop::DeferredDeletion);
+    QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
+    QCoreApplication::processEvents();
 
     QVERIFY(source.value == 0);
 }
@@ -2724,7 +2767,7 @@ void tst_qdeclarativeecmascript::qlistqobjectMethods()
     QDeclarativeContext *context = new QDeclarativeContext(engine.rootContext());
     context->setContextObject(&obj);
 
-    QDeclarativeComponent component(&engine, TEST_FILE("qlistqobjectMethods.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("qlistqobjectMethods.qml"));
 
     QObject *object = component.create(context);
 
@@ -2738,7 +2781,7 @@ void tst_qdeclarativeecmascript::qlistqobjectMethods()
 // QTBUG-9205
 void tst_qdeclarativeecmascript::strictlyEquals()
 {
-    QDeclarativeComponent component(&engine, TEST_FILE("strictlyEquals.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("strictlyEquals.qml"));
 
     QObject *object = component.create();
     QVERIFY(object != 0);
@@ -2757,7 +2800,7 @@ void tst_qdeclarativeecmascript::strictlyEquals()
 
 void tst_qdeclarativeecmascript::compiled()
 {
-    QDeclarativeComponent component(&engine, TEST_FILE("compiled.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("compiled.qml"));
 
     QObject *object = component.create();
     QVERIFY(object != 0);
@@ -2797,7 +2840,7 @@ void tst_qdeclarativeecmascript::compiled()
 // Test that numbers assigned in bindings as strings work consistently
 void tst_qdeclarativeecmascript::numberAssignment()
 {
-    QDeclarativeComponent component(&engine, TEST_FILE("numberAssignment.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("numberAssignment.qml"));
 
     QObject *object = component.create();
     QVERIFY(object != 0);
@@ -2823,7 +2866,7 @@ void tst_qdeclarativeecmascript::numberAssignment()
 
 void tst_qdeclarativeecmascript::propertySplicing()
 {
-    QDeclarativeComponent component(&engine, TEST_FILE("propertySplicing.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("propertySplicing.qml"));
 
     QObject *object = component.create();
     QVERIFY(object != 0);
@@ -2836,7 +2879,7 @@ void tst_qdeclarativeecmascript::propertySplicing()
 // QTBUG-16683
 void tst_qdeclarativeecmascript::signalWithUnknownTypes()
 {
-    QDeclarativeComponent component(&engine, TEST_FILE("signalWithUnknownTypes.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("signalWithUnknownTypes.qml"));
 
     MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
     QVERIFY(object != 0);
@@ -2884,7 +2927,7 @@ void tst_qdeclarativeecmascript::signalWithJSValueInVariant()
     QFETCH(QString, expression);
     QFETCH(QString, compare);
 
-    QDeclarativeComponent component(&engine, TEST_FILE("signalWithJSValueInVariant.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("signalWithJSValueInVariant.qml"));
     QScopedPointer<MyQmlObject> object(qobject_cast<MyQmlObject *>(component.create()));
     QVERIFY(object != 0);
 
@@ -2908,7 +2951,7 @@ void tst_qdeclarativeecmascript::signalWithJSValueInVariant_twoEngines()
     QFETCH(QString, expression);
     QFETCH(QString, compare);
 
-    QDeclarativeComponent component(&engine, TEST_FILE("signalWithJSValueInVariant.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("signalWithJSValueInVariant.qml"));
     QScopedPointer<MyQmlObject> object(qobject_cast<MyQmlObject *>(component.create()));
     QVERIFY(object != 0);
 
@@ -2924,6 +2967,32 @@ void tst_qdeclarativeecmascript::signalWithJSValueInVariant_twoEngines()
     QVERIFY(!object->property("pass").toBool());
 }
 
+void tst_qdeclarativeecmascript::signalWithQJSValue_data()
+{
+    signalWithJSValueInVariant_data();
+}
+
+void tst_qdeclarativeecmascript::signalWithQJSValue()
+{
+    QFETCH(QString, expression);
+    QFETCH(QString, compare);
+
+    QDeclarativeComponent component(&engine, testFileUrl("signalWithQJSValue.qml"));
+    QScopedPointer<MyQmlObject> object(qobject_cast<MyQmlObject *>(component.create()));
+    QVERIFY(object != 0);
+
+    QJSValue value = engine.evaluate(expression);
+    QVERIFY(!engine.hasUncaughtException());
+    object->setProperty("expression", expression);
+    object->setProperty("compare", compare);
+    object->setProperty("pass", false);
+
+    emit object->signalWithQJSValue(value);
+
+    QVERIFY(object->property("pass").toBool());
+    QVERIFY(object->qjsvalue().strictlyEquals(value));
+}
+
 void tst_qdeclarativeecmascript::moduleApi_data()
 {
     QTest::addColumn<QUrl>("testfile");
@@ -2937,7 +3006,7 @@ void tst_qdeclarativeecmascript::moduleApi_data()
     QTest::addColumn<QVariantList>("readBackExpectedValues");
 
     QTest::newRow("qobject, register + read + method")
-            << TEST_FILE("moduleapi/qobjectModuleApi.qml")
+            << testFileUrl("moduleapi/qobjectModuleApi.qml")
             << QString()
             << QStringList()
             << (QStringList() << "existingUriTest" << "qobjectTest" << "qobjectMethodTest"
@@ -2949,7 +3018,7 @@ void tst_qdeclarativeecmascript::moduleApi_data()
             << QVariantList();
 
     QTest::newRow("script, register + read")
-            << TEST_FILE("moduleapi/scriptModuleApi.qml")
+            << testFileUrl("moduleapi/scriptModuleApi.qml")
             << QString()
             << QStringList()
             << (QStringList() << "scriptTest")
@@ -2960,7 +3029,7 @@ void tst_qdeclarativeecmascript::moduleApi_data()
             << QVariantList();
 
     QTest::newRow("qobject, caching + read")
-            << TEST_FILE("moduleapi/qobjectModuleApiCaching.qml")
+            << testFileUrl("moduleapi/qobjectModuleApiCaching.qml")
             << QString()
             << QStringList()
             << (QStringList() << "existingUriTest" << "qobjectParentedTest")
@@ -2971,7 +3040,7 @@ void tst_qdeclarativeecmascript::moduleApi_data()
             << QVariantList();
 
     QTest::newRow("script, caching + read")
-            << TEST_FILE("moduleapi/scriptModuleApiCaching.qml")
+            << testFileUrl("moduleapi/scriptModuleApiCaching.qml")
             << QString()
             << QStringList()
             << (QStringList() << "scriptTest")
@@ -2982,9 +3051,9 @@ void tst_qdeclarativeecmascript::moduleApi_data()
             << QVariantList();
 
     QTest::newRow("qobject, writing + readonly constraints")
-            << TEST_FILE("moduleapi/qobjectModuleApiWriting.qml")
+            << testFileUrl("moduleapi/qobjectModuleApiWriting.qml")
             << QString()
-            << (QStringList() << QString(QLatin1String("file://") + TEST_FILE("moduleapi/qobjectModuleApiWriting.qml").toLocalFile() + QLatin1String(":14: Error: Cannot assign to read-only property \"qobjectTestProperty\"")))
+            << (QStringList() << QString(QLatin1String("file://") + testFileUrl("moduleapi/qobjectModuleApiWriting.qml").toLocalFile() + QLatin1String(":14: Error: Cannot assign to read-only property \"qobjectTestProperty\"")))
             << (QStringList() << "readOnlyProperty" << "writableProperty")
             << (QVariantList() << 20 << 50)
             << (QStringList() << "firstProperty" << "writableProperty")
@@ -2993,9 +3062,9 @@ void tst_qdeclarativeecmascript::moduleApi_data()
             << (QVariantList() << 20 << 30);
 
     QTest::newRow("script, writing + readonly constraints")
-            << TEST_FILE("moduleapi/scriptModuleApiWriting.qml")
+            << testFileUrl("moduleapi/scriptModuleApiWriting.qml")
             << QString()
-            << (QStringList() << QString(QLatin1String("file://") + TEST_FILE("moduleapi/scriptModuleApiWriting.qml").toLocalFile() + QLatin1String(":21: Error: Cannot assign to read-only property \"scriptTestProperty\"")))
+            << (QStringList() << QString(QLatin1String("file://") + testFileUrl("moduleapi/scriptModuleApiWriting.qml").toLocalFile() + QLatin1String(":21: Error: Cannot assign to read-only property \"scriptTestProperty\"")))
             << (QStringList() << "readBack" << "unchanged")
             << (QVariantList() << 13 << 42)
             << (QStringList() << "firstProperty" << "secondProperty")
@@ -3004,7 +3073,7 @@ void tst_qdeclarativeecmascript::moduleApi_data()
             << (QVariantList() << 30 << 42);
 
     QTest::newRow("qobject module API enum values in JS")
-            << TEST_FILE("moduleapi/qobjectModuleApiEnums.qml")
+            << testFileUrl("moduleapi/qobjectModuleApiEnums.qml")
             << QString()
             << QStringList()
             << (QStringList() << "enumValue" << "enumMethod")
@@ -3015,7 +3084,7 @@ void tst_qdeclarativeecmascript::moduleApi_data()
             << QVariantList();
 
     QTest::newRow("qobject, invalid major version fail")
-            << TEST_FILE("moduleapi/moduleApiMajorVersionFail.qml")
+            << testFileUrl("moduleapi/moduleApiMajorVersionFail.qml")
             << QString("QDeclarativeComponent: Component is not ready")
             << QStringList()
             << QStringList()
@@ -3026,7 +3095,7 @@ void tst_qdeclarativeecmascript::moduleApi_data()
             << QVariantList();
 
     QTest::newRow("qobject, invalid minor version fail")
-            << TEST_FILE("moduleapi/moduleApiMinorVersionFail.qml")
+            << testFileUrl("moduleapi/moduleApiMinorVersionFail.qml")
             << QString("QDeclarativeComponent: Component is not ready")
             << QStringList()
             << QStringList()
@@ -3082,7 +3151,7 @@ void tst_qdeclarativeecmascript::importScripts_data()
     QTest::addColumn<QVariantList>("propertyValues");
 
     QTest::newRow("basic functionality")
-            << TEST_FILE("jsimport/testImport.qml")
+            << testFileUrl("jsimport/testImport.qml")
             << QString()
             << QStringList()
             << (QStringList() << QLatin1String("importedScriptStringValue")
@@ -3095,71 +3164,71 @@ void tst_qdeclarativeecmascript::importScripts_data()
                                << QVariant(2));
 
     QTest::newRow("import scoping")
-            << TEST_FILE("jsimport/testImportScoping.qml")
+            << testFileUrl("jsimport/testImportScoping.qml")
             << QString()
             << QStringList()
             << (QStringList() << QLatin1String("componentError"))
             << (QVariantList() << QVariant(5));
 
     QTest::newRow("parent scope shouldn't be inherited by import with imports")
-            << TEST_FILE("jsimportfail/failOne.qml")
+            << testFileUrl("jsimportfail/failOne.qml")
             << QString()
-            << (QStringList() << QString(QLatin1String("file://") + TEST_FILE("jsimportfail/failOne.qml").toLocalFile() + QLatin1String(":6: TypeError: Cannot call method 'greetingString' of undefined")))
+            << (QStringList() << QString(QLatin1String("file://") + testFileUrl("jsimportfail/failOne.qml").toLocalFile() + QLatin1String(":6: TypeError: Cannot call method 'greetingString' of undefined")))
             << (QStringList() << QLatin1String("importScriptFunctionValue"))
             << (QVariantList() << QVariant(QString()));
 
     QTest::newRow("javascript imports in an import should be private to the import scope")
-            << TEST_FILE("jsimportfail/failTwo.qml")
+            << testFileUrl("jsimportfail/failTwo.qml")
             << QString()
-            << (QStringList() << QString(QLatin1String("file://") + TEST_FILE("jsimportfail/failTwo.qml").toLocalFile() + QLatin1String(":6: ReferenceError: Can't find variable: ImportOneJs")))
+            << (QStringList() << QString(QLatin1String("file://") + testFileUrl("jsimportfail/failTwo.qml").toLocalFile() + QLatin1String(":6: ReferenceError: Can't find variable: ImportOneJs")))
             << (QStringList() << QLatin1String("importScriptFunctionValue"))
             << (QVariantList() << QVariant(QString()));
 
     QTest::newRow("module imports in an import should be private to the import scope")
-            << TEST_FILE("jsimportfail/failThree.qml")
+            << testFileUrl("jsimportfail/failThree.qml")
             << QString()
-            << (QStringList() << QString(QLatin1String("file://") + TEST_FILE("jsimportfail/failThree.qml").toLocalFile() + QLatin1String(":7: TypeError: Cannot read property 'JsQtTest' of undefined")))
+            << (QStringList() << QString(QLatin1String("file://") + testFileUrl("jsimportfail/failThree.qml").toLocalFile() + QLatin1String(":7: TypeError: Cannot read property 'JsQtTest' of undefined")))
             << (QStringList() << QLatin1String("importedModuleAttachedPropertyValue"))
             << (QVariantList() << QVariant(false));
 
     QTest::newRow("typenames in an import should be private to the import scope")
-            << TEST_FILE("jsimportfail/failFour.qml")
+            << testFileUrl("jsimportfail/failFour.qml")
             << QString()
-            << (QStringList() << QString(QLatin1String("file://") + TEST_FILE("jsimportfail/failFour.qml").toLocalFile() + QLatin1String(":6: ReferenceError: Can't find variable: JsQtTest")))
+            << (QStringList() << QString(QLatin1String("file://") + testFileUrl("jsimportfail/failFour.qml").toLocalFile() + QLatin1String(":6: ReferenceError: Can't find variable: JsQtTest")))
             << (QStringList() << QLatin1String("importedModuleEnumValue"))
             << (QVariantList() << QVariant(0));
 
     QTest::newRow("import with imports has it's own activation scope")
-            << TEST_FILE("jsimportfail/failFive.qml")
+            << testFileUrl("jsimportfail/failFive.qml")
             << QString()
-            << (QStringList() << QString(QLatin1String("file://") + TEST_FILE("jsimportfail/importWithImports.js").toLocalFile() + QLatin1String(":8: ReferenceError: Can't find variable: Component"))
-                              << QString(QLatin1String("file://") + TEST_FILE("jsimportfail/importPragmaLibrary.js").toLocalFile() + QLatin1String(":6: ReferenceError: Can't find variable: Component")))
+            << (QStringList() << QString(QLatin1String("file://") + testFileUrl("jsimportfail/importWithImports.js").toLocalFile() + QLatin1String(":8: ReferenceError: Can't find variable: Component"))
+                              << QString(QLatin1String("file://") + testFileUrl("jsimportfail/importPragmaLibrary.js").toLocalFile() + QLatin1String(":6: ReferenceError: Can't find variable: Component")))
             << (QStringList() << QLatin1String("componentError"))
             << (QVariantList() << QVariant(0));
 
     QTest::newRow("import pragma library script")
-            << TEST_FILE("jsimport/testImportPragmaLibrary.qml")
+            << testFileUrl("jsimport/testImportPragmaLibrary.qml")
             << QString()
             << QStringList()
             << (QStringList() << QLatin1String("testValue"))
             << (QVariantList() << QVariant(31));
 
     QTest::newRow("pragma library imports shouldn't inherit parent imports or scope")
-            << TEST_FILE("jsimportfail/testImportPragmaLibrary.qml")
+            << testFileUrl("jsimportfail/testImportPragmaLibrary.qml")
             << QString()
             << QStringList()
             << (QStringList() << QLatin1String("testValue"))
             << (QVariantList() << QVariant(0));
 
     QTest::newRow("import pragma library script which has an import")
-            << TEST_FILE("jsimport/testImportPragmaLibraryWithImports.qml")
+            << testFileUrl("jsimport/testImportPragmaLibraryWithImports.qml")
             << QString()
             << QStringList()
             << (QStringList() << QLatin1String("testValue"))
             << (QVariantList() << QVariant(55));
 
     QTest::newRow("import pragma library script which has a pragma library import")
-            << TEST_FILE("jsimport/testImportPragmaLibraryWithPragmaLibraryImports.qml")
+            << testFileUrl("jsimport/testImportPragmaLibraryWithPragmaLibraryImports.qml")
             << QString()
             << QStringList()
             << (QStringList() << QLatin1String("testValue"))
@@ -3194,110 +3263,98 @@ void tst_qdeclarativeecmascript::importScripts()
     }
 }
 
-void tst_qdeclarativeecmascript::scarceResources()
+void tst_qdeclarativeecmascript::scarceResources_other()
 {
+    /* These tests require knowledge of state, since we test values after
+       performing signal or function invocation. */
+
     QPixmap origPixmap(100, 100);
     origPixmap.fill(Qt::blue);
-
+    QString srp_name, expectedWarning;
     QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(&engine);
     ScarceResourceObject *eo = 0;
+    QObject *srsc = 0;
     QObject *object = 0;
 
-    // in the following three cases, the instance created from the component
-    // has a property which is a copy of the scarce resource; hence, the
-    // resource should NOT be detached prior to deletion of the object instance,
-    // unless the resource is destroyed explicitly.
-    QDeclarativeComponent component(&engine, TEST_FILE("scarceresources/scarceResourceCopy.qml"));
-    object = component.create();
-    QVERIFY(object != 0);
-    QVERIFY(object->property("scarceResourceCopy").isValid());
-    QCOMPARE(object->property("scarceResourceCopy").value<QPixmap>(), origPixmap);
-    QVERIFY(ep->scarceResources.isEmpty()); // should have been released by this point.
+    /* property var semantics */
+
+    // test that scarce resources are handled properly in signal invocation
+    QDeclarativeComponent varComponentTen(&engine, testFileUrl("scarceResourceSignal.var.qml"));
+    object = varComponentTen.create();
+    srsc = object->findChild<QObject*>("srsc");
+    QVERIFY(srsc);
+    QVERIFY(!srsc->property("scarceResourceCopy").isValid()); // hasn't been instantiated yet.
+    QCOMPARE(srsc->property("width"), QVariant(5)); // default value is 5.
+    eo = qobject_cast<ScarceResourceObject*>(QDeclarativeProperty::read(object, "a").value<QObject*>());
+    QVERIFY(eo->scarceResourceIsDetached()); // should be no other copies of it at this stage.
+    QMetaObject::invokeMethod(srsc, "testSignal");
+    QVERIFY(!srsc->property("scarceResourceCopy").isValid()); // still hasn't been instantiated
+    QCOMPARE(srsc->property("width"), QVariant(10)); // but width was assigned to 10.
     eo = qobject_cast<ScarceResourceObject*>(QDeclarativeProperty::read(object, "a").value<QObject*>());
-    QVERIFY(!eo->scarceResourceIsDetached()); // there are two copies of it in existence: the property of object, and the property of eo.
+    QVERIFY(eo->scarceResourceIsDetached()); // should still be no other copies of it at this stage.
+    QMetaObject::invokeMethod(srsc, "testSignal2"); // assigns scarceResourceCopy to the scarce pixmap.
+    QVERIFY(srsc->property("scarceResourceCopy").isValid());
+    QCOMPARE(srsc->property("scarceResourceCopy").value<QPixmap>(), origPixmap);
+    eo = qobject_cast<ScarceResourceObject*>(QDeclarativeProperty::read(object, "a").value<QObject*>());
+    QVERIFY(!(eo->scarceResourceIsDetached())); // should be another copy of the resource now.
+    QVERIFY(ep->scarceResources.isEmpty()); // should have been released by this point.
     delete object;
 
-    QDeclarativeComponent componentTwo(&engine, TEST_FILE("scarceresources/scarceResourceCopyFromJs.qml"));
-    object = componentTwo.create();
+    // test that scarce resources are handled properly from js functions in qml files
+    QDeclarativeComponent varComponentEleven(&engine, testFileUrl("scarceResourceFunction.var.qml"));
+    object = varComponentEleven.create();
     QVERIFY(object != 0);
-    QVERIFY(object->property("scarceResourceCopy").isValid());
+    QVERIFY(!object->property("scarceResourceCopy").isValid()); // not yet assigned, so should not be valid
+    eo = qobject_cast<ScarceResourceObject*>(QDeclarativeProperty::read(object, "a").value<QObject*>());
+    QVERIFY(eo->scarceResourceIsDetached()); // should be no other copies of it at this stage.
+    QMetaObject::invokeMethod(object, "retrieveScarceResource");
+    QVERIFY(object->property("scarceResourceCopy").isValid()); // assigned, so should be valid.
     QCOMPARE(object->property("scarceResourceCopy").value<QPixmap>(), origPixmap);
-    QVERIFY(ep->scarceResources.isEmpty()); // should have been released by this point.
     eo = qobject_cast<ScarceResourceObject*>(QDeclarativeProperty::read(object, "a").value<QObject*>());
-    QVERIFY(!eo->scarceResourceIsDetached()); // there are two copies of it in existence: the property of object, and the property of eo.
-    delete object;
-
-    QDeclarativeComponent componentThree(&engine, TEST_FILE("scarceresources/scarceResourceDestroyedCopy.qml"));
-    object = componentThree.create();
-    QVERIFY(object != 0);
-    QVERIFY(!(object->property("scarceResourceCopy").isValid())); // was manually released prior to being returned.
-    QVERIFY(ep->scarceResources.isEmpty()); // should have been released by this point.
+    QVERIFY(!eo->scarceResourceIsDetached()); // should be a copy of the resource at this stage.
+    QMetaObject::invokeMethod(object, "releaseScarceResource");
+    QVERIFY(!object->property("scarceResourceCopy").isValid()); // just released, so should not be valid
     eo = qobject_cast<ScarceResourceObject*>(QDeclarativeProperty::read(object, "a").value<QObject*>());
-    QVERIFY(eo->scarceResourceIsDetached()); // should have explicitly been released during the evaluation of the binding.
-    delete object;
-
-    // in the following three cases, no other copy should exist in memory,
-    // and so it should be detached (unless explicitly preserved).
-    QDeclarativeComponent componentFour(&engine, TEST_FILE("scarceresources/scarceResourceTest.qml"));
-    object = componentFour.create();
-    QVERIFY(object != 0);
-    QVERIFY(object->property("scarceResourceTest").isValid());
-    QCOMPARE(object->property("scarceResourceTest").toInt(), 100);
+    QVERIFY(eo->scarceResourceIsDetached()); // should be no other copies of it at this stage.
     QVERIFY(ep->scarceResources.isEmpty()); // should have been released by this point.
-    eo = qobject_cast<ScarceResourceObject*>(QDeclarativeProperty::read(object, "a").value<QObject*>());
-    QVERIFY(eo->scarceResourceIsDetached()); // the resource should have been released after the binding was evaluated.
     delete object;
 
-    QDeclarativeComponent componentFive(&engine, TEST_FILE("scarceresources/scarceResourceTestPreserve.qml"));
-    object = componentFive.create();
+    // test that if an exception occurs while invoking js function from cpp, that the resources are released.
+    QDeclarativeComponent varComponentTwelve(&engine, testFileUrl("scarceResourceFunctionFail.var.qml"));
+    object = varComponentTwelve.create();
     QVERIFY(object != 0);
-    QVERIFY(object->property("scarceResourceTest").isValid());
-    QCOMPARE(object->property("scarceResourceTest").toInt(), 100);
-    QVERIFY(ep->scarceResources.isEmpty()); // should have been released by this point.
+    QVERIFY(!object->property("scarceResourceCopy").isValid()); // not yet assigned, so should not be valid
     eo = qobject_cast<ScarceResourceObject*>(QDeclarativeProperty::read(object, "a").value<QObject*>());
-    QVERIFY(!eo->scarceResourceIsDetached()); // this won't be detached since we explicitly preserved it.
-    delete object;
-
-    QDeclarativeComponent componentSix(&engine, TEST_FILE("scarceresources/scarceResourceTestMultiple.qml"));
-    object = componentSix.create();
-    QVERIFY(object != 0);
-    QVERIFY(object->property("scarceResourceTest").isValid());
-    QCOMPARE(object->property("scarceResourceTest").toInt(), 100);
-    QVERIFY(ep->scarceResources.isEmpty()); // should have been released by this point.
+    QVERIFY(eo->scarceResourceIsDetached()); // should be no other copies of it at this stage.
+    srp_name = object->property("srp_name").toString();
+    expectedWarning = varComponentTwelve.url().toString() + QLatin1String(":16: TypeError: Property 'scarceResource' of object ") + srp_name + QLatin1String(" is not a function");
+    QTest::ignoreMessage(QtWarningMsg, qPrintable(expectedWarning)); // we expect a meaningful warning to be printed.
+    QMetaObject::invokeMethod(object, "retrieveScarceResource");
+    QVERIFY(!object->property("scarceResourceCopy").isValid()); // due to exception, assignment will NOT have occurred.
     eo = qobject_cast<ScarceResourceObject*>(QDeclarativeProperty::read(object, "a").value<QObject*>());
-    QVERIFY(eo->scarceResourceIsDetached()); // all resources were released manually or automatically released.
-    delete object;
-
-    // test that scarce resources are handled correctly for imports
-    QDeclarativeComponent componentSeven(&engine, TEST_FILE("scarceresources/scarceResourceCopyImportNoBinding.qml"));
-    object = componentSeven.create();
-    QVERIFY(object != 0); // the import should have caused the addition of a resource to the ScarceResources list
-    QVERIFY(ep->scarceResources.isEmpty()); // but they should have been released by this point.
-    delete object;
-
-    QDeclarativeComponent componentEight(&engine, TEST_FILE("scarceresources/scarceResourceCopyImportFail.qml"));
-    object = componentEight.create();
-    QVERIFY(object != 0);
-    QVERIFY(!object->property("scarceResourceCopy").isValid()); // wasn't preserved, so shouldn't be valid.
+    QVERIFY(eo->scarceResourceIsDetached()); // should be no other copies of it at this stage.
     QVERIFY(ep->scarceResources.isEmpty()); // should have been released by this point.
     delete object;
 
-    QDeclarativeComponent componentNine(&engine, TEST_FILE("scarceresources/scarceResourceCopyImport.qml"));
-    object = componentNine.create();
+    // test that if an Item which has JS ownership but has a scarce resource property is garbage collected,
+    // that the scarce resource is removed from the engine's list of scarce resources to clean up.
+    QDeclarativeComponent varComponentThirteen(&engine, testFileUrl("scarceResourceObjectGc.var.qml"));
+    object = varComponentThirteen.create();
     QVERIFY(object != 0);
-    QVERIFY(object->property("scarceResourceCopy").isValid()); // preserved, so should be valid.
-    QCOMPARE(object->property("scarceResourceCopy").value<QPixmap>(), origPixmap);
-    QVERIFY(object->property("scarceResourceAssignedCopyOne").isValid()); // assigned before destroy(), so should be valid.
-    QCOMPARE(object->property("scarceResourceAssignedCopyOne").value<QPixmap>(), origPixmap);
-    QVERIFY(!object->property("scarceResourceAssignedCopyTwo").isValid()); // assigned after destroy(), so should be invalid.
-    QVERIFY(ep->scarceResources.isEmpty()); // this will still be zero, because "preserve()" REMOVES it from this list.
+    QVERIFY(!object->property("varProperty").isValid()); // not assigned yet
+    QMetaObject::invokeMethod(object, "assignVarProperty");
+    QVERIFY(ep->scarceResources.isEmpty());             // the scarce resource is a VME property.
+    QMetaObject::invokeMethod(object, "deassignVarProperty");
+    QVERIFY(ep->scarceResources.isEmpty());             // should still be empty; the resource should have been released on gc.
     delete object;
 
+    /* property variant semantics */
+
     // test that scarce resources are handled properly in signal invocation
-    QDeclarativeComponent componentTen(&engine, TEST_FILE("scarceresources/scarceResourceSignal.qml"));
-    object = componentTen.create();
+    QDeclarativeComponent variantComponentTen(&engine, testFileUrl("scarceResourceSignal.variant.qml"));
+    object = variantComponentTen.create();
     QVERIFY(object != 0);
-    QObject *srsc = object->findChild<QObject*>("srsc");
+    srsc = object->findChild<QObject*>("srsc");
     QVERIFY(srsc);
     QVERIFY(!srsc->property("scarceResourceCopy").isValid()); // hasn't been instantiated yet.
     QCOMPARE(srsc->property("width"), QVariant(5)); // default value is 5.
@@ -3317,8 +3374,8 @@ void tst_qdeclarativeecmascript::scarceResources()
     delete object;
 
     // test that scarce resources are handled properly from js functions in qml files
-    QDeclarativeComponent componentEleven(&engine, TEST_FILE("scarceresources/scarceResourceFunction.qml"));
-    object = componentEleven.create();
+    QDeclarativeComponent variantComponentEleven(&engine, testFileUrl("scarceResourceFunction.variant.qml"));
+    object = variantComponentEleven.create();
     QVERIFY(object != 0);
     QVERIFY(!object->property("scarceResourceCopy").isValid()); // not yet assigned, so should not be valid
     eo = qobject_cast<ScarceResourceObject*>(QDeclarativeProperty::read(object, "a").value<QObject*>());
@@ -3336,14 +3393,14 @@ void tst_qdeclarativeecmascript::scarceResources()
     delete object;
 
     // test that if an exception occurs while invoking js function from cpp, that the resources are released.
-    QDeclarativeComponent componentTwelve(&engine, TEST_FILE("scarceresources/scarceResourceFunctionFail.qml"));
-    object = componentTwelve.create();
+    QDeclarativeComponent variantComponentTwelve(&engine, testFileUrl("scarceResourceFunctionFail.variant.qml"));
+    object = variantComponentTwelve.create();
     QVERIFY(object != 0);
     QVERIFY(!object->property("scarceResourceCopy").isValid()); // not yet assigned, so should not be valid
     eo = qobject_cast<ScarceResourceObject*>(QDeclarativeProperty::read(object, "a").value<QObject*>());
     QVERIFY(eo->scarceResourceIsDetached()); // should be no other copies of it at this stage.
-    QString srp_name = object->property("srp_name").toString();
-    QString expectedWarning = componentTwelve.url().toString() + QLatin1String(":17: TypeError: Property 'scarceResource' of object ") + srp_name + QLatin1String(" is not a function");
+    srp_name = object->property("srp_name").toString();
+    expectedWarning = variantComponentTwelve.url().toString() + QLatin1String(":16: TypeError: Property 'scarceResource' of object ") + srp_name + QLatin1String(" is not a function");
     QTest::ignoreMessage(QtWarningMsg, qPrintable(expectedWarning)); // we expect a meaningful warning to be printed.
     QMetaObject::invokeMethod(object, "retrieveScarceResource");
     QVERIFY(!object->property("scarceResourceCopy").isValid()); // due to exception, assignment will NOT have occurred.
@@ -3353,17 +3410,277 @@ void tst_qdeclarativeecmascript::scarceResources()
     delete object;
 }
 
+void tst_qdeclarativeecmascript::scarceResources_data()
+{
+    QTest::addColumn<QUrl>("qmlFile");
+    QTest::addColumn<bool>("readDetachStatus");
+    QTest::addColumn<bool>("expectedDetachStatus");
+    QTest::addColumn<QStringList>("propertyNames");
+    QTest::addColumn<QVariantList>("expectedValidity");
+    QTest::addColumn<QVariantList>("expectedValues");
+    QTest::addColumn<QStringList>("expectedErrors");
+
+    QPixmap origPixmap(100, 100);
+    origPixmap.fill(Qt::blue);
+
+    /* property var semantics */
+
+    // in the following three cases, the instance created from the component
+    // has a property which is a copy of the scarce resource; hence, the
+    // resource should NOT be detached prior to deletion of the object instance,
+    // unless the resource is destroyed explicitly.
+    QTest::newRow("var: import scarce resource copy directly")
+        << testFileUrl("scarceResourceCopy.var.qml")
+        << true
+        << false // won't be detached, because assigned to property and not explicitly released
+        << (QStringList() << QLatin1String("scarceResourceCopy"))
+        << (QList<QVariant>() << true)
+        << (QList<QVariant>() << origPixmap)
+        << QStringList();
+
+    QTest::newRow("var: import scarce resource copy from JS")
+        << testFileUrl("scarceResourceCopyFromJs.var.qml")
+        << true
+        << false // won't be detached, because assigned to property and not explicitly released
+        << (QStringList() << QLatin1String("scarceResourceCopy"))
+        << (QList<QVariant>() << true)
+        << (QList<QVariant>() << origPixmap)
+        << QStringList();
+
+    QTest::newRow("var: import released scarce resource copy from JS")
+        << testFileUrl("scarceResourceDestroyedCopy.var.qml")
+        << true
+        << true // explicitly released, so it will be detached
+        << (QStringList() << QLatin1String("scarceResourceCopy"))
+        << (QList<QVariant>() << false)
+        << (QList<QVariant>() << QVariant())
+        << QStringList();
+
+    // in the following three cases, no other copy should exist in memory,
+    // and so it should be detached (unless explicitly preserved).
+    QTest::newRow("var: import auto-release SR from JS in binding side-effect")
+        << testFileUrl("scarceResourceTest.var.qml")
+        << true
+        << true // auto released, so it will be detached
+        << (QStringList() << QLatin1String("scarceResourceTest"))
+        << (QList<QVariant>() << true)
+        << (QList<QVariant>() << QVariant(100))
+        << QStringList();
+    QTest::newRow("var: import explicit-preserve SR from JS in binding side-effect")
+        << testFileUrl("scarceResourceTestPreserve.var.qml")
+        << true
+        << false // won't be detached because we explicitly preserve it
+        << (QStringList() << QLatin1String("scarceResourceTest"))
+        << (QList<QVariant>() << true)
+        << (QList<QVariant>() << QVariant(100))
+        << QStringList();
+    QTest::newRow("var: import explicit-preserve SR from JS in binding side-effect")
+        << testFileUrl("scarceResourceTestMultiple.var.qml")
+        << true
+        << true // will be detached because all resources were released manually or automatically.
+        << (QStringList() << QLatin1String("scarceResourceTest"))
+        << (QList<QVariant>() << true)
+        << (QList<QVariant>() << QVariant(100))
+        << QStringList();
+
+    // In the following three cases, test that scarce resources are handled
+    // correctly for imports.
+    QTest::newRow("var: import with no binding")
+        << testFileUrl("scarceResourceCopyImportNoBinding.var.qml")
+        << false // cannot check detach status.
+        << false
+        << QStringList()
+        << QList<QVariant>()
+        << QList<QVariant>()
+        << QStringList();
+    QTest::newRow("var: import with binding without explicit preserve")
+        << testFileUrl("scarceResourceCopyImportNoBinding.var.qml")
+        << false
+        << false
+        << (QStringList() << QLatin1String("scarceResourceCopy"))
+        << (QList<QVariant>() << false) // will have been released prior to evaluation of binding.
+        << (QList<QVariant>() << QVariant())
+        << QStringList();
+    QTest::newRow("var: import with explicit release after binding evaluation")
+        << testFileUrl("scarceResourceCopyImport.var.qml")
+        << false
+        << false
+        << (QStringList() << QLatin1String("scarceResourceImportedCopy") << QLatin1String("scarceResourceAssignedCopyOne") << QLatin1String("scarceResourceAssignedCopyTwo") << QLatin1String("arePropertiesEqual"))
+        << (QList<QVariant>() << false << false << false << true) // since property var = JS object reference, by releasing the provider's resource, all handles are invalidated.
+        << (QList<QVariant>() << QVariant() << QVariant() << QVariant() << QVariant(true))
+        << QStringList();
+    QTest::newRow("var: import with different js objects")
+        << testFileUrl("scarceResourceCopyImportDifferent.var.qml")
+        << false
+        << false
+        << (QStringList() << QLatin1String("scarceResourceAssignedCopyOne") << QLatin1String("scarceResourceAssignedCopyTwo") << QLatin1String("arePropertiesEqual"))
+        << (QList<QVariant>() << false << true << true) // invalidating one shouldn't invalidate the other, because they're not references to the same JS object.
+        << (QList<QVariant>() << QVariant() << QVariant(origPixmap) << QVariant(false))
+        << QStringList();
+    QTest::newRow("var: import with different js objects and explicit release")
+        << testFileUrl("scarceResourceMultipleDifferentNoBinding.var.qml")
+        << false
+        << false
+        << (QStringList() << QLatin1String("resourceOne") << QLatin1String("resourceTwo"))
+        << (QList<QVariant>() << true << false) // invalidating one shouldn't invalidate the other, because they're not references to the same JS object.
+        << (QList<QVariant>() << QVariant(origPixmap) << QVariant())
+        << QStringList();
+    QTest::newRow("var: import with same js objects and explicit release")
+        << testFileUrl("scarceResourceMultipleSameNoBinding.var.qml")
+        << false
+        << false
+        << (QStringList() << QLatin1String("resourceOne") << QLatin1String("resourceTwo"))
+        << (QList<QVariant>() << false << false) // invalidating one should invalidate the other, because they're references to the same JS object.
+        << (QList<QVariant>() << QVariant() << QVariant())
+        << QStringList();
+    QTest::newRow("var: binding with same js objects and explicit release")
+        << testFileUrl("scarceResourceMultipleSameWithBinding.var.qml")
+        << false
+        << false
+        << (QStringList() << QLatin1String("resourceOne") << QLatin1String("resourceTwo"))
+        << (QList<QVariant>() << false << false) // invalidating one should invalidate the other, because they're references to the same JS object.
+        << (QList<QVariant>() << QVariant() << QVariant())
+        << QStringList();
+
+
+    /* property variant semantics */
+
+    // in the following three cases, the instance created from the component
+    // has a property which is a copy of the scarce resource; hence, the
+    // resource should NOT be detached prior to deletion of the object instance,
+    // unless the resource is destroyed explicitly.
+    QTest::newRow("variant: import scarce resource copy directly")
+        << testFileUrl("scarceResourceCopy.variant.qml")
+        << true
+        << false // won't be detached, because assigned to property and not explicitly released
+        << (QStringList() << QLatin1String("scarceResourceCopy"))
+        << (QList<QVariant>() << true)
+        << (QList<QVariant>() << origPixmap)
+        << QStringList();
+
+    QTest::newRow("variant: import scarce resource copy from JS")
+        << testFileUrl("scarceResourceCopyFromJs.variant.qml")
+        << true
+        << false // won't be detached, because assigned to property and not explicitly released
+        << (QStringList() << QLatin1String("scarceResourceCopy"))
+        << (QList<QVariant>() << true)
+        << (QList<QVariant>() << origPixmap)
+        << QStringList();
+
+    QTest::newRow("variant: import released scarce resource copy from JS")
+        << testFileUrl("scarceResourceDestroyedCopy.variant.qml")
+        << true
+        << true // explicitly released, so it will be detached
+        << (QStringList() << QLatin1String("scarceResourceCopy"))
+        << (QList<QVariant>() << false)
+        << (QList<QVariant>() << QVariant())
+        << QStringList();
+
+    // in the following three cases, no other copy should exist in memory,
+    // and so it should be detached (unless explicitly preserved).
+    QTest::newRow("variant: import auto-release SR from JS in binding side-effect")
+        << testFileUrl("scarceResourceTest.variant.qml")
+        << true
+        << true // auto released, so it will be detached
+        << (QStringList() << QLatin1String("scarceResourceTest"))
+        << (QList<QVariant>() << true)
+        << (QList<QVariant>() << QVariant(100))
+        << QStringList();
+    QTest::newRow("variant: import explicit-preserve SR from JS in binding side-effect")
+        << testFileUrl("scarceResourceTestPreserve.variant.qml")
+        << true
+        << false // won't be detached because we explicitly preserve it
+        << (QStringList() << QLatin1String("scarceResourceTest"))
+        << (QList<QVariant>() << true)
+        << (QList<QVariant>() << QVariant(100))
+        << QStringList();
+    QTest::newRow("variant: import multiple scarce resources")
+        << testFileUrl("scarceResourceTestMultiple.variant.qml")
+        << true
+        << true // will be detached because all resources were released manually or automatically.
+        << (QStringList() << QLatin1String("scarceResourceTest"))
+        << (QList<QVariant>() << true)
+        << (QList<QVariant>() << QVariant(100))
+        << QStringList();
+
+    // In the following three cases, test that scarce resources are handled
+    // correctly for imports.
+    QTest::newRow("variant: import with no binding")
+        << testFileUrl("scarceResourceCopyImportNoBinding.variant.qml")
+        << false // cannot check detach status.
+        << false
+        << QStringList()
+        << QList<QVariant>()
+        << QList<QVariant>()
+        << QStringList();
+    QTest::newRow("variant: import with binding without explicit preserve")
+        << testFileUrl("scarceResourceCopyImportNoBinding.variant.qml")
+        << false
+        << false
+        << (QStringList() << QLatin1String("scarceResourceCopy"))
+        << (QList<QVariant>() << false) // will have been released prior to evaluation of binding.
+        << (QList<QVariant>() << QVariant())
+        << QStringList();
+    QTest::newRow("variant: import with explicit release after binding evaluation")
+        << testFileUrl("scarceResourceCopyImport.variant.qml")
+        << false
+        << false
+        << (QStringList() << QLatin1String("scarceResourceImportedCopy") << QLatin1String("scarceResourceAssignedCopyOne") << QLatin1String("scarceResourceAssignedCopyTwo"))
+        << (QList<QVariant>() << true << true << false) // since property variant = variant copy, releasing the provider's resource does not invalidate previously assigned copies.
+        << (QList<QVariant>() << origPixmap << origPixmap << QVariant())
+        << QStringList();
+}
+
+void tst_qdeclarativeecmascript::scarceResources()
+{
+    QFETCH(QUrl, qmlFile);
+    QFETCH(bool, readDetachStatus);
+    QFETCH(bool, expectedDetachStatus);
+    QFETCH(QStringList, propertyNames);
+    QFETCH(QVariantList, expectedValidity);
+    QFETCH(QVariantList, expectedValues);
+    QFETCH(QStringList, expectedErrors);
+
+    QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(&engine);
+    ScarceResourceObject *eo = 0;
+    QObject *object = 0;
+
+    QDeclarativeComponent c(&engine, qmlFile);
+    object = c.create();
+    QVERIFY(object != 0);
+    for (int i = 0; i < propertyNames.size(); ++i) {
+        QString prop = propertyNames.at(i);
+        bool validity = expectedValidity.at(i).toBool();
+        QVariant value = expectedValues.at(i);
+
+        QCOMPARE(object->property(prop.toLatin1().constData()).isValid(), validity);
+        if (value.type() == QVariant::Int) {
+            QCOMPARE(object->property(prop.toLatin1().constData()).toInt(), value.toInt());
+        } else if (value.type() == QVariant::Pixmap) {
+            QCOMPARE(object->property(prop.toLatin1().constData()).value<QPixmap>(), value.value<QPixmap>());
+        }
+    }
+
+    if (readDetachStatus) {
+        eo = qobject_cast<ScarceResourceObject*>(QDeclarativeProperty::read(object, "a").value<QObject*>());
+        QCOMPARE(eo->scarceResourceIsDetached(), expectedDetachStatus);
+    }
+
+    QVERIFY(ep->scarceResources.isEmpty());
+    delete object;
+}
+
 void tst_qdeclarativeecmascript::propertyChangeSlots()
 {
     // ensure that allowable property names are allowed and onPropertyNameChanged slots are generated correctly.
-    QDeclarativeComponent component(&engine, TEST_FILE("changeslots/propertyChangeSlots.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("changeslots/propertyChangeSlots.qml"));
     QObject *object = component.create();
     QVERIFY(object != 0);
     delete object;
 
     // ensure that invalid property names fail properly.
     QTest::ignoreMessage(QtWarningMsg, "QDeclarativeComponent: Component is not ready");
-    QDeclarativeComponent e1(&engine, TEST_FILE("changeslots/propertyChangeSlotErrors.1.qml"));
+    QDeclarativeComponent e1(&engine, testFileUrl("changeslots/propertyChangeSlotErrors.1.qml"));
     QString expectedErrorString = e1.url().toString() + QLatin1String(":9:5: Cannot assign to non-existent property \"on_nameWithUnderscoreChanged\"");
     QCOMPARE(e1.errors().at(0).toString(), expectedErrorString);
     object = e1.create();
@@ -3371,7 +3688,7 @@ void tst_qdeclarativeecmascript::propertyChangeSlots()
     delete object;
 
     QTest::ignoreMessage(QtWarningMsg, "QDeclarativeComponent: Component is not ready");
-    QDeclarativeComponent e2(&engine, TEST_FILE("changeslots/propertyChangeSlotErrors.2.qml"));
+    QDeclarativeComponent e2(&engine, testFileUrl("changeslots/propertyChangeSlotErrors.2.qml"));
     expectedErrorString = e2.url().toString() + QLatin1String(":9:5: Cannot assign to non-existent property \"on____nameWithUnderscoresChanged\"");
     QCOMPARE(e2.errors().at(0).toString(), expectedErrorString);
     object = e2.create();
@@ -3379,7 +3696,7 @@ void tst_qdeclarativeecmascript::propertyChangeSlots()
     delete object;
 
     QTest::ignoreMessage(QtWarningMsg, "QDeclarativeComponent: Component is not ready");
-    QDeclarativeComponent e3(&engine, TEST_FILE("changeslots/propertyChangeSlotErrors.3.qml"));
+    QDeclarativeComponent e3(&engine, testFileUrl("changeslots/propertyChangeSlotErrors.3.qml"));
     expectedErrorString = e3.url().toString() + QLatin1String(":9:5: Cannot assign to non-existent property \"on$NameWithDollarsignChanged\"");
     QCOMPARE(e3.errors().at(0).toString(), expectedErrorString);
     object = e3.create();
@@ -3387,7 +3704,7 @@ void tst_qdeclarativeecmascript::propertyChangeSlots()
     delete object;
 
     QTest::ignoreMessage(QtWarningMsg, "QDeclarativeComponent: Component is not ready");
-    QDeclarativeComponent e4(&engine, TEST_FILE("changeslots/propertyChangeSlotErrors.4.qml"));
+    QDeclarativeComponent e4(&engine, testFileUrl("changeslots/propertyChangeSlotErrors.4.qml"));
     expectedErrorString = e4.url().toString() + QLatin1String(":9:5: Cannot assign to non-existent property \"on_6NameWithUnderscoreNumberChanged\"");
     QCOMPARE(e4.errors().at(0).toString(), expectedErrorString);
     object = e4.create();
@@ -3400,15 +3717,16 @@ void tst_qdeclarativeecmascript::propertyVar_data()
     QTest::addColumn<QUrl>("qmlFile");
 
     // valid
-    QTest::newRow("non-bindable object subproperty changed") << TEST_FILE("propertyVar.1.qml");
-    QTest::newRow("non-bindable object changed") << TEST_FILE("propertyVar.2.qml");
-    QTest::newRow("primitive changed") << TEST_FILE("propertyVar.3.qml");
-    QTest::newRow("javascript array modification") << TEST_FILE("propertyVar.4.qml");
-    QTest::newRow("javascript map modification") << TEST_FILE("propertyVar.5.qml");
-    QTest::newRow("javascript array assignment") << TEST_FILE("propertyVar.6.qml");
-    QTest::newRow("javascript map assignment") << TEST_FILE("propertyVar.7.qml");
-    QTest::newRow("literal property assignment") << TEST_FILE("propertyVar.8.qml");
-    QTest::newRow("qobject property assignment") << TEST_FILE("propertyVar.9.qml");
+    QTest::newRow("non-bindable object subproperty changed") << testFileUrl("propertyVar.1.qml");
+    QTest::newRow("non-bindable object changed") << testFileUrl("propertyVar.2.qml");
+    QTest::newRow("primitive changed") << testFileUrl("propertyVar.3.qml");
+    QTest::newRow("javascript array modification") << testFileUrl("propertyVar.4.qml");
+    QTest::newRow("javascript map modification") << testFileUrl("propertyVar.5.qml");
+    QTest::newRow("javascript array assignment") << testFileUrl("propertyVar.6.qml");
+    QTest::newRow("javascript map assignment") << testFileUrl("propertyVar.7.qml");
+    QTest::newRow("literal property assignment") << testFileUrl("propertyVar.8.qml");
+    QTest::newRow("qobject property assignment") << testFileUrl("propertyVar.9.qml");
+    QTest::newRow("base class var property assignment") << testFileUrl("propertyVar.10.qml");
 }
 
 void tst_qdeclarativeecmascript::propertyVar()
@@ -3432,7 +3750,7 @@ void tst_qdeclarativeecmascript::propertyVarCpp()
     // ensure that writing to and reading from a var property from cpp works as required.
     // Literal values stored in var properties can be read and written as QVariants
     // of a specific type, whereas object values are read as QVariantMaps.
-    QDeclarativeComponent component(&engine, TEST_FILE("propertyVarCpp.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("propertyVarCpp.qml"));
     object = component.create();
     QVERIFY(object != 0);
     // assign int to property var that currently has int assigned
@@ -3454,14 +3772,15 @@ void tst_qdeclarativeecmascript::propertyVarCpp()
 static void gc(QDeclarativeEngine &engine)
 {
     engine.collectGarbage();
-    QCoreApplication::processEvents(QEventLoop::DeferredDeletion);
+    QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
+    QCoreApplication::processEvents();
 }
 
 void tst_qdeclarativeecmascript::propertyVarOwnership()
 {
     // Referenced JS objects are not collected
     {
-    QDeclarativeComponent component(&engine, TEST_FILE("propertyVarOwnership.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("propertyVarOwnership.qml"));
     QObject *object = component.create();
     QVERIFY(object != 0);
     QCOMPARE(object->property("test").toBool(), false);
@@ -3471,7 +3790,7 @@ void tst_qdeclarativeecmascript::propertyVarOwnership()
     }
     // Referenced JS objects are not collected
     {
-    QDeclarativeComponent component(&engine, TEST_FILE("propertyVarOwnership.2.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("propertyVarOwnership.2.qml"));
     QObject *object = component.create();
     QVERIFY(object != 0);
     QCOMPARE(object->property("test").toBool(), false);
@@ -3481,7 +3800,7 @@ void tst_qdeclarativeecmascript::propertyVarOwnership()
     }
     // Qt objects are not collected until they've been dereferenced
     {
-    QDeclarativeComponent component(&engine, TEST_FILE("propertyVarOwnership.3.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("propertyVarOwnership.3.qml"));
     QObject *object = component.create();
     QVERIFY(object != 0);
 
@@ -3505,7 +3824,7 @@ void tst_qdeclarativeecmascript::propertyVarOwnership()
     }
     // Self reference does not prevent Qt object collection
     {
-    QDeclarativeComponent component(&engine, TEST_FILE("propertyVarOwnership.4.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("propertyVarOwnership.4.qml"));
     QObject *object = component.create();
     QVERIFY(object != 0);
 
@@ -3529,11 +3848,12 @@ void tst_qdeclarativeecmascript::propertyVarImplicitOwnership()
     // The childObject has a reference to a different QObject.  We want to ensure
     // that the different item will not be cleaned up until required.  IE, the childObject
     // has implicit ownership of the constructed QObject.
-    QDeclarativeComponent component(&engine, TEST_FILE("propertyVarImplicitOwnership.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("propertyVarImplicitOwnership.qml"));
     QObject *object = component.create();
     QVERIFY(object != 0);
     QMetaObject::invokeMethod(object, "assignCircular");
-    QCoreApplication::processEvents(QEventLoop::DeferredDeletion); // process deleteLater() events from QV8QObjectWrapper.
+    QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); // process deleteLater() events from QV8QObjectWrapper.
+    QCoreApplication::processEvents();
     QObject *rootObject = object->property("vp").value<QObject*>();
     QVERIFY(rootObject != 0);
     QObject *childObject = rootObject->findChild<QObject*>("text");
@@ -3543,10 +3863,12 @@ void tst_qdeclarativeecmascript::propertyVarImplicitOwnership()
     QMetaObject::invokeMethod(childObject, "constructQObject");    // creates a reference to a constructed QObject.
     QWeakPointer<QObject> qobjectGuard(childObject->property("vp").value<QObject*>()); // get the pointer prior to processing deleteLater events.
     QVERIFY(!qobjectGuard.isNull());
-    QCoreApplication::processEvents(QEventLoop::DeferredDeletion); // process deleteLater() events from QV8QObjectWrapper.
+    QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); // process deleteLater() events from QV8QObjectWrapper.
+    QCoreApplication::processEvents();
     QVERIFY(!qobjectGuard.isNull());
     QMetaObject::invokeMethod(object, "deassignCircular");
-    QCoreApplication::processEvents(QEventLoop::DeferredDeletion); // process deleteLater() events from QV8QObjectWrapper.
+    QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); // process deleteLater() events from QV8QObjectWrapper.
+    QCoreApplication::processEvents();
     QVERIFY(qobjectGuard.isNull());                                // should have been collected now.
     delete object;
 }
@@ -3554,11 +3876,12 @@ void tst_qdeclarativeecmascript::propertyVarImplicitOwnership()
 void tst_qdeclarativeecmascript::propertyVarReparent()
 {
     // ensure that nothing breaks if we re-parent objects
-    QDeclarativeComponent component(&engine, TEST_FILE("propertyVar.reparent.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("propertyVar.reparent.qml"));
     QObject *object = component.create();
     QVERIFY(object != 0);
     QMetaObject::invokeMethod(object, "assignVarProp");
-    QCoreApplication::processEvents(QEventLoop::DeferredDeletion); // process deleteLater() events from QV8QObjectWrapper.
+    QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); // process deleteLater() events from QV8QObjectWrapper.
+    QCoreApplication::processEvents();
     QObject *rect = object->property("vp").value<QObject*>();
     QObject *text = rect->findChild<QObject*>("textOne");
     QObject *text2 = rect->findChild<QObject*>("textTwo");
@@ -3579,13 +3902,15 @@ void tst_qdeclarativeecmascript::propertyVarReparent()
     // now reparent the "Image" object (currently, it has JS ownership)
     image->setParent(text);                                        // shouldn't be collected after deassignVp now, since has a parent.
     QMetaObject::invokeMethod(text2, "deassignVp");
-    QCoreApplication::processEvents(QEventLoop::DeferredDeletion); // process deleteLater() events from QV8QObjectWrapper.
+    QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); // process deleteLater() events from QV8QObjectWrapper.
+    QCoreApplication::processEvents();
     QCOMPARE(text->property("textCanary").toInt(), 11);
     QCOMPARE(text2->property("textCanary").toInt(), 22);
     QVERIFY(!imageGuard.isNull());                                 // should still be alive.
     QCOMPARE(image->property("imageCanary").toInt(), 13);          // still able to access var properties
     QMetaObject::invokeMethod(object, "deassignVarProp");          // now deassign the root-object's vp, causing gc of rect+text+text2
-    QCoreApplication::processEvents(QEventLoop::DeferredDeletion); // process deleteLater() events from QV8QObjectWrapper.
+    QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); // process deleteLater() events from QV8QObjectWrapper.
+    QCoreApplication::processEvents();
     QVERIFY(imageGuard.isNull());                                  // should now have been deleted, due to parent being deleted.
     delete object;
 }
@@ -3595,11 +3920,12 @@ void tst_qdeclarativeecmascript::propertyVarReparentNullContext()
     // sometimes reparenting can cause problems
     // (eg, if the ctxt is collected, varproperties are no longer available)
     // this test ensures that no crash occurs in that situation.
-    QDeclarativeComponent component(&engine, TEST_FILE("propertyVar.reparent.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("propertyVar.reparent.qml"));
     QObject *object = component.create();
     QVERIFY(object != 0);
     QMetaObject::invokeMethod(object, "assignVarProp");
-    QCoreApplication::processEvents(QEventLoop::DeferredDeletion); // process deleteLater() events from QV8QObjectWrapper.
+    QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); // process deleteLater() events from QV8QObjectWrapper.
+    QCoreApplication::processEvents();
     QObject *rect = object->property("vp").value<QObject*>();
     QObject *text = rect->findChild<QObject*>("textOne");
     QObject *text2 = rect->findChild<QObject*>("textTwo");
@@ -3620,7 +3946,8 @@ void tst_qdeclarativeecmascript::propertyVarReparentNullContext()
     // now reparent the "Image" object (currently, it has JS ownership)
     image->setParent(object);                                      // reparented to base object.  after deassignVarProp, the ctxt will be invalid.
     QMetaObject::invokeMethod(object, "deassignVarProp");          // now deassign the root-object's vp, causing gc of rect+text+text2
-    QCoreApplication::processEvents(QEventLoop::DeferredDeletion); // process deleteLater() events from QV8QObjectWrapper.
+    QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); // process deleteLater() events from QV8QObjectWrapper.
+    QCoreApplication::processEvents();
     QVERIFY(!imageGuard.isNull());                                 // should still be alive.
     QVERIFY(!image->property("imageCanary").isValid());            // but varProperties won't be available (null context).
     delete object;
@@ -3630,21 +3957,24 @@ void tst_qdeclarativeecmascript::propertyVarReparentNullContext()
 void tst_qdeclarativeecmascript::propertyVarCircular()
 {
     // enforce behaviour regarding circular references - ensure qdvmemo deletion.
-    QDeclarativeComponent component(&engine, TEST_FILE("propertyVar.circular.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("propertyVar.circular.qml"));
     QObject *object = component.create();
     QVERIFY(object != 0);
     QMetaObject::invokeMethod(object, "assignCircular");           // cause assignment and gc
-    QCoreApplication::processEvents(QEventLoop::DeferredDeletion); // process deleteLater() events from QV8QObjectWrapper.
+    QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); // process deleteLater() events from QV8QObjectWrapper.
+    QCoreApplication::processEvents();
     QCOMPARE(object->property("canaryInt"), QVariant(5));
     QVariant canaryResourceVariant = object->property("canaryResource");
     QVERIFY(canaryResourceVariant.isValid());
     QPixmap canaryResourcePixmap = canaryResourceVariant.value<QPixmap>();
     canaryResourceVariant = QVariant();                            // invalidate it to remove one copy of the pixmap from memory.
     QMetaObject::invokeMethod(object, "deassignCanaryResource");   // remove one copy of the pixmap from memory
-    QCoreApplication::processEvents(QEventLoop::DeferredDeletion); // process deleteLater() events from QV8QObjectWrapper.
+    QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); // process deleteLater() events from QV8QObjectWrapper.
+    QCoreApplication::processEvents();
     QVERIFY(!canaryResourcePixmap.isDetached());                   // two copies extant - this and the propertyVar.vp.vp.vp.vp.memoryHog.
     QMetaObject::invokeMethod(object, "deassignCircular");         // cause deassignment and gc
-    QCoreApplication::processEvents(QEventLoop::DeferredDeletion); // process deleteLater() events from QV8QObjectWrapper.
+    QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); // process deleteLater() events from QV8QObjectWrapper.
+    QCoreApplication::processEvents();
     QCOMPARE(object->property("canaryInt"), QVariant(2));
     QCOMPARE(object->property("canaryResource"), QVariant(1));
     QVERIFY(canaryResourcePixmap.isDetached());                    // now detached, since orig copy was member of qdvmemo which was deleted.
@@ -3655,11 +3985,12 @@ void tst_qdeclarativeecmascript::propertyVarCircular2()
 {
     // track deletion of JS-owned parent item with Cpp-owned child
     // where the child has a var property referencing its parent.
-    QDeclarativeComponent component(&engine, TEST_FILE("propertyVar.circular.2.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("propertyVar.circular.2.qml"));
     QObject *object = component.create();
     QVERIFY(object != 0);
     QMetaObject::invokeMethod(object, "assignCircular");
-    QCoreApplication::processEvents(QEventLoop::DeferredDeletion); // process deleteLater() events from QV8QObjectWrapper.
+    QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); // process deleteLater() events from QV8QObjectWrapper.
+    QCoreApplication::processEvents();
     QObject *rootObject = object->property("vp").value<QObject*>();
     QVERIFY(rootObject != 0);
     QObject *childObject = rootObject->findChild<QObject*>("text");
@@ -3672,7 +4003,8 @@ void tst_qdeclarativeecmascript::propertyVarCircular2()
     QCOMPARE(rootObject->property("rectCanary").toInt(), 5);
     QCOMPARE(childObject->property("textCanary").toInt(), 10);
     QMetaObject::invokeMethod(object, "deassignCircular");
-    QCoreApplication::processEvents(QEventLoop::DeferredDeletion); // process deleteLater() events from QV8QObjectWrapper.
+    QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); // process deleteLater() events from QV8QObjectWrapper.
+    QCoreApplication::processEvents();
     QVERIFY(rootObjectTracker.isNull());                           // should have been collected
     QVERIFY(childObjectTracker.isNull());                          // should have been collected
     delete object;
@@ -3690,11 +4022,12 @@ void tst_qdeclarativeecmascript::propertyVarInheritance()
 
     // enforce behaviour regarding element inheritance - ensure handle disposal.
     // The particular component under test here has a chain of references.
-    QDeclarativeComponent component(&engine, TEST_FILE("propertyVar.inherit.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("propertyVar.inherit.qml"));
     QObject *object = component.create();
     QVERIFY(object != 0);
     QMetaObject::invokeMethod(object, "assignCircular");           // cause assignment and gc
-    QCoreApplication::processEvents(QEventLoop::DeferredDeletion); // process deleteLater() events from QV8QObjectWrapper.
+    QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); // process deleteLater() events from QV8QObjectWrapper.
+    QCoreApplication::processEvents();
     // we want to be able to track when the varProperties array of the last metaobject is disposed
     QObject *cco5 = object->property("varProperty").value<QObject*>()->property("vp").value<QObject*>()->property("vp").value<QObject*>()->property("vp").value<QObject*>()->property("vp").value<QObject*>();
     QObject *ico5 = object->property("varProperty").value<QObject*>()->property("inheritanceVarProperty").value<QObject*>()->property("vp").value<QObject*>()->property("vp").value<QObject*>()->property("vp").value<QObject*>()->property("vp").value<QObject*>();
@@ -3706,8 +4039,8 @@ void tst_qdeclarativeecmascript::propertyVarInheritance()
         v8::HandleScope hs;
         // XXX NOTE: this is very implementation dependent.  QDVMEMO->vmeProperty() is the only
         // public function which can return us a handle to something in the varProperties array.
-        icoCanaryHandle = qPersistentNew(icovmemo->vmeProperty(41));
-        ccoCanaryHandle = qPersistentNew(ccovmemo->vmeProperty(41));
+        icoCanaryHandle = qPersistentNew(icovmemo->vmeProperty(ico5->metaObject()->indexOfProperty("circ")));
+        ccoCanaryHandle = qPersistentNew(ccovmemo->vmeProperty(cco5->metaObject()->indexOfProperty("circ")));
         // we make them weak and invoke the gc, but we should not hit the weak-callback yet
         // as the varproperties array of each vmemo still references the resource.
         icoCanaryHandle.MakeWeak(&propertyVarWeakRefCallbackCount, propertyVarWeakRefCallback);
@@ -3717,7 +4050,8 @@ void tst_qdeclarativeecmascript::propertyVarInheritance()
     }
     // now we deassign the var prop, which should trigger collection of item subtrees.
     QMetaObject::invokeMethod(object, "deassignCircular");         // cause deassignment and gc
-    QCoreApplication::processEvents(QEventLoop::DeferredDeletion); // process deleteLater() events from QV8QObjectWrapper.
+    QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); // process deleteLater() events from QV8QObjectWrapper.
+    QCoreApplication::processEvents();
     // ensure that there are only weak handles to the underlying varProperties array remaining.
     gc(engine);
     QCOMPARE(propertyVarWeakRefCallbackCount, 2);                  // should have been called for both, since all refs should be weak.
@@ -3732,11 +4066,12 @@ void tst_qdeclarativeecmascript::propertyVarInheritance2()
 
     // The particular component under test here does NOT have a chain of references; the
     // only link between rootObject and childObject is that rootObject is the parent of childObject.
-    QDeclarativeComponent component(&engine, TEST_FILE("propertyVar.circular.2.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("propertyVar.circular.2.qml"));
     QObject *object = component.create();
     QVERIFY(object != 0);
     QMetaObject::invokeMethod(object, "assignCircular");
-    QCoreApplication::processEvents(QEventLoop::DeferredDeletion); // process deleteLater() events from QV8QObjectWrapper.
+    QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); // process deleteLater() events from QV8QObjectWrapper.
+    QCoreApplication::processEvents();
     QObject *rootObject = object->property("vp").value<QObject*>();
     QVERIFY(rootObject != 0);
     QObject *childObject = rootObject->findChild<QObject*>("text");
@@ -3747,14 +4082,16 @@ void tst_qdeclarativeecmascript::propertyVarInheritance2()
     {
         v8::HandleScope hs;
         propertyVarWeakRefCallbackCount = 0;                           // reset callback count.
-        childObjectVarArrayValueHandle = qPersistentNew(((QDeclarativeVMEMetaObject *)(childObject->metaObject()))->vmeProperty(58));
+        childObjectVarArrayValueHandle = qPersistentNew(((QDeclarativeVMEMetaObject *)(childObject->metaObject()))->vmeProperty(childObject->metaObject()->indexOfProperty("vp")));
         childObjectVarArrayValueHandle.MakeWeak(&propertyVarWeakRefCallbackCount, propertyVarWeakRefCallback);
         gc(engine);
         QVERIFY(propertyVarWeakRefCallbackCount == 0);                 // should not have been collected yet.
+        QCOMPARE(childObject->property("vp").value<QObject*>(), rootObject);
         QCOMPARE(childObject->property("textCanary").toInt(), 10);
     }
     QMetaObject::invokeMethod(object, "deassignCircular");
-    QCoreApplication::processEvents(QEventLoop::DeferredDeletion); // process deleteLater() events from QV8QObjectWrapper.
+    QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); // process deleteLater() events from QV8QObjectWrapper.
+    QCoreApplication::processEvents();
     QVERIFY(propertyVarWeakRefCallbackCount == 1);                 // should have been collected now.
     delete object;
 }
@@ -3762,7 +4099,7 @@ void tst_qdeclarativeecmascript::propertyVarInheritance2()
 // Ensure that QObject type conversion works on binding assignment
 void tst_qdeclarativeecmascript::elementAssign()
 {
-    QDeclarativeComponent component(&engine, TEST_FILE("elementAssign.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("elementAssign.qml"));
 
     QObject *object = component.create();
     QVERIFY(object != 0);
@@ -3775,7 +4112,7 @@ void tst_qdeclarativeecmascript::elementAssign()
 // QTBUG-12457
 void tst_qdeclarativeecmascript::objectPassThroughSignals()
 {
-    QDeclarativeComponent component(&engine, TEST_FILE("objectsPassThroughSignals.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("objectsPassThroughSignals.qml"));
 
     QObject *object = component.create();
     QVERIFY(object != 0);
@@ -3788,7 +4125,7 @@ void tst_qdeclarativeecmascript::objectPassThroughSignals()
 // QTBUG-21626
 void tst_qdeclarativeecmascript::objectConversion()
 {
-    QDeclarativeComponent component(&engine, TEST_FILE("objectConversion.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("objectConversion.qml"));
 
     QObject *object = component.create();
     QVERIFY(object != 0);
@@ -3803,7 +4140,7 @@ void tst_qdeclarativeecmascript::objectConversion()
 // QTBUG-20242
 void tst_qdeclarativeecmascript::booleanConversion()
 {
-    QDeclarativeComponent component(&engine, TEST_FILE("booleanConversion.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("booleanConversion.qml"));
 
     QObject *object = component.create();
     QVERIFY(object != 0);
@@ -3828,17 +4165,19 @@ void tst_qdeclarativeecmascript::handleReferenceManagement()
     {
         // Linear QObject reference
         QDeclarativeEngine hrmEngine;
-        QDeclarativeComponent component(&hrmEngine, TEST_FILE("handleReferenceManagement.object.1.qml"));
+        QDeclarativeComponent component(&hrmEngine, testFileUrl("handleReferenceManagement.object.1.qml"));
         QObject *object = component.create();
         QVERIFY(object != 0);
         CircularReferenceObject *cro = object->findChild<CircularReferenceObject*>("cro");
+        cro->setEngine(&hrmEngine);
         cro->setDtorCount(&dtorCount);
         QMetaObject::invokeMethod(object, "createReference");
         gc(engine);
         QCOMPARE(dtorCount, 0); // second has JS ownership, kept alive by first's reference
         delete object;
         hrmEngine.collectGarbage();
-        QCoreApplication::processEvents(QEventLoop::DeferredDeletion);
+        QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
+        QCoreApplication::processEvents();
         QCOMPARE(dtorCount, 3);
     }
 
@@ -3846,17 +4185,19 @@ void tst_qdeclarativeecmascript::handleReferenceManagement()
     {
         // Circular QObject reference
         QDeclarativeEngine hrmEngine;
-        QDeclarativeComponent component(&hrmEngine, TEST_FILE("handleReferenceManagement.object.2.qml"));
+        QDeclarativeComponent component(&hrmEngine, testFileUrl("handleReferenceManagement.object.2.qml"));
         QObject *object = component.create();
         QVERIFY(object != 0);
         CircularReferenceObject *cro = object->findChild<CircularReferenceObject*>("cro");
+        cro->setEngine(&hrmEngine);
         cro->setDtorCount(&dtorCount);
         QMetaObject::invokeMethod(object, "circularReference");
         gc(engine);
         QCOMPARE(dtorCount, 2); // both should be cleaned up, since circular references shouldn't keep alive.
         delete object;
         hrmEngine.collectGarbage();
-        QCoreApplication::processEvents(QEventLoop::DeferredDeletion);
+        QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
+        QCoreApplication::processEvents();
         QCOMPARE(dtorCount, 3);
     }
 
@@ -3864,11 +4205,12 @@ void tst_qdeclarativeecmascript::handleReferenceManagement()
     {
         // Linear handle reference
         QDeclarativeEngine hrmEngine;
-        QDeclarativeComponent component(&hrmEngine, TEST_FILE("handleReferenceManagement.handle.1.qml"));
+        QDeclarativeComponent component(&hrmEngine, testFileUrl("handleReferenceManagement.handle.1.qml"));
         QObject *object = component.create();
         QVERIFY(object != 0);
         CircularReferenceHandle *crh = object->findChild<CircularReferenceHandle*>("crh");
         QVERIFY(crh != 0);
+        crh->setEngine(&hrmEngine);
         crh->setDtorCount(&dtorCount);
         QMetaObject::invokeMethod(object, "createReference");
         CircularReferenceHandle *first = object->property("first").value<CircularReferenceHandle*>();
@@ -3883,7 +4225,8 @@ void tst_qdeclarativeecmascript::handleReferenceManagement()
         QCOMPARE(dtorCount, 0); // due to reference from first to second, second shouldn't be collected.
         delete object;
         hrmEngine.collectGarbage();
-        QCoreApplication::processEvents(QEventLoop::DeferredDeletion);
+        QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
+        QCoreApplication::processEvents();
         QCOMPARE(dtorCount, 3);
     }
 
@@ -3891,11 +4234,12 @@ void tst_qdeclarativeecmascript::handleReferenceManagement()
     {
         // Circular handle reference
         QDeclarativeEngine hrmEngine;
-        QDeclarativeComponent component(&hrmEngine, TEST_FILE("handleReferenceManagement.handle.2.qml"));
+        QDeclarativeComponent component(&hrmEngine, testFileUrl("handleReferenceManagement.handle.2.qml"));
         QObject *object = component.create();
         QVERIFY(object != 0);
         CircularReferenceHandle *crh = object->findChild<CircularReferenceHandle*>("crh");
         QVERIFY(crh != 0);
+        crh->setEngine(&hrmEngine);
         crh->setDtorCount(&dtorCount);
         QMetaObject::invokeMethod(object, "circularReference");
         CircularReferenceHandle *first = object->property("first").value<CircularReferenceHandle*>();
@@ -3913,7 +4257,8 @@ void tst_qdeclarativeecmascript::handleReferenceManagement()
         QCOMPARE(dtorCount, 2); // despite circular references, both will be collected.
         delete object;
         hrmEngine.collectGarbage();
-        QCoreApplication::processEvents(QEventLoop::DeferredDeletion);
+        QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
+        QCoreApplication::processEvents();
         QCOMPARE(dtorCount, 3);
     }
 
@@ -3922,8 +4267,8 @@ void tst_qdeclarativeecmascript::handleReferenceManagement()
         // multiple engine interaction - linear reference
         QDeclarativeEngine hrmEngine1;
         QDeclarativeEngine hrmEngine2;
-        QDeclarativeComponent component1(&hrmEngine1, TEST_FILE("handleReferenceManagement.handle.1.qml"));
-        QDeclarativeComponent component2(&hrmEngine2, TEST_FILE("handleReferenceManagement.handle.1.qml"));
+        QDeclarativeComponent component1(&hrmEngine1, testFileUrl("handleReferenceManagement.handle.1.qml"));
+        QDeclarativeComponent component2(&hrmEngine2, testFileUrl("handleReferenceManagement.handle.1.qml"));
         QObject *object1 = component1.create();
         QObject *object2 = component2.create();
         QVERIFY(object1 != 0);
@@ -3932,6 +4277,8 @@ void tst_qdeclarativeecmascript::handleReferenceManagement()
         CircularReferenceHandle *crh2 = object2->findChild<CircularReferenceHandle*>("crh");
         QVERIFY(crh1 != 0);
         QVERIFY(crh2 != 0);
+        crh1->setEngine(&hrmEngine1);
+        crh2->setEngine(&hrmEngine2);
         crh1->setDtorCount(&dtorCount);
         crh2->setDtorCount(&dtorCount);
         QMetaObject::invokeMethod(object1, "createReference");
@@ -3949,13 +4296,15 @@ void tst_qdeclarativeecmascript::handleReferenceManagement()
         second2->setParent(0);
         QDeclarativeEngine::setObjectOwnership(second2, QDeclarativeEngine::JavaScriptOwnership);
         gc(engine);
-        QCoreApplication::processEvents(QEventLoop::DeferredDeletion);
+        QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
+        QCoreApplication::processEvents();
         QCOMPARE(dtorCount, 0); // due to reference from first1 to second2, second2 shouldn't be collected.
         delete object1;
         delete object2;
         hrmEngine1.collectGarbage();
         hrmEngine2.collectGarbage();
-        QCoreApplication::processEvents(QEventLoop::DeferredDeletion);
+        QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
+        QCoreApplication::processEvents();
         QCOMPARE(dtorCount, 6);
     }
 
@@ -3964,8 +4313,8 @@ void tst_qdeclarativeecmascript::handleReferenceManagement()
         // multiple engine interaction - circular reference
         QDeclarativeEngine hrmEngine1;
         QDeclarativeEngine hrmEngine2;
-        QDeclarativeComponent component1(&hrmEngine1, TEST_FILE("handleReferenceManagement.handle.1.qml"));
-        QDeclarativeComponent component2(&hrmEngine2, TEST_FILE("handleReferenceManagement.handle.1.qml"));
+        QDeclarativeComponent component1(&hrmEngine1, testFileUrl("handleReferenceManagement.handle.1.qml"));
+        QDeclarativeComponent component2(&hrmEngine2, testFileUrl("handleReferenceManagement.handle.1.qml"));
         QObject *object1 = component1.create();
         QObject *object2 = component2.create();
         QVERIFY(object1 != 0);
@@ -3974,6 +4323,8 @@ void tst_qdeclarativeecmascript::handleReferenceManagement()
         CircularReferenceHandle *crh2 = object2->findChild<CircularReferenceHandle*>("crh");
         QVERIFY(crh1 != 0);
         QVERIFY(crh2 != 0);
+        crh1->setEngine(&hrmEngine1);
+        crh2->setEngine(&hrmEngine2);
         crh1->setDtorCount(&dtorCount);
         crh2->setDtorCount(&dtorCount);
         QMetaObject::invokeMethod(object1, "createReference");
@@ -4000,13 +4351,15 @@ void tst_qdeclarativeecmascript::handleReferenceManagement()
         QDeclarativeEngine::setObjectOwnership(first2, QDeclarativeEngine::JavaScriptOwnership);
         QDeclarativeEngine::setObjectOwnership(second2, QDeclarativeEngine::JavaScriptOwnership);
         gc(engine);
-        QCoreApplication::processEvents(QEventLoop::DeferredDeletion);
+        QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
+        QCoreApplication::processEvents();
         QCOMPARE(dtorCount, 4); // circular references shouldn't keep them alive.
         delete object1;
         delete object2;
         hrmEngine1.collectGarbage();
         hrmEngine2.collectGarbage();
-        QCoreApplication::processEvents(QEventLoop::DeferredDeletion);
+        QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
+        QCoreApplication::processEvents();
         QCOMPARE(dtorCount, 6);
     }
 
@@ -4015,8 +4368,8 @@ void tst_qdeclarativeecmascript::handleReferenceManagement()
         // multiple engine interaction - linear reference with engine deletion
         QDeclarativeEngine *hrmEngine1 = new QDeclarativeEngine;
         QDeclarativeEngine *hrmEngine2 = new QDeclarativeEngine;
-        QDeclarativeComponent component1(hrmEngine1, TEST_FILE("handleReferenceManagement.handle.1.qml"));
-        QDeclarativeComponent component2(hrmEngine2, TEST_FILE("handleReferenceManagement.handle.1.qml"));
+        QDeclarativeComponent component1(hrmEngine1, testFileUrl("handleReferenceManagement.handle.1.qml"));
+        QDeclarativeComponent component2(hrmEngine2, testFileUrl("handleReferenceManagement.handle.1.qml"));
         QObject *object1 = component1.create();
         QObject *object2 = component2.create();
         QVERIFY(object1 != 0);
@@ -4025,6 +4378,8 @@ void tst_qdeclarativeecmascript::handleReferenceManagement()
         CircularReferenceHandle *crh2 = object2->findChild<CircularReferenceHandle*>("crh");
         QVERIFY(crh1 != 0);
         QVERIFY(crh2 != 0);
+        crh1->setEngine(hrmEngine1);
+        crh2->setEngine(hrmEngine2);
         crh1->setDtorCount(&dtorCount);
         crh2->setDtorCount(&dtorCount);
         QMetaObject::invokeMethod(object1, "createReference");
@@ -4056,7 +4411,8 @@ void tst_qdeclarativeecmascript::handleReferenceManagement()
         delete object1;
         delete object2;
         hrmEngine1->collectGarbage();
-        QCoreApplication::processEvents(QEventLoop::DeferredDeletion);
+        QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
+        QCoreApplication::processEvents();
         QCOMPARE(dtorCount, 6);
         delete hrmEngine1;
     }
@@ -4064,13 +4420,13 @@ void tst_qdeclarativeecmascript::handleReferenceManagement()
 
 void tst_qdeclarativeecmascript::stringArg()
 {
-    QDeclarativeComponent component(&engine, TEST_FILE("stringArg.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("stringArg.qml"));
     QObject *object = component.create();
     QVERIFY(object != 0);
     QMetaObject::invokeMethod(object, "success");
     QVERIFY(object->property("returnValue").toBool());
 
-    QString w1 = TEST_FILE("stringArg.qml").toString() + QLatin1String(":45: Error: String.arg(): Invalid arguments");
+    QString w1 = testFileUrl("stringArg.qml").toString() + QLatin1String(":45: Error: String.arg(): Invalid arguments");
     QTest::ignoreMessage(QtWarningMsg, w1.toAscii().constData());
     QMetaObject::invokeMethod(object, "failure");
     QVERIFY(object->property("returnValue").toBool());
@@ -4080,7 +4436,7 @@ void tst_qdeclarativeecmascript::stringArg()
 
 void tst_qdeclarativeecmascript::readonlyDeclaration()
 {
-    QDeclarativeComponent component(&engine, TEST_FILE("readonlyDeclaration.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("readonlyDeclaration.qml"));
 
     QObject *object = component.create();
     QVERIFY(object != 0);
@@ -4098,7 +4454,7 @@ Q_DECLARE_METATYPE(QList<QUrl>)
 void tst_qdeclarativeecmascript::sequenceConversionRead()
 {
     {
-        QUrl qmlFile = TEST_FILE("sequenceConversion.read.qml");
+        QUrl qmlFile = testFileUrl("sequenceConversion.read.qml");
         QDeclarativeComponent component(&engine, qmlFile);
         QObject *object = component.create();
         QVERIFY(object != 0);
@@ -4149,7 +4505,7 @@ void tst_qdeclarativeecmascript::sequenceConversionRead()
     }
 
     {
-        QUrl qmlFile = TEST_FILE("sequenceConversion.read.error.qml");
+        QUrl qmlFile = testFileUrl("sequenceConversion.read.error.qml");
         QDeclarativeComponent component(&engine, qmlFile);
         QObject *object = component.create();
         QVERIFY(object != 0);
@@ -4178,7 +4534,7 @@ void tst_qdeclarativeecmascript::sequenceConversionRead()
 void tst_qdeclarativeecmascript::sequenceConversionWrite()
 {
     {
-        QUrl qmlFile = TEST_FILE("sequenceConversion.write.qml");
+        QUrl qmlFile = testFileUrl("sequenceConversion.write.qml");
         QDeclarativeComponent component(&engine, qmlFile);
         QObject *object = component.create();
         QVERIFY(object != 0);
@@ -4201,7 +4557,7 @@ void tst_qdeclarativeecmascript::sequenceConversionWrite()
     }
 
     {
-        QUrl qmlFile = TEST_FILE("sequenceConversion.write.error.qml");
+        QUrl qmlFile = testFileUrl("sequenceConversion.write.error.qml");
         QDeclarativeComponent component(&engine, qmlFile);
         QObject *object = component.create();
         QVERIFY(object != 0);
@@ -4224,7 +4580,7 @@ void tst_qdeclarativeecmascript::sequenceConversionWrite()
 void tst_qdeclarativeecmascript::sequenceConversionArray()
 {
     // ensure that in JS the returned sequences act just like normal JS Arrays.
-    QUrl qmlFile = TEST_FILE("sequenceConversion.array.qml");
+    QUrl qmlFile = testFileUrl("sequenceConversion.array.qml");
     QDeclarativeComponent component(&engine, qmlFile);
     QObject *object = component.create();
     QVERIFY(object != 0);
@@ -4243,7 +4599,7 @@ void tst_qdeclarativeecmascript::sequenceConversionThreads()
 {
     // ensure that sequence conversion operations work correctly in a worker thread
     // and that serialisation between the main and worker thread succeeds.
-    QUrl qmlFile = TEST_FILE("sequenceConversion.threads.qml");
+    QUrl qmlFile = testFileUrl("sequenceConversion.threads.qml");
     QDeclarativeComponent component(&engine, qmlFile);
     QObject *object = component.create();
     QVERIFY(object != 0);
@@ -4282,7 +4638,7 @@ void tst_qdeclarativeecmascript::sequenceConversionThreads()
 void tst_qdeclarativeecmascript::sequenceConversionBindings()
 {
     {
-        QUrl qmlFile = TEST_FILE("sequenceConversion.bindings.qml");
+        QUrl qmlFile = testFileUrl("sequenceConversion.bindings.qml");
         QDeclarativeComponent component(&engine, qmlFile);
         QObject *object = component.create();
         QVERIFY(object != 0);
@@ -4295,7 +4651,7 @@ void tst_qdeclarativeecmascript::sequenceConversionBindings()
     }
 
     {
-        QUrl qmlFile = TEST_FILE("sequenceConversion.bindings.error.qml");
+        QUrl qmlFile = testFileUrl("sequenceConversion.bindings.error.qml");
         QString warning = QString(QLatin1String("%1:17: Unable to assign QList<int> to QList<bool>")).arg(qmlFile.toString());
         QTest::ignoreMessage(QtWarningMsg, warning.toAscii().constData());
         QDeclarativeComponent component(&engine, qmlFile);
@@ -4307,7 +4663,7 @@ void tst_qdeclarativeecmascript::sequenceConversionBindings()
 
 void tst_qdeclarativeecmascript::sequenceConversionCopy()
 {
-    QUrl qmlFile = TEST_FILE("sequenceConversion.copy.qml");
+    QUrl qmlFile = testFileUrl("sequenceConversion.copy.qml");
     QDeclarativeComponent component(&engine, qmlFile);
     QObject *object = component.create();
     QVERIFY(object != 0);
@@ -4320,11 +4676,113 @@ void tst_qdeclarativeecmascript::sequenceConversionCopy()
     delete object;
 }
 
+void tst_qdeclarativeecmascript::assignSequenceTypes()
+{
+    // test binding array to sequence type property
+    {
+    QDeclarativeComponent component(&engine, testFileUrl("assignSequenceTypes.1.qml"));
+    MySequenceConversionObject *object = qobject_cast<MySequenceConversionObject *>(component.create());
+    QVERIFY(object != 0);
+    QCOMPARE(object->intListProperty(), (QList<int>() << 1 << 2));
+    QCOMPARE(object->qrealListProperty(), (QList<qreal>() << 1.1 << 2.2));
+    QCOMPARE(object->boolListProperty(), (QList<bool>() << false << true));
+    QCOMPARE(object->urlListProperty(), (QList<QUrl>() << QUrl("http://www.example1.com") << QUrl("http://www.example2.com")));
+    QCOMPARE(object->stringListProperty(), (QList<QString>() << QLatin1String("one") << QLatin1String("two")));
+    QCOMPARE(object->qstringListProperty(), (QStringList() << QLatin1String("one") << QLatin1String("two")));
+    delete object;
+    }
+
+    // test binding literal to sequence type property
+    {
+    QDeclarativeComponent component(&engine, testFileUrl("assignSequenceTypes.2.qml"));
+    MySequenceConversionObject *object = qobject_cast<MySequenceConversionObject *>(component.create());
+    QVERIFY(object != 0);
+    QCOMPARE(object->intListProperty(), (QList<int>() << 1));
+    QCOMPARE(object->qrealListProperty(), (QList<qreal>() << 1.1));
+    QCOMPARE(object->boolListProperty(), (QList<bool>() << false));
+    QCOMPARE(object->urlListProperty(), (QList<QUrl>() << QUrl("http://www.example1.com")));
+    QCOMPARE(object->stringListProperty(), (QList<QString>() << QLatin1String("one")));
+    QCOMPARE(object->qstringListProperty(), (QStringList() << QLatin1String("two")));
+    delete object;
+    }
+
+    // test binding single value to sequence type property
+    {
+    QDeclarativeComponent component(&engine, testFileUrl("assignSequenceTypes.3.qml"));
+    MySequenceConversionObject *object = qobject_cast<MySequenceConversionObject *>(component.create());
+    QVERIFY(object != 0);
+    QCOMPARE(object->intListProperty(), (QList<int>() << 1));
+    QCOMPARE(object->qrealListProperty(), (QList<qreal>() << 1.1));
+    QCOMPARE(object->boolListProperty(), (QList<bool>() << false));
+    QCOMPARE(object->urlListProperty(), (QList<QUrl>() << QUrl(testFileUrl("example.html"))));
+    delete object;
+    }
+
+    // test assigning array to sequence type property in js function
+    {
+    QDeclarativeComponent component(&engine, testFileUrl("assignSequenceTypes.4.qml"));
+    MySequenceConversionObject *object = qobject_cast<MySequenceConversionObject *>(component.create());
+    QVERIFY(object != 0);
+    QCOMPARE(object->intListProperty(), (QList<int>() << 1 << 2));
+    QCOMPARE(object->qrealListProperty(), (QList<qreal>() << 1.1 << 2.2));
+    QCOMPARE(object->boolListProperty(), (QList<bool>() << false << true));
+    QCOMPARE(object->urlListProperty(), (QList<QUrl>() << QUrl("http://www.example1.com") << QUrl("http://www.example2.com")));
+    QCOMPARE(object->stringListProperty(), (QList<QString>() << QLatin1String("one") << QLatin1String("two")));
+    QCOMPARE(object->qstringListProperty(), (QStringList() << QLatin1String("one") << QLatin1String("two")));
+    delete object;
+    }
+
+    // test assigning literal to sequence type property in js function
+    {
+    QDeclarativeComponent component(&engine, testFileUrl("assignSequenceTypes.5.qml"));
+    MySequenceConversionObject *object = qobject_cast<MySequenceConversionObject *>(component.create());
+    QVERIFY(object != 0);
+    QCOMPARE(object->intListProperty(), (QList<int>() << 1));
+    QCOMPARE(object->qrealListProperty(), (QList<qreal>() << 1.1));
+    QCOMPARE(object->boolListProperty(), (QList<bool>() << false));
+    QCOMPARE(object->urlListProperty(), (QList<QUrl>() << QUrl("http://www.example1.com")));
+    QCOMPARE(object->stringListProperty(), (QList<QString>() << QLatin1String("one")));
+    QCOMPARE(object->qstringListProperty(), (QStringList() << QLatin1String("two")));
+    delete object;
+    }
+
+    // test assigning single value to sequence type property in js function
+    {
+    QDeclarativeComponent component(&engine, testFileUrl("assignSequenceTypes.6.qml"));
+    MySequenceConversionObject *object = qobject_cast<MySequenceConversionObject *>(component.create());
+    QVERIFY(object != 0);
+    QCOMPARE(object->intListProperty(), (QList<int>() << 1));
+    QCOMPARE(object->qrealListProperty(), (QList<qreal>() << 1.1));
+    QCOMPARE(object->boolListProperty(), (QList<bool>() << false));
+    QCOMPARE(object->urlListProperty(), (QList<QUrl>() << QUrl(testFileUrl("example.html"))));
+    delete object;
+    }
+
+    // test QList<QUrl> literal assignment and binding assignment causes url resolution when required
+    {
+    QDeclarativeComponent component(&engine, testFileUrl("assignSequenceTypes.7.qml"));
+    QObject *object = component.create();
+    QVERIFY(object != 0);
+    MySequenceConversionObject *msco1 = object->findChild<MySequenceConversionObject *>(QLatin1String("msco1"));
+    MySequenceConversionObject *msco2 = object->findChild<MySequenceConversionObject *>(QLatin1String("msco2"));
+    MySequenceConversionObject *msco3 = object->findChild<MySequenceConversionObject *>(QLatin1String("msco3"));
+    MySequenceConversionObject *msco4 = object->findChild<MySequenceConversionObject *>(QLatin1String("msco4"));
+    MySequenceConversionObject *msco5 = object->findChild<MySequenceConversionObject *>(QLatin1String("msco5"));
+    QVERIFY(msco1 != 0 && msco2 != 0 && msco3 != 0 && msco4 != 0 && msco5 != 0);
+    QCOMPARE(msco1->urlListProperty(), (QList<QUrl>() << QUrl(testFileUrl("example.html"))));
+    QCOMPARE(msco2->urlListProperty(), (QList<QUrl>() << QUrl(testFileUrl("example.html"))));
+    QCOMPARE(msco3->urlListProperty(), (QList<QUrl>() << QUrl(testFileUrl("example.html")) << QUrl(testFileUrl("example2.html"))));
+    QCOMPARE(msco4->urlListProperty(), (QList<QUrl>() << QUrl(testFileUrl("example.html")) << QUrl(testFileUrl("example2.html"))));
+    QCOMPARE(msco5->urlListProperty(), (QList<QUrl>() << QUrl(testFileUrl("example.html")) << QUrl(testFileUrl("example2.html"))));
+    delete object;
+    }
+}
+
 // Test that assigning a null object works 
 // Regressed with: df1788b4dbbb2826ae63f26bdf166342595343f4
 void tst_qdeclarativeecmascript::nullObjectBinding()
 {
-    QDeclarativeComponent component(&engine, TEST_FILE("nullObjectBinding.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("nullObjectBinding.qml"));
 
     QObject *object = component.create();
     QVERIFY(object != 0);
@@ -4338,7 +4796,7 @@ void tst_qdeclarativeecmascript::nullObjectBinding()
 void tst_qdeclarativeecmascript::deletedEngine()
 {
     QDeclarativeEngine *engine = new QDeclarativeEngine;
-    QDeclarativeComponent component(engine, TEST_FILE("deletedEngine.qml"));
+    QDeclarativeComponent component(engine, testFileUrl("deletedEngine.qml"));
 
     QObject *object = component.create();
     QVERIFY(object != 0);
@@ -4359,7 +4817,7 @@ void tst_qdeclarativeecmascript::deletedEngine()
 // Test the crashing part of QTBUG-9705
 void tst_qdeclarativeecmascript::libraryScriptAssert()
 {
-    QDeclarativeComponent component(&engine, TEST_FILE("libraryScriptAssert.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("libraryScriptAssert.qml"));
 
     QObject *object = component.create();
     QVERIFY(object != 0);
@@ -4369,7 +4827,7 @@ void tst_qdeclarativeecmascript::libraryScriptAssert()
 
 void tst_qdeclarativeecmascript::variantsAssignedUndefined()
 {
-    QDeclarativeComponent component(&engine, TEST_FILE("variantsAssignedUndefined.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("variantsAssignedUndefined.qml"));
 
     QObject *object = component.create();
     QVERIFY(object != 0);
@@ -4388,7 +4846,7 @@ void tst_qdeclarativeecmascript::variantsAssignedUndefined()
 
 void tst_qdeclarativeecmascript::qtbug_9792()
 {
-    QDeclarativeComponent component(&engine, TEST_FILE("qtbug_9792.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("qtbug_9792.qml"));
 
     QDeclarativeContext *context = new QDeclarativeContext(engine.rootContext());
 
@@ -4415,7 +4873,7 @@ void tst_qdeclarativeecmascript::qtbug_9792()
 // Verifies that QDeclarativeGuard<>s used in the vmemetaobject are cleaned correctly
 void tst_qdeclarativeecmascript::qtcreatorbug_1289()
 {
-    QDeclarativeComponent component(&engine, TEST_FILE("qtcreatorbug_1289.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("qtcreatorbug_1289.qml"));
 
     QObject *o = component.create();
     QVERIFY(o != 0);
@@ -4437,7 +4895,7 @@ void tst_qdeclarativeecmascript::qtcreatorbug_1289()
 void tst_qdeclarativeecmascript::noSpuriousWarningsAtShutdown()
 {
     {
-    QDeclarativeComponent component(&engine, TEST_FILE("noSpuriousWarningsAtShutdown.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("noSpuriousWarningsAtShutdown.qml"));
 
     QObject *o = component.create();
 
@@ -4453,7 +4911,7 @@ void tst_qdeclarativeecmascript::noSpuriousWarningsAtShutdown()
 
 
     {
-    QDeclarativeComponent component(&engine, TEST_FILE("noSpuriousWarningsAtShutdown.2.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("noSpuriousWarningsAtShutdown.2.qml"));
 
     QObject *o = component.create();
 
@@ -4471,7 +4929,7 @@ void tst_qdeclarativeecmascript::noSpuriousWarningsAtShutdown()
 void tst_qdeclarativeecmascript::canAssignNullToQObject()
 {
     {
-    QDeclarativeComponent component(&engine, TEST_FILE("canAssignNullToQObject.1.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("canAssignNullToQObject.1.qml"));
 
     MyQmlObject *o = qobject_cast<MyQmlObject *>(component.create());
     QVERIFY(o != 0);
@@ -4486,7 +4944,7 @@ void tst_qdeclarativeecmascript::canAssignNullToQObject()
     }
 
     {
-    QDeclarativeComponent component(&engine, TEST_FILE("canAssignNullToQObject.2.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("canAssignNullToQObject.2.qml"));
 
     MyQmlObject *o = qobject_cast<MyQmlObject *>(component.create());
     QVERIFY(o != 0);
@@ -4499,7 +4957,7 @@ void tst_qdeclarativeecmascript::canAssignNullToQObject()
 
 void tst_qdeclarativeecmascript::functionAssignment_fromBinding()
 {
-    QDeclarativeComponent component(&engine, TEST_FILE("functionAssignment.1.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("functionAssignment.1.qml"));
 
     QString url = component.url().toString();
     QString warning = url + ":4: Unable to assign a function to a property.";
@@ -4517,7 +4975,7 @@ void tst_qdeclarativeecmascript::functionAssignment_fromJS()
 {
     QFETCH(QString, triggerProperty);
 
-    QDeclarativeComponent component(&engine, TEST_FILE("functionAssignment.2.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("functionAssignment.2.qml"));
     QVERIFY2(component.errorString().isEmpty(), qPrintable(component.errorString()));
 
     MyQmlObject *o = qobject_cast<MyQmlObject *>(component.create());
@@ -4549,7 +5007,7 @@ void tst_qdeclarativeecmascript::functionAssignment_fromJS_data()
 
 void tst_qdeclarativeecmascript::functionAssignmentfromJS_invalid()
 {
-    QDeclarativeComponent component(&engine, TEST_FILE("functionAssignment.2.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("functionAssignment.2.qml"));
     QVERIFY2(component.errorString().isEmpty(), qPrintable(component.errorString()));
 
     MyQmlObject *o = qobject_cast<MyQmlObject *>(component.create());
@@ -4573,7 +5031,7 @@ void tst_qdeclarativeecmascript::functionAssignmentfromJS_invalid()
 
 void tst_qdeclarativeecmascript::eval()
 {
-    QDeclarativeComponent component(&engine, TEST_FILE("eval.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("eval.qml"));
 
     QObject *o = component.create();
     QVERIFY(o != 0);
@@ -4589,7 +5047,7 @@ void tst_qdeclarativeecmascript::eval()
 
 void tst_qdeclarativeecmascript::function()
 {
-    QDeclarativeComponent component(&engine, TEST_FILE("function.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("function.qml"));
 
     QObject *o = component.create();
     QVERIFY(o != 0);
@@ -4606,7 +5064,7 @@ void tst_qdeclarativeecmascript::include()
 {
     // Non-library relative include
     {
-    QDeclarativeComponent component(&engine, TEST_FILE("include.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("include.qml"));
     QObject *o = component.create();
     QVERIFY(o != 0);
 
@@ -4622,7 +5080,7 @@ void tst_qdeclarativeecmascript::include()
 
     // Library relative include
     {
-    QDeclarativeComponent component(&engine, TEST_FILE("include_shared.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("include_shared.qml"));
     QObject *o = component.create();
     QVERIFY(o != 0);
 
@@ -4638,7 +5096,7 @@ void tst_qdeclarativeecmascript::include()
 
     // Callback
     {
-    QDeclarativeComponent component(&engine, TEST_FILE("include_callback.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("include_callback.qml"));
     QObject *o = component.create();
     QVERIFY(o != 0);
 
@@ -4654,7 +5112,7 @@ void tst_qdeclarativeecmascript::include()
 
     // Including file with ".pragma library"
     {
-    QDeclarativeComponent component(&engine, TEST_FILE("include_pragma.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("include_pragma.qml"));
     QObject *o = component.create();
     QVERIFY(o != 0);
     QCOMPARE(o->property("test1").toInt(), 100);
@@ -4666,9 +5124,9 @@ void tst_qdeclarativeecmascript::include()
     {
     TestHTTPServer server(8111);
     QVERIFY(server.isValid());
-    server.serveDirectory(TESTDATA(""));
+    server.serveDirectory(dataDirectory());
 
-    QDeclarativeComponent component(&engine, TEST_FILE("include_remote.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("include_remote.qml"));
     QObject *o = component.create();
     QVERIFY(o != 0);
 
@@ -4694,9 +5152,9 @@ void tst_qdeclarativeecmascript::include()
     {
     TestHTTPServer server(8111);
     QVERIFY(server.isValid());
-    server.serveDirectory(TESTDATA(""));
+    server.serveDirectory(dataDirectory());
 
-    QDeclarativeComponent component(&engine, TEST_FILE("include_remote_missing.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("include_remote_missing.qml"));
     QObject *o = component.create();
     QVERIFY(o != 0);
 
@@ -4712,7 +5170,7 @@ void tst_qdeclarativeecmascript::include()
 
 void tst_qdeclarativeecmascript::signalHandlers()
 {
-    QDeclarativeComponent component(&engine, TEST_FILE("signalHandlers.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("signalHandlers.qml"));
     QObject *o = component.create();
     QVERIFY(o != 0);
 
@@ -4742,7 +5200,7 @@ void tst_qdeclarativeecmascript::signalHandlers()
 
 void tst_qdeclarativeecmascript::qtbug_10696()
 {
-    QDeclarativeComponent component(&engine, TEST_FILE("qtbug_10696.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("qtbug_10696.qml"));
     QObject *o = component.create();
     QVERIFY(o != 0);
     delete o;
@@ -4750,7 +5208,7 @@ void tst_qdeclarativeecmascript::qtbug_10696()
 
 void tst_qdeclarativeecmascript::qtbug_11606()
 {
-    QDeclarativeComponent component(&engine, TEST_FILE("qtbug_11606.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("qtbug_11606.qml"));
     QObject *o = component.create();
     QVERIFY(o != 0);
     QCOMPARE(o->property("test").toBool(), true);
@@ -4759,7 +5217,30 @@ void tst_qdeclarativeecmascript::qtbug_11606()
 
 void tst_qdeclarativeecmascript::qtbug_11600()
 {
-    QDeclarativeComponent component(&engine, TEST_FILE("qtbug_11600.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("qtbug_11600.qml"));
+    QObject *o = component.create();
+    QVERIFY(o != 0);
+    QCOMPARE(o->property("test").toBool(), true);
+    delete o;
+}
+
+void tst_qdeclarativeecmascript::qtbug_21864()
+{
+    QDeclarativeComponent component(&engine, testFileUrl("qtbug_21864.qml"));
+    QObject *o = component.create();
+    QVERIFY(o != 0);
+    QCOMPARE(o->property("test").toBool(), true);
+    delete o;
+}
+
+void tst_qdeclarativeecmascript::qobjectConnectionListExceptionHandling()
+{
+    // QTBUG-23375
+    QDeclarativeComponent component(&engine, testFileUrl("qobjectConnectionListExceptionHandling.qml"));
+    QString warning = component.url().toString() + QLatin1String(":13: TypeError: Cannot read property 'undefined' of undefined");
+    QTest::ignoreMessage(QtWarningMsg, qPrintable(warning));
+    QTest::ignoreMessage(QtWarningMsg, qPrintable(warning));
+    QTest::ignoreMessage(QtWarningMsg, qPrintable(warning));
     QObject *o = component.create();
     QVERIFY(o != 0);
     QCOMPARE(o->property("test").toBool(), true);
@@ -4769,7 +5250,7 @@ void tst_qdeclarativeecmascript::qtbug_11600()
 // Reading and writing non-scriptable properties should fail
 void tst_qdeclarativeecmascript::nonscriptable()
 {
-    QDeclarativeComponent component(&engine, TEST_FILE("nonscriptable.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("nonscriptable.qml"));
     QObject *o = component.create();
     QVERIFY(o != 0);
     QCOMPARE(o->property("readOk").toBool(), true);
@@ -4780,7 +5261,7 @@ void tst_qdeclarativeecmascript::nonscriptable()
 // deleteLater() should not be callable from QML
 void tst_qdeclarativeecmascript::deleteLater()
 {
-    QDeclarativeComponent component(&engine, TEST_FILE("deleteLater.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("deleteLater.qml"));
     QObject *o = component.create();
     QVERIFY(o != 0);
     QCOMPARE(o->property("test").toBool(), true);
@@ -4789,7 +5270,7 @@ void tst_qdeclarativeecmascript::deleteLater()
 
 void tst_qdeclarativeecmascript::in()
 {
-    QDeclarativeComponent component(&engine, TEST_FILE("in.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("in.qml"));
     QObject *o = component.create();
     QVERIFY(o != 0);
     QCOMPARE(o->property("test1").toBool(), true);
@@ -4799,9 +5280,18 @@ void tst_qdeclarativeecmascript::in()
 
 void tst_qdeclarativeecmascript::typeOf()
 {
-    QDeclarativeComponent component(&engine, TEST_FILE("typeOf.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("typeOf.qml"));
+
+    // These warnings should not happen once QTBUG-21864 is fixed
+    QString warning1 = component.url().toString() + QLatin1String(":16: Error: Cannot assign [undefined] to QString");
+    QString warning2 = component.url().resolved(QUrl("typeOf.js")).toString() + QLatin1String(":1: ReferenceError: Can't find variable: a");
+
+    QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1));
+    QTest::ignoreMessage(QtWarningMsg, qPrintable(warning2));
+
     QObject *o = component.create();
     QVERIFY(o != 0);
+
     QEXPECT_FAIL("", "QTBUG-21864", Abort);
     QCOMPARE(o->property("test1").toString(), QLatin1String("undefined"));
     QCOMPARE(o->property("test2").toString(), QLatin1String("object"));
@@ -4818,7 +5308,7 @@ void tst_qdeclarativeecmascript::typeOf()
 
 void tst_qdeclarativeecmascript::sharedAttachedObject()
 {
-    QDeclarativeComponent component(&engine, TEST_FILE("sharedAttachedObject.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("sharedAttachedObject.qml"));
     QObject *o = component.create();
     QVERIFY(o != 0);
     QCOMPARE(o->property("test1").toBool(), true);
@@ -4829,7 +5319,7 @@ void tst_qdeclarativeecmascript::sharedAttachedObject()
 // QTBUG-13999
 void tst_qdeclarativeecmascript::objectName()
 {
-    QDeclarativeComponent component(&engine, TEST_FILE("objectName.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("objectName.qml"));
     QObject *o = component.create();
     QVERIFY(o != 0);
 
@@ -4846,7 +5336,7 @@ void tst_qdeclarativeecmascript::objectName()
 
 void tst_qdeclarativeecmascript::writeRemovesBinding()
 {
-    QDeclarativeComponent component(&engine, TEST_FILE("writeRemovesBinding.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("writeRemovesBinding.qml"));
     QObject *o = component.create();
     QVERIFY(o != 0);
 
@@ -4858,7 +5348,7 @@ void tst_qdeclarativeecmascript::writeRemovesBinding()
 // Test bindings assigned to alias properties actually assign to the alias' target
 void tst_qdeclarativeecmascript::aliasBindingsAssignCorrectly()
 {
-    QDeclarativeComponent component(&engine, TEST_FILE("aliasBindingsAssignCorrectly.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("aliasBindingsAssignCorrectly.qml"));
     QObject *o = component.create();
     QVERIFY(o != 0);
 
@@ -4871,7 +5361,7 @@ void tst_qdeclarativeecmascript::aliasBindingsAssignCorrectly()
 void tst_qdeclarativeecmascript::aliasBindingsOverrideTarget()
 {
     { 
-    QDeclarativeComponent component(&engine, TEST_FILE("aliasBindingsOverrideTarget.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("aliasBindingsOverrideTarget.qml"));
     QObject *o = component.create();
     QVERIFY(o != 0);
 
@@ -4881,7 +5371,7 @@ void tst_qdeclarativeecmascript::aliasBindingsOverrideTarget()
     }
 
     {
-    QDeclarativeComponent component(&engine, TEST_FILE("aliasBindingsOverrideTarget.2.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("aliasBindingsOverrideTarget.2.qml"));
     QObject *o = component.create();
     QVERIFY(o != 0);
 
@@ -4891,7 +5381,7 @@ void tst_qdeclarativeecmascript::aliasBindingsOverrideTarget()
     }
 
     {
-    QDeclarativeComponent component(&engine, TEST_FILE("aliasBindingsOverrideTarget.3.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("aliasBindingsOverrideTarget.3.qml"));
     QObject *o = component.create();
     QVERIFY(o != 0);
 
@@ -4905,7 +5395,7 @@ void tst_qdeclarativeecmascript::aliasBindingsOverrideTarget()
 void tst_qdeclarativeecmascript::aliasWritesOverrideBindings()
 {
     {
-    QDeclarativeComponent component(&engine, TEST_FILE("aliasWritesOverrideBindings.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("aliasWritesOverrideBindings.qml"));
     QObject *o = component.create();
     QVERIFY(o != 0);
 
@@ -4915,7 +5405,7 @@ void tst_qdeclarativeecmascript::aliasWritesOverrideBindings()
     }
 
     {
-    QDeclarativeComponent component(&engine, TEST_FILE("aliasWritesOverrideBindings.2.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("aliasWritesOverrideBindings.2.qml"));
     QObject *o = component.create();
     QVERIFY(o != 0);
 
@@ -4925,7 +5415,7 @@ void tst_qdeclarativeecmascript::aliasWritesOverrideBindings()
     }
 
     {
-    QDeclarativeComponent component(&engine, TEST_FILE("aliasWritesOverrideBindings.3.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("aliasWritesOverrideBindings.3.qml"));
     QObject *o = component.create();
     QVERIFY(o != 0);
 
@@ -4939,7 +5429,7 @@ void tst_qdeclarativeecmascript::aliasWritesOverrideBindings()
 // QTBUG-20200
 void tst_qdeclarativeecmascript::aliasToCompositeElement()
 {
-    QDeclarativeComponent component(&engine, TEST_FILE("aliasToCompositeElement.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("aliasToCompositeElement.qml"));
 
     QObject *object = component.create();
     QVERIFY(object != 0);
@@ -4949,7 +5439,7 @@ void tst_qdeclarativeecmascript::aliasToCompositeElement()
 
 void tst_qdeclarativeecmascript::qtbug_20344()
 {
-    QDeclarativeComponent component(&engine, TEST_FILE("qtbug_20344.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("qtbug_20344.qml"));
 
     QString warning = component.url().toString() + ":5: Error: Exception thrown from within QObject slot";
     QTest::ignoreMessage(QtWarningMsg, qPrintable(warning));
@@ -4963,7 +5453,7 @@ void tst_qdeclarativeecmascript::qtbug_20344()
 void tst_qdeclarativeecmascript::revisionErrors()
 {
     {
-        QDeclarativeComponent component(&engine, TEST_FILE("metaobjectRevisionErrors.qml"));
+        QDeclarativeComponent component(&engine, testFileUrl("metaobjectRevisionErrors.qml"));
         QString url = component.url().toString();
 
         QString warning1 = url + ":8: ReferenceError: Can't find variable: prop2";
@@ -4978,7 +5468,7 @@ void tst_qdeclarativeecmascript::revisionErrors()
         delete object;
     }
     {
-        QDeclarativeComponent component(&engine, TEST_FILE("metaobjectRevisionErrors2.qml"));
+        QDeclarativeComponent component(&engine, testFileUrl("metaobjectRevisionErrors2.qml"));
         QString url = component.url().toString();
 
         // MyRevisionedSubclass 1.0 uses MyRevisionedClass revision 0
@@ -5000,7 +5490,7 @@ void tst_qdeclarativeecmascript::revisionErrors()
         delete object;
     }
     {
-        QDeclarativeComponent component(&engine, TEST_FILE("metaobjectRevisionErrors3.qml"));
+        QDeclarativeComponent component(&engine, testFileUrl("metaobjectRevisionErrors3.qml"));
         QString url = component.url().toString();
 
         // MyRevisionedSubclass 1.1 uses MyRevisionedClass revision 1
@@ -5020,7 +5510,7 @@ void tst_qdeclarativeecmascript::revisionErrors()
 void tst_qdeclarativeecmascript::revision()
 {
     {
-        QDeclarativeComponent component(&engine, TEST_FILE("metaobjectRevision.qml"));
+        QDeclarativeComponent component(&engine, testFileUrl("metaobjectRevision.qml"));
         QString url = component.url().toString();
 
         MyRevisionedClass *object = qobject_cast<MyRevisionedClass *>(component.create());
@@ -5028,7 +5518,7 @@ void tst_qdeclarativeecmascript::revision()
         delete object;
     }
     {
-        QDeclarativeComponent component(&engine, TEST_FILE("metaobjectRevision2.qml"));
+        QDeclarativeComponent component(&engine, testFileUrl("metaobjectRevision2.qml"));
         QString url = component.url().toString();
 
         MyRevisionedClass *object = qobject_cast<MyRevisionedClass *>(component.create());
@@ -5036,7 +5526,7 @@ void tst_qdeclarativeecmascript::revision()
         delete object;
     }
     {
-        QDeclarativeComponent component(&engine, TEST_FILE("metaobjectRevision3.qml"));
+        QDeclarativeComponent component(&engine, testFileUrl("metaobjectRevision3.qml"));
         QString url = component.url().toString();
 
         MyRevisionedClass *object = qobject_cast<MyRevisionedClass *>(component.create());
@@ -5045,7 +5535,7 @@ void tst_qdeclarativeecmascript::revision()
     }
     // Test that non-root classes can resolve revisioned methods
     {
-        QDeclarativeComponent component(&engine, TEST_FILE("metaobjectRevision4.qml"));
+        QDeclarativeComponent component(&engine, testFileUrl("metaobjectRevision4.qml"));
 
         QObject *object = component.create();
         QVERIFY(object != 0);
@@ -5056,7 +5546,7 @@ void tst_qdeclarativeecmascript::revision()
 
 void tst_qdeclarativeecmascript::realToInt()
 {
-    QDeclarativeComponent component(&engine, TEST_FILE("realToInt.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("realToInt.qml"));
     MyQmlObject *object = qobject_cast<MyQmlObject*>(component.create());
     QVERIFY(object != 0);
 
@@ -5065,9 +5555,60 @@ void tst_qdeclarativeecmascript::realToInt()
     QMetaObject::invokeMethod(object, "test2");
     QCOMPARE(object->value(), int(8));
 }
+
+void tst_qdeclarativeecmascript::urlProperty()
+{
+    {
+        QDeclarativeComponent component(&engine, testFileUrl("urlProperty.1.qml"));
+        MyQmlObject *object = qobject_cast<MyQmlObject*>(component.create());
+        QVERIFY(object != 0);
+        object->setStringProperty("http://qt-project.org");
+        QCOMPARE(object->urlProperty(), QUrl("http://qt-project.org/index.html"));
+        QCOMPARE(object->intProperty(), 123);
+        QCOMPARE(object->value(), 1);
+        QCOMPARE(object->property("result").toBool(), true);
+    }
+}
+
+void tst_qdeclarativeecmascript::urlPropertyWithEncoding()
+{
+    {
+        QDeclarativeComponent component(&engine, testFileUrl("urlProperty.2.qml"));
+        MyQmlObject *object = qobject_cast<MyQmlObject*>(component.create());
+        QVERIFY(object != 0);
+        object->setStringProperty("http://qt-project.org");
+        QUrl encoded;
+        encoded.setEncodedUrl("http://qt-project.org/?get%3cDATA%3e", QUrl::TolerantMode);
+        QCOMPARE(object->urlProperty(), encoded);
+        QCOMPARE(object->value(), 0);   // Interpreting URL as string yields canonicalised version
+        QCOMPARE(object->property("result").toBool(), true);
+    }
+}
+
+void tst_qdeclarativeecmascript::urlListPropertyWithEncoding()
+{
+    {
+        QDeclarativeComponent component(&engine, testFileUrl("urlListProperty.qml"));
+        QObject *object = component.create();
+        QVERIFY(object != 0);
+        MySequenceConversionObject *msco1 = object->findChild<MySequenceConversionObject *>(QLatin1String("msco1"));
+        MySequenceConversionObject *msco2 = object->findChild<MySequenceConversionObject *>(QLatin1String("msco2"));
+        MySequenceConversionObject *msco3 = object->findChild<MySequenceConversionObject *>(QLatin1String("msco3"));
+        MySequenceConversionObject *msco4 = object->findChild<MySequenceConversionObject *>(QLatin1String("msco4"));
+        QVERIFY(msco1 != 0 && msco2 != 0 && msco3 != 0 && msco4 != 0);
+        QUrl encoded;
+        encoded.setEncodedUrl("http://qt-project.org/?get%3cDATA%3e", QUrl::TolerantMode);
+        QCOMPARE(msco1->urlListProperty(), (QList<QUrl>() << encoded));
+        QCOMPARE(msco2->urlListProperty(), (QList<QUrl>() << encoded));
+        QCOMPARE(msco3->urlListProperty(), (QList<QUrl>() << encoded << encoded));
+        QCOMPARE(msco4->urlListProperty(), (QList<QUrl>() << encoded << encoded));
+        delete object;
+    }
+}
+
 void tst_qdeclarativeecmascript::dynamicString()
 {
-    QDeclarativeComponent component(&engine, TEST_FILE("dynamicString.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("dynamicString.qml"));
     QObject *object = component.create();
     QVERIFY(object != 0);
     QCOMPARE(object->property("stringProperty").toString(),
@@ -5076,14 +5617,14 @@ void tst_qdeclarativeecmascript::dynamicString()
 
 void tst_qdeclarativeecmascript::automaticSemicolon()
 {
-    QDeclarativeComponent component(&engine, TEST_FILE("automaticSemicolon.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("automaticSemicolon.qml"));
     QObject *object = component.create();
     QVERIFY(object != 0);
 }
 
 void tst_qdeclarativeecmascript::unaryExpression()
 {
-    QDeclarativeComponent component(&engine, TEST_FILE("unaryExpression.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("unaryExpression.qml"));
     QObject *object = component.create();
     QVERIFY(object != 0);
 }
@@ -5091,7 +5632,7 @@ void tst_qdeclarativeecmascript::unaryExpression()
 // Makes sure that a binding isn't double re-evaluated when it depends on the same variable twice
 void tst_qdeclarativeecmascript::doubleEvaluate()
 {
-    QDeclarativeComponent component(&engine, TEST_FILE("doubleEvaluate.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("doubleEvaluate.qml"));
     QObject *object = component.create();
     QVERIFY(object != 0);
     WriteCounter *wc = qobject_cast<WriteCounter *>(object);
@@ -5114,7 +5655,7 @@ static void captureMsgHandler(QtMsgType, const char *msg)
 void tst_qdeclarativeecmascript::nonNotifyable()
 {
     QV4Compiler::enableV4(false);
-    QDeclarativeComponent component(&engine, TEST_FILE("nonNotifyable.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("nonNotifyable.qml"));
     QV4Compiler::enableV4(true);
 
     QtMsgHandler old = qInstallMsgHandler(captureMsgHandler);
@@ -5140,7 +5681,7 @@ void tst_qdeclarativeecmascript::nonNotifyable()
 
 void tst_qdeclarativeecmascript::forInLoop()
 {
-    QDeclarativeComponent component(&engine, TEST_FILE("forInLoop.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("forInLoop.qml"));
     QObject *object = component.create();
     QVERIFY(object != 0);
 
@@ -5160,7 +5701,7 @@ void tst_qdeclarativeecmascript::forInLoop()
 // An object the binding depends on is deleted while the binding is still running
 void tst_qdeclarativeecmascript::deleteWhileBindingRunning()
 {
-    QDeclarativeComponent component(&engine, TEST_FILE("deleteWhileBindingRunning.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("deleteWhileBindingRunning.qml"));
     QObject *object = component.create();
     QVERIFY(object != 0);
     delete object;
@@ -5172,7 +5713,7 @@ void tst_qdeclarativeecmascript::qtbug_22679()
     object.setStringProperty(QLatin1String("Please work correctly"));
     engine.rootContext()->setContextProperty("contextProp", &object);
 
-    QDeclarativeComponent component(&engine, TEST_FILE("qtbug_22679.qml"));
+    QDeclarativeComponent component(&engine, testFileUrl("qtbug_22679.qml"));
     qRegisterMetaType<QList<QDeclarativeError> >("QList<QDeclarativeError>");
     QSignalSpy warningsSpy(&engine, SIGNAL(warnings(QList<QDeclarativeError>)));
 
@@ -5199,7 +5740,7 @@ void tst_qdeclarativeecmascript::qtbug_22843()
         fileName += QLatin1String(".library");
     fileName += QLatin1String(".qml");
 
-    QDeclarativeComponent component(&engine, TEST_FILE(fileName));
+    QDeclarativeComponent component(&engine, testFileUrl(fileName));
     QString url = component.url().toString();
     QString warning1 = url.left(url.length()-3) + QLatin1String("js:4: SyntaxError: Unexpected token )");
     QString warning2 = url + QLatin1String(":5: TypeError: Object [object Object] has no method 'func'");
@@ -5226,7 +5767,7 @@ void tst_qdeclarativeecmascript::qtbug_22843()
 void tst_qdeclarativeecmascript::switchStatement()
 {
     {
-        QDeclarativeComponent component(&engine, TEST_FILE("switchStatement.1.qml"));
+        QDeclarativeComponent component(&engine, testFileUrl("switchStatement.1.qml"));
         MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
         QVERIFY(object != 0);
 
@@ -5249,7 +5790,7 @@ void tst_qdeclarativeecmascript::switchStatement()
     }
 
     {
-        QDeclarativeComponent component(&engine, TEST_FILE("switchStatement.2.qml"));
+        QDeclarativeComponent component(&engine, testFileUrl("switchStatement.2.qml"));
         MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
         QVERIFY(object != 0);
 
@@ -5272,7 +5813,7 @@ void tst_qdeclarativeecmascript::switchStatement()
     }
 
     {
-        QDeclarativeComponent component(&engine, TEST_FILE("switchStatement.3.qml"));
+        QDeclarativeComponent component(&engine, testFileUrl("switchStatement.3.qml"));
         MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
         QVERIFY(object != 0);
 
@@ -5295,7 +5836,11 @@ void tst_qdeclarativeecmascript::switchStatement()
     }
 
     {
-        QDeclarativeComponent component(&engine, TEST_FILE("switchStatement.4.qml"));
+        QDeclarativeComponent component(&engine, testFileUrl("switchStatement.4.qml"));
+
+        QString warning = component.url().toString() + ":4: Unable to assign [undefined] to int";
+        QTest::ignoreMessage(QtWarningMsg, qPrintable(warning));
+
         MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
         QVERIFY(object != 0);
 
@@ -5313,14 +5858,13 @@ void tst_qdeclarativeecmascript::switchStatement()
         object->setStringProperty("F");
         QCOMPARE(object->value(), 3);
 
-        QString warning = component.url().toString() + ":4: Unable to assign [undefined] to int";
         QTest::ignoreMessage(QtWarningMsg, qPrintable(warning));
 
         object->setStringProperty("something else");
     }
 
     {
-        QDeclarativeComponent component(&engine, TEST_FILE("switchStatement.5.qml"));
+        QDeclarativeComponent component(&engine, testFileUrl("switchStatement.5.qml"));
         MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
         QVERIFY(object != 0);
 
@@ -5343,7 +5887,7 @@ void tst_qdeclarativeecmascript::switchStatement()
     }
 
     {
-        QDeclarativeComponent component(&engine, TEST_FILE("switchStatement.6.qml"));
+        QDeclarativeComponent component(&engine, testFileUrl("switchStatement.6.qml"));
         MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
         QVERIFY(object != 0);
 
@@ -5369,7 +5913,7 @@ void tst_qdeclarativeecmascript::switchStatement()
 void tst_qdeclarativeecmascript::withStatement()
 {
     {
-        QDeclarativeComponent component(&engine, TEST_FILE("withStatement.1.qml"));
+        QDeclarativeComponent component(&engine, testFileUrl("withStatement.1.qml"));
         MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
         QVERIFY(object != 0);
 
@@ -5380,7 +5924,7 @@ void tst_qdeclarativeecmascript::withStatement()
 void tst_qdeclarativeecmascript::tryStatement()
 {
     {
-        QDeclarativeComponent component(&engine, TEST_FILE("tryStatement.1.qml"));
+        QDeclarativeComponent component(&engine, testFileUrl("tryStatement.1.qml"));
         MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
         QVERIFY(object != 0);
 
@@ -5388,7 +5932,7 @@ void tst_qdeclarativeecmascript::tryStatement()
     }
 
     {
-        QDeclarativeComponent component(&engine, TEST_FILE("tryStatement.2.qml"));
+        QDeclarativeComponent component(&engine, testFileUrl("tryStatement.2.qml"));
         MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
         QVERIFY(object != 0);
 
@@ -5396,7 +5940,7 @@ void tst_qdeclarativeecmascript::tryStatement()
     }
 
     {
-        QDeclarativeComponent component(&engine, TEST_FILE("tryStatement.3.qml"));
+        QDeclarativeComponent component(&engine, testFileUrl("tryStatement.3.qml"));
         MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
         QVERIFY(object != 0);
 
@@ -5404,7 +5948,7 @@ void tst_qdeclarativeecmascript::tryStatement()
     }
 
     {
-        QDeclarativeComponent component(&engine, TEST_FILE("tryStatement.4.qml"));
+        QDeclarativeComponent component(&engine, testFileUrl("tryStatement.4.qml"));
         MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
         QVERIFY(object != 0);