aboutsummaryrefslogtreecommitdiffstats
path: root/tests/auto/qml/qqmlincubator
diff options
context:
space:
mode:
authorMichael Brasser <mbrasser@ford.com>2018-01-08 13:33:27 -0600
committerSimon Hausmann <simon.hausmann@qt.io>2018-10-26 05:20:41 +0000
commit475c74a9926efcd968572563e678988e53804603 (patch)
tree57675cdf22c34a098f82ecb54baf01be5dcbd810 /tests/auto/qml/qqmlincubator
parent33d85e20037e83d10b8ce66f8745f00d84baccd8 (diff)
Hold internal reference to incubator object while incubating
Task-number: QTBUG-53111 Change-Id: Ifaef6a855914d79155f8028b0de7ccca3c9a00f5 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'tests/auto/qml/qqmlincubator')
-rw-r--r--tests/auto/qml/qqmlincubator/data/garbageCollection.qml19
-rw-r--r--tests/auto/qml/qqmlincubator/tst_qqmlincubator.cpp30
2 files changed, 49 insertions, 0 deletions
diff --git a/tests/auto/qml/qqmlincubator/data/garbageCollection.qml b/tests/auto/qml/qqmlincubator/data/garbageCollection.qml
new file mode 100644
index 0000000000..6866a02a00
--- /dev/null
+++ b/tests/auto/qml/qqmlincubator/data/garbageCollection.qml
@@ -0,0 +1,19 @@
+import QtQuick 2.0
+
+QtObject {
+ id: root
+
+ property var incubator
+
+ function getAndClearIncubator() {
+ var result = incubator
+ incubator = null
+ return result
+ }
+
+ Component.onCompleted: {
+ var c = Qt.createComponent("statusChanged.qml"); // use existing simple type for convenience
+ var incubator = c.incubateObject(root);
+ incubator.onStatusChanged = function(status) { if (status === 1) root.incubator = incubator }
+ }
+}
diff --git a/tests/auto/qml/qqmlincubator/tst_qqmlincubator.cpp b/tests/auto/qml/qqmlincubator/tst_qqmlincubator.cpp
index 8f0e04e12e..8e25079703 100644
--- a/tests/auto/qml/qqmlincubator/tst_qqmlincubator.cpp
+++ b/tests/auto/qml/qqmlincubator/tst_qqmlincubator.cpp
@@ -39,6 +39,7 @@
#include <QQmlComponent>
#include <QQmlIncubator>
#include "../../shared/util.h"
+#include <private/qjsvalue_p.h>
#include <private/qqmlincubator_p.h>
#include <private/qqmlobjectcreator_p.h>
@@ -68,6 +69,7 @@ private slots:
void chainedAsynchronousClear();
void selfDelete();
void contextDelete();
+ void garbageCollection();
private:
QQmlIncubationController controller;
@@ -1144,6 +1146,34 @@ void tst_qqmlincubator::contextDelete()
}
}
+// QTBUG-53111
+void tst_qqmlincubator::garbageCollection()
+{
+ QQmlComponent component(&engine, testFileUrl("garbageCollection.qml"));
+ QScopedPointer<QObject> obj(component.create());
+
+ engine.collectGarbage();
+
+ bool b = true;
+ controller.incubateWhile(&b);
+
+ // verify incubation completed (the incubator was not prematurely collected)
+ QVariant incubatorVariant;
+ QMetaObject::invokeMethod(obj.data(), "getAndClearIncubator", Q_RETURN_ARG(QVariant, incubatorVariant));
+ QJSValue strongRef = incubatorVariant.value<QJSValue>();
+ QVERIFY(!strongRef.isNull() && !strongRef.isUndefined());
+
+ // turn the last strong reference to the incubator into a weak one and collect
+ QV4::WeakValue weakIncubatorRef;
+ weakIncubatorRef.set(QQmlEnginePrivate::getV4Engine(&engine), *QJSValuePrivate::getValue(&strongRef));
+ strongRef = QJSValue();
+ incubatorVariant.clear();
+
+ // verify incubator is correctly collected now that incubation is complete and all references are gone
+ engine.collectGarbage();
+ QVERIFY(weakIncubatorRef.isNullOrUndefined());
+}
+
QTEST_MAIN(tst_qqmlincubator)
#include "tst_qqmlincubator.moc"