diff options
author | Aaron Kennedy <aaron.kennedy@nokia.com> | 2011-11-02 17:08:16 +0000 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2011-11-04 13:00:47 +0100 |
commit | 4a8871d3fe6c9fe16752697abf95d3a7b8fba7b7 (patch) | |
tree | e7c7d5dcefe2bdebe6d7aeb58ffcda6f5572c4c8 /tests/auto/declarative/qdeclarativecontext/tst_qdeclarativecontext.cpp | |
parent | f9261feb16d02e985982dd46783ea54c2cfce91b (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.cpp | 120 |
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" |