From fa3dcc0efb2696612bf9db54a7ed4e26a2cf4765 Mon Sep 17 00:00:00 2001 From: Matthew Vogt Date: Wed, 18 Jul 2012 10:16:12 +1000 Subject: Update var property to null on object deletion When a var property contains a pointer to a QObject-derived instance, ensure that object deletion causes the property to be updated. Task-number: QTBUG-26542 Change-Id: I67a59ffd7f09063328d45dc84889add55a5428e4 Reviewed-by: Martin Jones --- .../qqmllanguage/data/objectDeletionNotify.1.qml | 37 +++++++++++++++++ .../qqmllanguage/data/objectDeletionNotify.2.qml | 37 +++++++++++++++++ .../qqmllanguage/data/objectDeletionNotify.3.qml | 37 +++++++++++++++++ .../qqmllanguage/data/objectDeletionNotify.4.qml | 48 ++++++++++++++++++++++ tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp | 34 +++++++++++++++ 5 files changed, 193 insertions(+) create mode 100644 tests/auto/qml/qqmllanguage/data/objectDeletionNotify.1.qml create mode 100644 tests/auto/qml/qqmllanguage/data/objectDeletionNotify.2.qml create mode 100644 tests/auto/qml/qqmllanguage/data/objectDeletionNotify.3.qml create mode 100644 tests/auto/qml/qqmllanguage/data/objectDeletionNotify.4.qml (limited to 'tests/auto/qml/qqmllanguage') diff --git a/tests/auto/qml/qqmllanguage/data/objectDeletionNotify.1.qml b/tests/auto/qml/qqmllanguage/data/objectDeletionNotify.1.qml new file mode 100644 index 0000000000..acd5463a3c --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/objectDeletionNotify.1.qml @@ -0,0 +1,37 @@ +import QtQuick 2.0 + +Item { + property bool success: false + + Component { + id: internal + + Item { + } + } + + property bool expectNull: null + + function setExpectNull(b) { + success = false; + expectNull = b; + } + + property QtObject obj: null + onObjChanged: success = (expectNull ? obj == null : obj != null) + + Component.onCompleted: { + setExpectNull(false) + obj = internal.createObject(null, {}) + if (!success) return + + // Replace with a different object + setExpectNull(false) + obj = internal.createObject(null, {}) + } + + function destroyObject() { + setExpectNull(true) + obj.destroy(); + } +} diff --git a/tests/auto/qml/qqmllanguage/data/objectDeletionNotify.2.qml b/tests/auto/qml/qqmllanguage/data/objectDeletionNotify.2.qml new file mode 100644 index 0000000000..ed0e0d10f0 --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/objectDeletionNotify.2.qml @@ -0,0 +1,37 @@ +import QtQuick 2.0 + +Item { + property bool success: false + + Component { + id: internal + + Item { + } + } + + property bool expectNull: null + + function setExpectNull(b) { + success = false; + expectNull = b; + } + + property variant obj: null + onObjChanged: success = (expectNull ? obj == null : obj != null) + + Component.onCompleted: { + setExpectNull(false) + obj = internal.createObject(null, {}) + if (!success) return + + // Replace with a different object + setExpectNull(false) + obj = internal.createObject(null, {}) + } + + function destroyObject() { + setExpectNull(true) + obj.destroy(); + } +} diff --git a/tests/auto/qml/qqmllanguage/data/objectDeletionNotify.3.qml b/tests/auto/qml/qqmllanguage/data/objectDeletionNotify.3.qml new file mode 100644 index 0000000000..f5e94ba715 --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/objectDeletionNotify.3.qml @@ -0,0 +1,37 @@ +import QtQuick 2.0 + +Item { + property bool success: false + + Component { + id: internal + + Item { + } + } + + property bool expectNull: null + + function setExpectNull(b) { + success = false; + expectNull = b; + } + + property var obj: null + onObjChanged: success = (expectNull ? obj == null : obj != null) + + Component.onCompleted: { + setExpectNull(false) + obj = internal.createObject(null, {}) + if (!success) return + + // Replace with a different object + setExpectNull(false) + obj = internal.createObject(null, {}) + } + + function destroyObject() { + setExpectNull(true) + obj.destroy(); + } +} diff --git a/tests/auto/qml/qqmllanguage/data/objectDeletionNotify.4.qml b/tests/auto/qml/qqmllanguage/data/objectDeletionNotify.4.qml new file mode 100644 index 0000000000..ccfda01644 --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/objectDeletionNotify.4.qml @@ -0,0 +1,48 @@ +import QtQuick 2.0 + +Item { + property bool success: false + + Component { + id: internal + + Item { + } + } + + property var expectNull: null + + function setExpectNull(b) { + success = false; + expectNull = b; + } + + function setExpectNoChange() { + success = true; + expectNull = null; + } + + property var obj: null + onObjChanged: success = (expectNull == null) ? false : (expectNull ? obj == null : obj != null) + + property var temp: null + + Component.onCompleted: { + // Set obj to contain an object + setExpectNull(false) + obj = internal.createObject(null, {}) + if (!success) return + + // Use temp variable to keep object reference alive + temp = obj + + // Change obj to contain a string + setExpectNull(false) + obj = 'hello' + } + + function destroyObject() { + setExpectNoChange() + temp.destroy(); + } +} diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp index 2c9593bd01..316d7e28a7 100644 --- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp +++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp @@ -179,6 +179,9 @@ private slots: void literals_data(); void literals(); + void objectDeletionNotify_data(); + void objectDeletionNotify(); + private: QQmlEngine engine; QStringList defaultImportPathList; @@ -2987,6 +2990,37 @@ void tst_qqmllanguage::literals() delete object; } +void tst_qqmllanguage::objectDeletionNotify_data() +{ + QTest::addColumn("file"); + + QTest::newRow("property QtObject") << "objectDeletionNotify.1.qml"; + QTest::newRow("property variant") << "objectDeletionNotify.2.qml"; + QTest::newRow("property var") << "objectDeletionNotify.3.qml"; + QTest::newRow("property var guard removed") << "objectDeletionNotify.4.qml"; +} + +void tst_qqmllanguage::objectDeletionNotify() +{ + QFETCH(QString, file); + + QQmlComponent component(&engine, testFile(file)); + + QObject *object = component.create(); + QVERIFY(object != 0); + QCOMPARE(object->property("success").toBool(), true); + + QMetaObject::invokeMethod(object, "destroyObject"); + + // Process the deletion event + QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); + QCoreApplication::processEvents(); + + QCOMPARE(object->property("success").toBool(), true); + + delete object; +} + QTEST_MAIN(tst_qqmllanguage) #include "tst_qqmllanguage.moc" -- cgit v1.2.3