From fd68b868aee89f40138492468745f0e5edb3286e Mon Sep 17 00:00:00 2001 From: Chris Adams Date: Tue, 12 Jul 2011 14:05:24 +1000 Subject: Honour the resettable flag of aliased properties Previously, alias properties were not considered isResettable even if the property they alias is resettable. This commit ensures that the IsResettable flag is set for alias properties iff the aliased property is resettable, and that it is honoured during property reset operations. Task-number: QTBUG-18182 Change-Id: I9cab11923a952df72e976a48489a78b24a34314f Reviewed-on: http://codereview.qt.nokia.com/1471 Reviewed-by: Qt Sanity Bot Reviewed-by: Aaron Kennedy --- .../tst_qdeclarativeecmascript.cpp | 82 ++++++++++++++++++++++ 1 file changed, 82 insertions(+) (limited to 'tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp') diff --git a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp index c5f7ed1b58..3efe18909c 100644 --- a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp +++ b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp @@ -104,6 +104,7 @@ private slots: void constantsOverrideBindings(); void outerBindingOverridesInnerBinding(); void aliasPropertyAndBinding(); + void aliasPropertyReset(); void nonExistentAttachedObject(); void scope(); void importScope(); @@ -1038,6 +1039,87 @@ void tst_qdeclarativeecmascript::aliasPropertyAndBinding() delete object; } +/* +Ensure that we can write undefined value to an alias property, +and that the aliased property is reset correctly if possible. +*/ +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")); + object = c1.create(); + QVERIFY(object != 0); + QVERIFY(object->property("sourceComponentAlias").value() != 0); + QCOMPARE(object->property("aliasIsUndefined"), QVariant(false)); + QMetaObject::invokeMethod(object, "resetAliased"); + QVERIFY(object->property("sourceComponentAlias").value() == 0); + QCOMPARE(object->property("aliasIsUndefined"), QVariant(true)); + delete object; + + // test that a manual write (of undefined) to a resettable alias property succeeds + QDeclarativeComponent c2(&engine, TEST_FILE("aliasreset/aliasPropertyReset.2.qml")); + object = c2.create(); + QVERIFY(object != 0); + QVERIFY(object->property("sourceComponentAlias").value() != 0); + QCOMPARE(object->property("loaderSourceComponentIsUndefined"), QVariant(false)); + QMetaObject::invokeMethod(object, "resetAlias"); + QVERIFY(object->property("sourceComponentAlias").value() == 0); + QCOMPARE(object->property("loaderSourceComponentIsUndefined"), QVariant(true)); + delete object; + + // test that an alias to a bound property works correctly + QDeclarativeComponent c3(&engine, TEST_FILE("aliasreset/aliasPropertyReset.3.qml")); + object = c3.create(); + QVERIFY(object != 0); + QVERIFY(object->property("sourceComponentAlias").value() != 0); + QCOMPARE(object->property("loaderOneSourceComponentIsUndefined"), QVariant(false)); + QCOMPARE(object->property("loaderTwoSourceComponentIsUndefined"), QVariant(false)); + QMetaObject::invokeMethod(object, "resetAlias"); + QVERIFY(object->property("sourceComponentAlias").value() == 0); + QCOMPARE(object->property("loaderOneSourceComponentIsUndefined"), QVariant(true)); + QCOMPARE(object->property("loaderTwoSourceComponentIsUndefined"), QVariant(false)); + delete object; + + // 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")); + object = c4.create(); + QVERIFY(object != 0); + QVERIFY(object->property("sourceComponentAlias").value() != 0); + QObject *loader = object->findChild("loader"); + QVERIFY(loader != 0); + delete loader; + QVERIFY(object->property("sourceComponentAlias").value() == 0); // deletion should have caused value unset. + QMetaObject::invokeMethod(object, "resetAlias"); // shouldn't crash. + QVERIFY(object->property("sourceComponentAlias").value() == 0); + QMetaObject::invokeMethod(object, "setAlias"); // shouldn't crash, and shouldn't change value (since it's no longer referencing anything). + QVERIFY(object->property("sourceComponentAlias").value() == 0); + delete object; + + // test that binding an alias property to an undefined value works correctly + QDeclarativeComponent c5(&engine, TEST_FILE("aliasreset/aliasPropertyReset.5.qml")); + object = c5.create(); + QVERIFY(object != 0); + QVERIFY(object->property("sourceComponentAlias").value() == 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"); + QString warning1 = url.toString() + QLatin1String(":15: Error: Cannot assign [undefined] to int"); + QDeclarativeComponent e1(&engine, url); + object = e1.create(); + QVERIFY(object != 0); + QCOMPARE(object->property("intAlias").value(), 12); + QCOMPARE(object->property("aliasedIntIsUndefined"), QVariant(false)); + QTest::ignoreMessage(QtWarningMsg, warning1.toLatin1().constData()); + QMetaObject::invokeMethod(object, "resetAlias"); + QCOMPARE(object->property("intAlias").value(), 12); + QCOMPARE(object->property("aliasedIntIsUndefined"), QVariant(false)); + delete object; +} + void tst_qdeclarativeecmascript::dynamicCreation_data() { QTest::addColumn("method"); -- cgit v1.2.3