aboutsummaryrefslogtreecommitdiffstats
path: root/tests/auto/quick/qquickrepeater
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@qt.io>2018-05-07 11:45:09 +0200
committerSimon Hausmann <simon.hausmann@qt.io>2018-05-11 09:40:11 +0000
commit54da8f6c86aa9cba99bcedcd58b40db938b5af9e (patch)
treeaf3569a9da0063abcdd136e18702ea8042ee7f02 /tests/auto/quick/qquickrepeater
parent2dd213c34b5ba90cd811fada5b0c4494171abe46 (diff)
Fix JS ownership of model and delegate properties in QtQuick item views
When assigning a JS owned model or delegate to an item view, we must ensure that they stay alive as long as the item view. This happens easily for example when doing something like delegate: Qt.createComponent(...) This patch takes the minimally invasive approach by changing the QObject parent of such objects. Task-number: QTBUG-50319 Task-number: QTBUG-51620 Change-Id: Ie6384b8dd93dcdc62d49f64b38173b3fc4ffd3b3 Reviewed-by: J-P Nurmi <jpnurmi@qt.io>
Diffstat (limited to 'tests/auto/quick/qquickrepeater')
-rw-r--r--tests/auto/quick/qquickrepeater/data/ownership.qml4
-rw-r--r--tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp64
2 files changed, 68 insertions, 0 deletions
diff --git a/tests/auto/quick/qquickrepeater/data/ownership.qml b/tests/auto/quick/qquickrepeater/data/ownership.qml
new file mode 100644
index 0000000000..e13df3ab3a
--- /dev/null
+++ b/tests/auto/quick/qquickrepeater/data/ownership.qml
@@ -0,0 +1,4 @@
+import QtQuick 2.0
+
+Repeater {
+}
diff --git a/tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp b/tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp
index 791c3ae19a..0860956224 100644
--- a/tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp
+++ b/tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp
@@ -37,6 +37,7 @@
#include <QtQuick/private/qquicktext_p.h>
#include <QtQml/private/qqmllistmodel_p.h>
#include <QtQml/private/qqmlobjectmodel_p.h>
+#include <QtGui/qstandarditemmodel.h>
#include "../../shared/util.h"
#include "../shared/viewtestutil.h"
@@ -77,6 +78,7 @@ private slots:
void objectModel();
void QTBUG54859_asynchronousMove();
void package();
+ void ownership();
};
class TestObject : public QObject
@@ -1038,6 +1040,68 @@ void tst_QQuickRepeater::package()
}
}
+void tst_QQuickRepeater::ownership()
+{
+ QQmlEngine engine;
+
+ QQmlComponent component(&engine, testFileUrl("ownership.qml"));
+
+ QScopedPointer<QAbstractItemModel> aim(new QStandardItemModel);
+ QPointer<QAbstractItemModel> modelGuard(aim.data());
+ QQmlEngine::setObjectOwnership(aim.data(), QQmlEngine::JavaScriptOwnership);
+ {
+ QJSValue wrapper = engine.newQObject(aim.data());
+ }
+
+ QScopedPointer<QObject> repeater(component.create());
+ QVERIFY(!repeater.isNull());
+
+ QVERIFY(!QQmlData::keepAliveDuringGarbageCollection(aim.data()));
+
+ repeater->setProperty("model", QVariant::fromValue<QObject*>(aim.data()));
+
+ QVERIFY(!QQmlData::keepAliveDuringGarbageCollection(aim.data()));
+
+ engine.collectGarbage();
+ QCoreApplication::sendPostedEvents(nullptr, QEvent::DeferredDelete);
+
+ QVERIFY(modelGuard);
+
+ QScopedPointer<QQmlComponent> delegate(new QQmlComponent(&engine));
+ delegate->setData(QByteArrayLiteral("import QtQuick 2.0\nItem{}"), dataDirectoryUrl().resolved(QUrl("inline.qml")));
+ QPointer<QQmlComponent> delegateGuard(delegate.data());
+ QQmlEngine::setObjectOwnership(delegate.data(), QQmlEngine::JavaScriptOwnership);
+ {
+ QJSValue wrapper = engine.newQObject(delegate.data());
+ }
+
+ QVERIFY(!QQmlData::keepAliveDuringGarbageCollection(delegate.data()));
+
+ repeater->setProperty("delegate", QVariant::fromValue<QObject*>(delegate.data()));
+
+ QVERIFY(!QQmlData::keepAliveDuringGarbageCollection(delegate.data()));
+
+ engine.collectGarbage();
+ QCoreApplication::sendPostedEvents(nullptr, QEvent::DeferredDelete);
+
+ QVERIFY(delegateGuard);
+
+ repeater->setProperty("model", QVariant());
+ repeater->setProperty("delegate", QVariant());
+
+ QVERIFY(delegateGuard);
+ QVERIFY(modelGuard);
+
+ delegate.take();
+ aim.take();
+
+ engine.collectGarbage();
+ QCoreApplication::sendPostedEvents(nullptr, QEvent::DeferredDelete);
+
+ QVERIFY(!delegateGuard);
+ QVERIFY(!modelGuard);
+}
+
QTEST_MAIN(tst_QQuickRepeater)
#include "tst_qquickrepeater.moc"