aboutsummaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorJoni Poikelin <joni.poikelin@qt.io>2016-07-20 10:21:08 +0300
committerJoni Poikelin <joni.poikelin@qt.io>2017-11-28 05:09:01 +0000
commit323fd0037c8d3e016c66fea024b57b11763624ed (patch)
treeb23901e50c4834149a7c14d40ac02a27162666ba /tests
parent22858d41a5351e1bc3ffd9778af77643d90e395f (diff)
Fix crash when moving items during asynchronous creation
In complicated cases where the model moves rows around while the view is running slow (perhaps during high CPU load), there were cases when Repeater would call movedItem->stackBefore(deleteableItem), but deleteable items can be null, so there was often an error QQuickItem::stackBefore: Cannot stack before 0x0, which must be a sibling and occasionally a crash. Now we check both the callee and the parameter to stackBefore to make sure neither of them are null. Task-number: QTBUG-54859 Change-Id: I45a8b2939c16b9bbe3a802ddd348dc55f51061a7 Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
Diffstat (limited to 'tests')
-rw-r--r--tests/auto/quick/qquickrepeater/data/asynchronousMove.qml51
-rw-r--r--tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp25
2 files changed, 76 insertions, 0 deletions
diff --git a/tests/auto/quick/qquickrepeater/data/asynchronousMove.qml b/tests/auto/quick/qquickrepeater/data/asynchronousMove.qml
new file mode 100644
index 0000000000..02499c8531
--- /dev/null
+++ b/tests/auto/quick/qquickrepeater/data/asynchronousMove.qml
@@ -0,0 +1,51 @@
+import QtQuick 2.3
+import QtQuick.Window 2.2
+
+Item {
+ property bool finished: loader.status === Loader.Ready && loader.progress === 1
+
+ ListModel {
+ id: listModel
+ ListElement { i:0 }
+ ListElement { i:1 }
+ ListElement { i:2 }
+ ListElement { i:3 }
+ }
+
+ Timer {
+ running: true
+ interval: 1
+ repeat: count < 5
+ property int count : 0
+
+ onTriggered: {
+ listModel.move(listModel.count - 1, listModel.count - 2, 1)
+ ++count
+ }
+ }
+
+ Loader {
+ id: loader
+ asynchronous: true
+ sourceComponent: Row {
+ spacing: 4
+ Repeater {
+ model: listModel
+ delegate: Column {
+ spacing: 4
+ Repeater {
+ model: 4
+ delegate: Rectangle {
+ width: 30
+ height: 30
+ color: "blue"
+ Component.onCompleted: {
+ ctrl.wait()
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp b/tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp
index f7b04e9a30..3519c53cb7 100644
--- a/tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp
+++ b/tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp
@@ -75,6 +75,7 @@ private slots:
void destroyCount();
void stackingOrder();
void objectModel();
+ void QTBUG54859_asynchronousMove();
};
class TestObject : public QObject
@@ -989,6 +990,30 @@ void tst_QQuickRepeater::objectModel()
delete positioner;
}
+class Ctrl : public QObject
+{
+ Q_OBJECT
+public:
+
+ Q_INVOKABLE void wait()
+ {
+ QTest::qWait(200);
+ }
+};
+
+void tst_QQuickRepeater::QTBUG54859_asynchronousMove()
+{
+ Ctrl ctrl;
+ QQuickView* view = createView();
+ view->rootContext()->setContextProperty("ctrl", &ctrl);
+ view->setSource(testFileUrl("asynchronousMove.qml"));
+ view->show();
+ QQuickItem* item = view->rootObject();
+
+
+ QTRY_COMPARE(item->property("finished"), QVariant(true));
+}
+
QTEST_MAIN(tst_QQuickRepeater)
#include "tst_qquickrepeater.moc"