aboutsummaryrefslogtreecommitdiffstats
path: root/tests/auto/declarative/qdeclarativecontext/tst_qdeclarativecontext.cpp
diff options
context:
space:
mode:
authorAaron Kennedy <aaron.kennedy@nokia.com>2011-11-02 17:08:16 +0000
committerQt by Nokia <qt-info@nokia.com>2011-11-04 13:00:47 +0100
commit4a8871d3fe6c9fe16752697abf95d3a7b8fba7b7 (patch)
treee7c7d5dcefe2bdebe6d7aeb58ffcda6f5572c4c8 /tests/auto/declarative/qdeclarativecontext/tst_qdeclarativecontext.cpp
parentf9261feb16d02e985982dd46783ea54c2cfce91b (diff)
Don't crash if contexts are deleted during refreshExpressions
Change-Id: I23b59d33c07b017ef7355a7fe4a728d84c5d7eaa Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
Diffstat (limited to 'tests/auto/declarative/qdeclarativecontext/tst_qdeclarativecontext.cpp')
-rw-r--r--tests/auto/declarative/qdeclarativecontext/tst_qdeclarativecontext.cpp120
1 files changed, 120 insertions, 0 deletions
diff --git a/tests/auto/declarative/qdeclarativecontext/tst_qdeclarativecontext.cpp b/tests/auto/declarative/qdeclarativecontext/tst_qdeclarativecontext.cpp
index c241acac05..dee2cd9805 100644
--- a/tests/auto/declarative/qdeclarativecontext/tst_qdeclarativecontext.cpp
+++ b/tests/auto/declarative/qdeclarativecontext/tst_qdeclarativecontext.cpp
@@ -45,6 +45,18 @@
#include <QDeclarativeContext>
#include <QDeclarativeComponent>
#include <QDeclarativeExpression>
+#include <private/qdeclarativecontext_p.h>
+#include "../shared/util.h"
+
+inline QUrl TEST_FILE(const QString &filename)
+{
+ return QUrl::fromLocalFile(TESTDATA(filename));
+}
+
+inline QUrl TEST_FILE(const char *filename)
+{
+ return TEST_FILE(QLatin1String(filename));
+}
class tst_qdeclarativecontext : public QObject
{
@@ -64,6 +76,9 @@ private slots:
void readOnlyContexts();
void nameForObject();
+ void refreshExpressions();
+ void refreshExpressionsCrash();
+
private:
QDeclarativeEngine engine;
};
@@ -490,6 +505,111 @@ void tst_qdeclarativecontext::nameForObject()
delete o;
}
+class DeleteCommand : public QObject
+{
+Q_OBJECT
+public:
+ DeleteCommand() : object(0) {}
+
+ QObject *object;
+
+public slots:
+ void doCommand() { if (object) delete object; object = 0; }
+};
+
+// Calling refresh expressions would crash if an expression or context was deleted during
+// the refreshing
+void tst_qdeclarativecontext::refreshExpressionsCrash()
+{
+ {
+ QDeclarativeEngine engine;
+
+ DeleteCommand command;
+ engine.rootContext()->setContextProperty("deleteCommand", &command);
+ // We use a fresh context here to bypass any root-context optimizations in
+ // the engine
+ QDeclarativeContext ctxt(engine.rootContext());
+
+ QDeclarativeComponent component(&engine);
+ component.setData("import QtQuick 2.0; QtObject { property var binding: deleteCommand.doCommand() }", QUrl());
+ QVERIFY(component.isReady());
+
+ QObject *o1 = component.create(&ctxt);
+ QObject *o2 = component.create(&ctxt);
+
+ command.object = o2;
+
+ QDeclarativeContextData::get(&ctxt)->refreshExpressions();
+
+ delete o1;
+ }
+ {
+ QDeclarativeEngine engine;
+
+ DeleteCommand command;
+ engine.rootContext()->setContextProperty("deleteCommand", &command);
+ // We use a fresh context here to bypass any root-context optimizations in
+ // the engine
+ QDeclarativeContext ctxt(engine.rootContext());
+
+ QDeclarativeComponent component(&engine);
+ component.setData("import QtQuick 2.0; QtObject { property var binding: deleteCommand.doCommand() }", QUrl());
+ QVERIFY(component.isReady());
+
+ QObject *o1 = component.create(&ctxt);
+ QObject *o2 = component.create(&ctxt);
+
+ command.object = o1;
+
+ QDeclarativeContextData::get(&ctxt)->refreshExpressions();
+
+ delete o2;
+ }
+}
+
+class CountCommand : public QObject
+{
+Q_OBJECT
+public:
+ CountCommand() : count(0) {}
+
+ int count;
+
+public slots:
+ void doCommand() { ++count; }
+};
+
+
+// Test that calling refresh expressions causes all the expressions to refresh
+void tst_qdeclarativecontext::refreshExpressions()
+{
+ QDeclarativeEngine engine;
+ QDeclarativeComponent component(&engine, TEST_FILE("refreshExpressions.qml"));
+ QDeclarativeComponent component2(&engine, TEST_FILE("RefreshExpressionsType.qml"));
+
+ CountCommand command;
+ engine.rootContext()->setContextProperty("countCommand", &command);
+
+ // We use a fresh context here to bypass any root-context optimizations in
+ // the engine
+ QDeclarativeContext context(engine.rootContext());
+ QDeclarativeContext context2(&context);
+
+ QObject *o1 = component.create(&context);
+ QObject *o2 = component.create(&context2);
+ QObject *o3 = component2.create(&context);
+
+ QCOMPARE(command.count, 5);
+
+ QDeclarativeContextData::get(&context)->refreshExpressions();
+
+ QCOMPARE(command.count, 10);
+
+ delete o3;
+ delete o2;
+ delete o1;
+}
+
QTEST_MAIN(tst_qdeclarativecontext)
#include "tst_qdeclarativecontext.moc"