summaryrefslogtreecommitdiffstats
path: root/tests/auto/declarative
diff options
context:
space:
mode:
authorThomas McGuire <thomas.mcguire.qnx@kdab.com>2012-08-15 09:50:47 +0200
committerQt by Nokia <qt-info@nokia.com>2012-09-14 13:33:45 +0200
commitecc432a5b7ae269220f86c6f0b3dd364f8643191 (patch)
tree66c9f0ecc280d9b71e677266f533ce9edafa0f94 /tests/auto/declarative
parent3414828ccc91da0d94f3b160f29766b9273357ad (diff)
Delete JS-owned QML objects right away in the engine dtor.
This prevents memory leaks when the engine is destroyed after exec() has already finished. In most cases this happens during application shutdown, at which point the event loop is never entered again. Task-number: QTBUG-20377 Change-Id: I65564ed3e56314d656d92fd66f11ae67d4eb932b Reviewed-by: Jędrzej Nowacki <jedrzej.nowacki@nokia.com> Reviewed-by: Lars Knoll <lars.knoll@nokia.com>
Diffstat (limited to 'tests/auto/declarative')
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/jsOwnedObjectsDeletedOnEngineDestroy.qml6
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/testtypes.h21
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp36
3 files changed, 62 insertions, 1 deletions
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/jsOwnedObjectsDeletedOnEngineDestroy.qml b/tests/auto/declarative/qdeclarativeecmascript/data/jsOwnedObjectsDeletedOnEngineDestroy.qml
new file mode 100644
index 0000000000..da1b682d1e
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/jsOwnedObjectsDeletedOnEngineDestroy.qml
@@ -0,0 +1,6 @@
+import QtQuick 1.0
+
+Item {
+ property variant jsOwnedObject1: deleteObject.object1()
+ property variant jsOwnedObject2: deleteObject.object2
+}
diff --git a/tests/auto/declarative/qdeclarativeecmascript/testtypes.h b/tests/auto/declarative/qdeclarativeecmascript/testtypes.h
index 19505e1458..3d0d37fba9 100644
--- a/tests/auto/declarative/qdeclarativeecmascript/testtypes.h
+++ b/tests/auto/declarative/qdeclarativeecmascript/testtypes.h
@@ -903,6 +903,27 @@ protected:
qreal m_p4;
};
+class MyDeleteObject : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QObject *object2 READ object2 NOTIFY object2Changed)
+
+public:
+ MyDeleteObject() : m_object1(0), m_object2(0) {}
+
+ Q_INVOKABLE QObject *object1() const { return m_object1; }
+ Q_INVOKABLE QObject *object2() const { return m_object2; }
+ void setObject1(QObject *object) { m_object1 = object; }
+ void setObject2(QObject *object) { m_object2 = object; emit object2Changed(); }
+
+signals:
+ void object2Changed();
+
+private:
+ QObject *m_object1;
+ QObject *m_object2;
+};
+
QML_DECLARE_TYPE(MyRevisionedBaseClassRegistered)
QML_DECLARE_TYPE(MyRevisionedBaseClassUnregistered)
QML_DECLARE_TYPE(MyRevisionedClass)
diff --git a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp
index 1c54494325..188cf1b52a 100644
--- a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp
+++ b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp
@@ -48,6 +48,7 @@
#include <QtDeclarative/private/qdeclarativeguard_p.h>
#include <QtCore/qdir.h>
#include <QtCore/qnumeric.h>
+#include <QtTest/qsignalspy.h>
#include <private/qdeclarativeengine_p.h>
#include <private/qdeclarativeglobalscriptclass_p.h>
#include <private/qscriptdeclarativeclass_p.h>
@@ -178,6 +179,7 @@ private slots:
void pushCleanContext();
void realToInt();
void qtbug_20648();
+ void jsOwnedObjectsDeletedOnEngineDestroy();
void include();
@@ -1388,7 +1390,7 @@ void tst_qdeclarativeecmascript::callQtInvokables()
QDeclarativeEngine qmlengine;
QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(&qmlengine);
- QScriptEngine *engine = &ep->scriptEngine;
+ QScriptEngine *engine = ep->scriptEngine;
QStringList names; QList<QScriptValue> values;
names << QLatin1String("object"); values << ep->objectClass->newQObject(&o);
@@ -3100,6 +3102,38 @@ void tst_qdeclarativeecmascript::qtbug_20648()
delete o;
}
+void tst_qdeclarativeecmascript::jsOwnedObjectsDeletedOnEngineDestroy()
+{
+ QDeclarativeEngine *myEngine = new QDeclarativeEngine;
+
+ MyDeleteObject deleteObject;
+ deleteObject.setObjectName("deleteObject");
+ QObject * const object1 = new QObject;
+ QObject * const object2 = new QObject;
+ object1->setObjectName("object1");
+ object2->setObjectName("object2");
+ deleteObject.setObject1(object1);
+ deleteObject.setObject2(object2);
+
+ // Objects returned by function calls get marked as destructible, but objects returned by
+ // property getters do not - therefore we explicitly set the object as destructible.
+ QDeclarativeEngine::setObjectOwnership(object2, QDeclarativeEngine::JavaScriptOwnership);
+
+ myEngine->rootContext()->setContextProperty("deleteObject", &deleteObject);
+ QDeclarativeComponent component(myEngine, TEST_FILE("jsOwnedObjectsDeletedOnEngineDestroy.qml"));
+ QObject *object = component.create();
+ QVERIFY(object);
+
+ // Destroying the engine should delete all JS owned QObjects
+ QSignalSpy spy1(object1, SIGNAL(destroyed()));
+ QSignalSpy spy2(object2, SIGNAL(destroyed()));
+ delete myEngine;
+ QCOMPARE(spy1.count(), 1);
+ QCOMPARE(spy2.count(), 1);
+
+ delete object;
+}
+
QTEST_MAIN(tst_qdeclarativeecmascript)
#include "tst_qdeclarativeecmascript.moc"