aboutsummaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorAlan Alpert <aalpert@blackberry.com>2013-08-21 13:21:03 -0700
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-08-22 21:12:58 +0200
commitfac5337abfef36c631fe73152157446aae0ea3ea (patch)
treea54f9cd915cf480487359ffb7ad86d65f2ddeb5e /tests
parentda91b1c7312379ee18118059ee03faaf147a7d17 (diff)
Don't crash with deferred properties
There are cases where a qmlExecuteDeferred(o) can be postponed until the context of o is being destroyed, at which point it's too late to create an object in that context. Task-number: QTBUG-33112 Change-Id: I7f981b5e34e3cb8a52c00de4742a7242d7e4df54 Reviewed-by: Christopher Adams <chris.adams@jollamobile.com> Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Diffstat (limited to 'tests')
-rw-r--r--tests/auto/qml/qqmlecmascript/data/deferredPropertiesInDestruction.qml6
-rw-r--r--tests/auto/qml/qqmlecmascript/testtypes.cpp1
-rw-r--r--tests/auto/qml/qqmlecmascript/testtypes.h28
-rw-r--r--tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp14
4 files changed, 49 insertions, 0 deletions
diff --git a/tests/auto/qml/qqmlecmascript/data/deferredPropertiesInDestruction.qml b/tests/auto/qml/qqmlecmascript/data/deferredPropertiesInDestruction.qml
new file mode 100644
index 0000000000..d636dffccc
--- /dev/null
+++ b/tests/auto/qml/qqmlecmascript/data/deferredPropertiesInDestruction.qml
@@ -0,0 +1,6 @@
+import Qt.test 1.0
+
+MyVeryDeferredObject {
+ id: root
+ objectProperty: MyQmlObject { }
+}
diff --git a/tests/auto/qml/qqmlecmascript/testtypes.cpp b/tests/auto/qml/qqmlecmascript/testtypes.cpp
index 64aac83c02..919e06d7ee 100644
--- a/tests/auto/qml/qqmlecmascript/testtypes.cpp
+++ b/tests/auto/qml/qqmlecmascript/testtypes.cpp
@@ -252,6 +252,7 @@ void registerTypes()
qmlRegisterType<MyQmlObject>("Qt.test", 1,0, "MyQmlObjectAlias");
qmlRegisterType<MyQmlObject>("Qt.test", 1,0, "MyQmlObject");
qmlRegisterType<MyDeferredObject>("Qt.test", 1,0, "MyDeferredObject");
+ qmlRegisterType<MyVeryDeferredObject>("Qt.test", 1,0, "MyVeryDeferredObject");
qmlRegisterType<MyQmlContainer>("Qt.test", 1,0, "MyQmlContainer");
qmlRegisterExtendedType<MyBaseExtendedObject, BaseExtensionObject>("Qt.test", 1,0, "MyBaseExtendedObject");
qmlRegisterExtendedType<MyExtendedObject, ExtensionObject>("Qt.test", 1,0, "MyExtendedObject");
diff --git a/tests/auto/qml/qqmlecmascript/testtypes.h b/tests/auto/qml/qqmlecmascript/testtypes.h
index 4d30816b0a..2aa5fce534 100644
--- a/tests/auto/qml/qqmlecmascript/testtypes.h
+++ b/tests/auto/qml/qqmlecmascript/testtypes.h
@@ -376,6 +376,34 @@ private:
QObject *m_object2;
};
+class MyVeryDeferredObject : public QObject
+{
+ Q_OBJECT
+ //For inDestruction test
+ Q_PROPERTY(int value READ value WRITE setValue NOTIFY valueChanged)
+ Q_PROPERTY(QObject *objectProperty READ objectProperty WRITE setObjectProperty)
+ Q_CLASSINFO("DeferredPropertyNames", "objectProperty")
+
+public:
+ MyVeryDeferredObject() : m_value(0), m_object(0) {}
+ ~MyVeryDeferredObject() {
+ qmlExecuteDeferred(this); //Not a realistic case, see QTBUG-33112 to see how this could happen in practice
+ }
+
+ int value() const { return m_value; }
+ void setValue(int v) { m_value = v; emit valueChanged(); }
+
+ QObject *objectProperty() const { return m_object; }
+ void setObjectProperty(QObject *obj) { m_object = obj; }
+
+signals:
+ void valueChanged();
+
+private:
+ int m_value;
+ QObject *m_object;
+};
+
class MyBaseExtendedObject : public QObject
{
Q_OBJECT
diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
index 0db8351135..166e6cb83d 100644
--- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
+++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
@@ -102,6 +102,7 @@ private slots:
void deferredProperties();
void deferredPropertiesErrors();
void deferredPropertiesInComponents();
+ void deferredPropertiesInDestruction();
void extensionObjects();
void overrideExtensionProperties();
void attachedProperties();
@@ -924,6 +925,19 @@ void tst_qqmlecmascript::deferredPropertiesInComponents()
delete object;
}
+void tst_qqmlecmascript::deferredPropertiesInDestruction()
+{
+ //Test that the component does not get created at all if creation is deferred until the containing context is destroyed
+ //Very specific operation ordering is needed for this to occur, currently accessing object from object destructor.
+ //
+ QQmlComponent component(&engine, testFileUrl("deferredPropertiesInDestruction.qml"));
+ QObject *object = component.create();
+ if (!object)
+ qDebug() << component.errorString();
+ QVERIFY(object != 0);
+ delete object; //QTBUG-33112 was that this used to cause a crash
+}
+
void tst_qqmlecmascript::extensionObjects()
{
QQmlComponent component(&engine, testFileUrl("extensionObjects.qml"));