aboutsummaryrefslogtreecommitdiffstats
path: root/tests/auto/quick/qquickrepeater
diff options
context:
space:
mode:
authorErik Verbruggen <erik.verbruggen@qt.io>2018-03-20 11:11:02 +0100
committerSimon Hausmann <simon.hausmann@qt.io>2018-05-09 10:45:49 +0000
commit3b806a18cc665b5ae0e12d45fe170bfc3f00352a (patch)
tree1403138f7ef2d9cd832e21b9c09dca073b049db1 /tests/auto/quick/qquickrepeater
parenta393929fd149906596bd74480a561b986a87b35d (diff)
Fix crash when using repeaters with packages
When receiving the modelUpdated signal from the delegate model, the repeater - unlike other views - queries for the objects right away. That may result in instant incubation and when using Packages, we will end up delivering the initItem signal emission for the parts models via QQmlDelegateModelGroupPrivate::initPackage for _both_ repeaters immediately. For the first repeater that's expected, but for the second repeater that means initItem is received before modelUpdated was called. That is very confusing for the repeater as d->deletables is not set up yet. While it's possible to make the repeater more "robust" towards such behaving models, it seems cleaner to make the model behave well, by ensuring that we emit initItem after modelUpdated. Task-number: QTBUG-50349 Change-Id: Id2f3ba135e34d0111c8896bb4ecdfe51c8c649da Reviewed-by: Michael Brasser <michael.brasser@live.com> Reviewed-by: Erik Verbruggen <erik.verbruggen@qt.io>
Diffstat (limited to 'tests/auto/quick/qquickrepeater')
-rw-r--r--tests/auto/quick/qquickrepeater/data/package.qml35
-rw-r--r--tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp24
2 files changed, 59 insertions, 0 deletions
diff --git a/tests/auto/quick/qquickrepeater/data/package.qml b/tests/auto/quick/qquickrepeater/data/package.qml
new file mode 100644
index 0000000000..1f9eb0d970
--- /dev/null
+++ b/tests/auto/quick/qquickrepeater/data/package.qml
@@ -0,0 +1,35 @@
+import QtQuick 2.0
+import QtQml.Models 2.2
+import QtQuick.Window 2.0
+
+Window {
+ width: 300
+ height: 300
+ visible: true
+ DelegateModel {
+ id: mdl
+
+ model: 1
+ delegate: Package {
+ Item {
+ id: first
+ Package.name: "first"
+ objectName: "firstItem"
+ }
+ Item{
+ id: second
+ Package.name: "second"
+ objectName: "secondItem"
+ }
+ }
+ }
+
+ Repeater {
+ id: repeater1
+ model: mdl.parts.first
+ }
+ Repeater {
+ id: repeater2
+ model: mdl.parts.second
+ }
+}
diff --git a/tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp b/tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp
index 0499e2f9a6..791c3ae19a 100644
--- a/tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp
+++ b/tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp
@@ -76,6 +76,7 @@ private slots:
void stackingOrder();
void objectModel();
void QTBUG54859_asynchronousMove();
+ void package();
};
class TestObject : public QObject
@@ -1014,6 +1015,29 @@ void tst_QQuickRepeater::QTBUG54859_asynchronousMove()
QTRY_COMPARE(item->property("finished"), QVariant(true));
}
+void tst_QQuickRepeater::package()
+{
+ QQmlEngine engine;
+ QQmlComponent component(&engine, testFileUrl("package.qml"));
+
+ QScopedPointer<QObject>o(component.create()); // don't crash!
+ QVERIFY(o != nullptr);
+
+ {
+ QQuickRepeater *repeater1 = qobject_cast<QQuickRepeater*>(qmlContext(o.data())->contextProperty("repeater1").value<QObject*>());
+ QVERIFY(repeater1);
+ QCOMPARE(repeater1->count(), 1);
+ QCOMPARE(repeater1->itemAt(0)->objectName(), "firstItem");
+ }
+
+ {
+ QQuickRepeater *repeater2 = qobject_cast<QQuickRepeater*>(qmlContext(o.data())->contextProperty("repeater2").value<QObject*>());
+ QVERIFY(repeater2);
+ QCOMPARE(repeater2->count(), 1);
+ QCOMPARE(repeater2->itemAt(0)->objectName(), "secondItem");
+ }
+}
+
QTEST_MAIN(tst_QQuickRepeater)
#include "tst_qquickrepeater.moc"