From 3b6eeee177b64eebe240d51be0c7bb5f031471d8 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Thu, 14 Sep 2017 13:24:42 +0200 Subject: Fix execution of deferred properties When deferred properties were assigned in multiple contexts, only the outermost context was executed. Any deferred property assignments in other inner contexts were never executed. Collect the deferred data to a container to be able to execute them all. Task-number: QTBUG-63200 Change-Id: I88fab27c1f81b5188430ada086dcc19842507e99 Reviewed-by: Lars Knoll --- .../qml/qqmllanguage/data/MyDeferredProperties.qml | 19 +++++++++ .../qml/qqmllanguage/data/deferredProperties.qml | 19 +++++++++ tests/auto/qml/qqmllanguage/testtypes.cpp | 1 + tests/auto/qml/qqmllanguage/testtypes.h | 15 +++++++ tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp | 48 ++++++++++++++++++++++ 5 files changed, 102 insertions(+) create mode 100644 tests/auto/qml/qqmllanguage/data/MyDeferredProperties.qml create mode 100644 tests/auto/qml/qqmllanguage/data/deferredProperties.qml (limited to 'tests') diff --git a/tests/auto/qml/qqmllanguage/data/MyDeferredProperties.qml b/tests/auto/qml/qqmllanguage/data/MyDeferredProperties.qml new file mode 100644 index 0000000000..67e92e5a05 --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/MyDeferredProperties.qml @@ -0,0 +1,19 @@ +import QtQml 2.0 +import Test 1.0 +DeferredProperties { + groupProperty: QtObject { + objectName: "innerobj" + property bool wasCompleted: false + Component.onCompleted: wasCompleted = true + } + QtObject { + objectName: "innerlist1" + property bool wasCompleted: false + Component.onCompleted: wasCompleted = true + } + QtObject { + objectName: "innerlist2" + property bool wasCompleted: false + Component.onCompleted: wasCompleted = true + } +} diff --git a/tests/auto/qml/qqmllanguage/data/deferredProperties.qml b/tests/auto/qml/qqmllanguage/data/deferredProperties.qml new file mode 100644 index 0000000000..07b146967c --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/deferredProperties.qml @@ -0,0 +1,19 @@ +import QtQml 2.0 +import Test 1.0 +MyDeferredProperties { + groupProperty: QtObject { + objectName: "outerobj" + property bool wasCompleted: false + Component.onCompleted: wasCompleted = true + } + QtObject { + objectName: "outerlist1" + property bool wasCompleted: false + Component.onCompleted: wasCompleted = true + } + QtObject { + objectName: "outerlist2" + property bool wasCompleted: false + Component.onCompleted: wasCompleted = true + } +} diff --git a/tests/auto/qml/qqmllanguage/testtypes.cpp b/tests/auto/qml/qqmllanguage/testtypes.cpp index 72e06d26aa..d2240d25a9 100644 --- a/tests/auto/qml/qqmllanguage/testtypes.cpp +++ b/tests/auto/qml/qqmllanguage/testtypes.cpp @@ -105,6 +105,7 @@ void registerTypes() qmlRegisterType("Test", 1, 0, "MyArrayBufferTestClass"); qmlRegisterType("Test", 1, 0, "LazyDeferredSubObject"); + qmlRegisterType("Test", 1, 0, "DeferredProperties"); } QVariant myCustomVariantTypeConverter(const QString &data) diff --git a/tests/auto/qml/qqmllanguage/testtypes.h b/tests/auto/qml/qqmllanguage/testtypes.h index b0e677feb8..d9ddff20a7 100644 --- a/tests/auto/qml/qqmllanguage/testtypes.h +++ b/tests/auto/qml/qqmllanguage/testtypes.h @@ -1351,6 +1351,21 @@ private: QObject *obj; }; +class DeferredProperties : public QObject +{ + Q_OBJECT + Q_PROPERTY(QObject *groupProperty MEMBER m_group) + Q_PROPERTY(QQmlListProperty listProperty READ listProperty) + Q_CLASSINFO("DeferredPropertyNames", "groupProperty,listProperty") + Q_CLASSINFO("DefaultProperty", "listProperty") +public: + QQmlListProperty listProperty() { return QQmlListProperty(this, m_list); } + +private: + QObject *m_group = 0; + QObjectList m_list; +}; + void registerTypes(); #endif // TESTTYPES_H diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp index 30c34426af..f4d31d9e60 100644 --- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp +++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp @@ -248,6 +248,7 @@ private slots: void rootObjectInCreationNotForSubObjects(); void lazyDeferredSubObject(); + void deferredProperties(); void noChildEvents(); @@ -4258,6 +4259,53 @@ void tst_qqmllanguage::lazyDeferredSubObject() QCOMPARE(subObject->objectName(), QStringLiteral("custom")); } +// QTBUG-63200 +void tst_qqmllanguage::deferredProperties() +{ + QQmlComponent component(&engine, testFile("deferredProperties.qml")); + VERIFY_ERRORS(0); + QScopedPointer object(component.create()); + QVERIFY(!object.isNull()); + + QObject *innerObj = object->findChild(QStringLiteral("innerobj")); + QVERIFY(!innerObj); + + QObject *outerObj = object->findChild(QStringLiteral("outerobj")); + QVERIFY(!outerObj); + + QObject *groupProperty = object->property("groupProperty").value(); + QVERIFY(!groupProperty); + + QQmlListProperty listProperty = object->property("listProperty").value>(); + QCOMPARE(listProperty.count(&listProperty), 0); + + qmlExecuteDeferred(object.data()); + + innerObj = object->findChild(QStringLiteral("innerobj")); // MyDeferredListProperty.qml + QVERIFY(innerObj); + QCOMPARE(innerObj->property("wasCompleted"), QVariant(true)); + + outerObj = object->findChild(QStringLiteral("outerobj")); // deferredListProperty.qml + QVERIFY(outerObj); + QCOMPARE(outerObj->property("wasCompleted"), QVariant(true)); + + groupProperty = object->property("groupProperty").value(); + QCOMPARE(groupProperty, outerObj); + + listProperty = object->property("listProperty").value>(); + QCOMPARE(listProperty.count(&listProperty), 4); + + QCOMPARE(listProperty.at(&listProperty, 0)->objectName(), QStringLiteral("innerlist1")); // MyDeferredListProperty.qml + QCOMPARE(listProperty.at(&listProperty, 0)->property("wasCompleted"), QVariant(true)); + QCOMPARE(listProperty.at(&listProperty, 1)->objectName(), QStringLiteral("innerlist2")); // MyDeferredListProperty.qml + QCOMPARE(listProperty.at(&listProperty, 1)->property("wasCompleted"), QVariant(true)); + + QCOMPARE(listProperty.at(&listProperty, 2)->objectName(), QStringLiteral("outerlist1")); // deferredListProperty.qml + QCOMPARE(listProperty.at(&listProperty, 2)->property("wasCompleted"), QVariant(true)); + QCOMPARE(listProperty.at(&listProperty, 3)->objectName(), QStringLiteral("outerlist2")); // deferredListProperty.qml + QCOMPARE(listProperty.at(&listProperty, 3)->property("wasCompleted"), QVariant(true)); +} + void tst_qqmllanguage::noChildEvents() { QQmlComponent component(&engine); -- cgit v1.2.3