diff options
author | Matthew Vogt <matthew.vogt@nokia.com> | 2012-02-16 14:43:03 +1000 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2012-02-24 04:51:31 +0100 |
commit | b855240b782395f94315f43ea3e7e182299fac48 (patch) | |
tree | bc594c04449be8cd14cd0ab0bb72dafc2be0ffb2 /tests/auto/qml/qqmlcontext | |
parent | 6a42a6e0a9a1abdda0d07a5a20b4ac7e45348684 (diff) |
Rename QDeclarative symbols to QQuick and QQml
Symbols beginning with QDeclarative are already exported
by the quick1 module.
Users can apply the bin/rename-qtdeclarative-symbols.sh
script to modify client code using the previous names of the
renamed symbols.
Task-number: QTBUG-23737
Change-Id: Ifaa482663767634931e8711a8e9bf6e404859e66
Reviewed-by: Martin Jones <martin.jones@nokia.com>
Diffstat (limited to 'tests/auto/qml/qqmlcontext')
7 files changed, 702 insertions, 0 deletions
diff --git a/tests/auto/qml/qqmlcontext/data/Object_22535.qml b/tests/auto/qml/qqmlcontext/data/Object_22535.qml new file mode 100644 index 0000000000..294c744317 --- /dev/null +++ b/tests/auto/qml/qqmlcontext/data/Object_22535.qml @@ -0,0 +1,8 @@ +import QtQuick 2.0 + +QtObject { + + function goodBye() + { + } +} diff --git a/tests/auto/qml/qqmlcontext/data/RefreshExpressionsType.qml b/tests/auto/qml/qqmlcontext/data/RefreshExpressionsType.qml new file mode 100644 index 0000000000..b7c3427c85 --- /dev/null +++ b/tests/auto/qml/qqmlcontext/data/RefreshExpressionsType.qml @@ -0,0 +1,5 @@ +import QtQuick 2.0 + +QtObject { + property var dummy: countCommand.doCommand(); +} diff --git a/tests/auto/qml/qqmlcontext/data/qtbug_22535.qml b/tests/auto/qml/qqmlcontext/data/qtbug_22535.qml new file mode 100644 index 0000000000..3553f6c03b --- /dev/null +++ b/tests/auto/qml/qqmlcontext/data/qtbug_22535.qml @@ -0,0 +1,10 @@ +import QtQuick 2.0 + +Rectangle { + width: 64 + height: 64 + + Object_22535 { id:o } + + Component.onDestruction: o.goodBye() +} diff --git a/tests/auto/qml/qqmlcontext/data/refreshExpressions.qml b/tests/auto/qml/qqmlcontext/data/refreshExpressions.qml new file mode 100644 index 0000000000..01e503f8dc --- /dev/null +++ b/tests/auto/qml/qqmlcontext/data/refreshExpressions.qml @@ -0,0 +1,6 @@ +import QtQuick 2.0 + +QtObject { + property variant v1: RefreshExpressionsType {} + property variant v2: RefreshExpressionsType {} +} diff --git a/tests/auto/qml/qqmlcontext/data/refreshExpressionsRootContext.qml b/tests/auto/qml/qqmlcontext/data/refreshExpressionsRootContext.qml new file mode 100644 index 0000000000..bd82cd9552 --- /dev/null +++ b/tests/auto/qml/qqmlcontext/data/refreshExpressionsRootContext.qml @@ -0,0 +1,6 @@ +import QtQuick 2.0 + +QtObject { + property var dummy: countCommand.doCommand(), unresolvedName +} + diff --git a/tests/auto/qml/qqmlcontext/qqmlcontext.pro b/tests/auto/qml/qqmlcontext/qqmlcontext.pro new file mode 100644 index 0000000000..9920766d61 --- /dev/null +++ b/tests/auto/qml/qqmlcontext/qqmlcontext.pro @@ -0,0 +1,15 @@ +CONFIG += testcase +TARGET = tst_qqmlcontext +SOURCES += tst_qqmlcontext.cpp + +include (../../shared/util.pri) + +macx:CONFIG -= app_bundle + +testDataFiles.files = data +testDataFiles.path = . +DEPLOYMENT += testDataFiles + +CONFIG += parallel_test + +QT += core-private gui-private qml-private testlib v8-private diff --git a/tests/auto/qml/qqmlcontext/tst_qqmlcontext.cpp b/tests/auto/qml/qqmlcontext/tst_qqmlcontext.cpp new file mode 100644 index 0000000000..6125362365 --- /dev/null +++ b/tests/auto/qml/qqmlcontext/tst_qqmlcontext.cpp @@ -0,0 +1,652 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <qtest.h> +#include <QDebug> +#include <QQmlEngine> +#include <QQmlContext> +#include <QQmlComponent> +#include <QQmlExpression> +#include <private/qqmlcontext_p.h> +#include "../../shared/util.h" + +class tst_qqmlcontext : public QQmlDataTest +{ + Q_OBJECT +public: + tst_qqmlcontext() {} + +private slots: + void baseUrl(); + void resolvedUrl(); + void engineMethod(); + void parentContext(); + void setContextProperty(); + void setContextObject(); + void destruction(); + void idAsContextProperty(); + void readOnlyContexts(); + void nameForObject(); + + void refreshExpressions(); + void refreshExpressionsCrash(); + void refreshExpressionsRootContext(); + + void qtbug_22535(); +private: + QQmlEngine engine; +}; + +void tst_qqmlcontext::baseUrl() +{ + QQmlContext ctxt(&engine); + + QCOMPARE(ctxt.baseUrl(), QUrl()); + + ctxt.setBaseUrl(QUrl("http://www.nokia.com/")); + + QCOMPARE(ctxt.baseUrl(), QUrl("http://www.nokia.com/")); +} + +void tst_qqmlcontext::resolvedUrl() +{ + // Relative to the component + { + QQmlContext ctxt(&engine); + ctxt.setBaseUrl(QUrl("http://www.nokia.com/")); + + QCOMPARE(ctxt.resolvedUrl(QUrl("main.qml")), QUrl("http://www.nokia.com/main.qml")); + } + + // Relative to a parent + { + QQmlContext ctxt(&engine); + ctxt.setBaseUrl(QUrl("http://www.nokia.com/")); + + QQmlContext ctxt2(&ctxt); + QCOMPARE(ctxt2.resolvedUrl(QUrl("main2.qml")), QUrl("http://www.nokia.com/main2.qml")); + } + + // Relative to the engine + { + QQmlContext ctxt(&engine); + QCOMPARE(ctxt.resolvedUrl(QUrl("main.qml")), engine.baseUrl().resolved(QUrl("main.qml"))); + } + + // Relative to a deleted parent + { + QQmlContext *ctxt = new QQmlContext(&engine); + ctxt->setBaseUrl(QUrl("http://www.nokia.com/")); + + QQmlContext ctxt2(ctxt); + QCOMPARE(ctxt2.resolvedUrl(QUrl("main2.qml")), QUrl("http://www.nokia.com/main2.qml")); + + delete ctxt; ctxt = 0; + + QCOMPARE(ctxt2.resolvedUrl(QUrl("main2.qml")), QUrl()); + } + + // Absolute + { + QQmlContext ctxt(&engine); + + QCOMPARE(ctxt.resolvedUrl(QUrl("http://www.nokia.com/main2.qml")), QUrl("http://www.nokia.com/main2.qml")); + QCOMPARE(ctxt.resolvedUrl(QUrl("file:///main2.qml")), QUrl("file:///main2.qml")); + } +} + +void tst_qqmlcontext::engineMethod() +{ + QQmlEngine *engine = new QQmlEngine; + + QQmlContext ctxt(engine); + QQmlContext ctxt2(&ctxt); + QQmlContext ctxt3(&ctxt2); + QQmlContext ctxt4(&ctxt2); + + QCOMPARE(ctxt.engine(), engine); + QCOMPARE(ctxt2.engine(), engine); + QCOMPARE(ctxt3.engine(), engine); + QCOMPARE(ctxt4.engine(), engine); + + delete engine; engine = 0; + + QCOMPARE(ctxt.engine(), engine); + QCOMPARE(ctxt2.engine(), engine); + QCOMPARE(ctxt3.engine(), engine); + QCOMPARE(ctxt4.engine(), engine); +} + +void tst_qqmlcontext::parentContext() +{ + QQmlEngine *engine = new QQmlEngine; + + QCOMPARE(engine->rootContext()->parentContext(), (QQmlContext *)0); + + QQmlContext *ctxt = new QQmlContext(engine); + QQmlContext *ctxt2 = new QQmlContext(ctxt); + QQmlContext *ctxt3 = new QQmlContext(ctxt2); + QQmlContext *ctxt4 = new QQmlContext(ctxt2); + QQmlContext *ctxt5 = new QQmlContext(ctxt); + QQmlContext *ctxt6 = new QQmlContext(engine); + QQmlContext *ctxt7 = new QQmlContext(engine->rootContext()); + + QCOMPARE(ctxt->parentContext(), engine->rootContext()); + QCOMPARE(ctxt2->parentContext(), ctxt); + QCOMPARE(ctxt3->parentContext(), ctxt2); + QCOMPARE(ctxt4->parentContext(), ctxt2); + QCOMPARE(ctxt5->parentContext(), ctxt); + QCOMPARE(ctxt6->parentContext(), engine->rootContext()); + QCOMPARE(ctxt7->parentContext(), engine->rootContext()); + + delete ctxt2; ctxt2 = 0; + + QCOMPARE(ctxt->parentContext(), engine->rootContext()); + QCOMPARE(ctxt3->parentContext(), (QQmlContext *)0); + QCOMPARE(ctxt4->parentContext(), (QQmlContext *)0); + QCOMPARE(ctxt5->parentContext(), ctxt); + QCOMPARE(ctxt6->parentContext(), engine->rootContext()); + QCOMPARE(ctxt7->parentContext(), engine->rootContext()); + + delete engine; engine = 0; + + QCOMPARE(ctxt->parentContext(), (QQmlContext *)0); + QCOMPARE(ctxt3->parentContext(), (QQmlContext *)0); + QCOMPARE(ctxt4->parentContext(), (QQmlContext *)0); + QCOMPARE(ctxt5->parentContext(), (QQmlContext *)0); + QCOMPARE(ctxt6->parentContext(), (QQmlContext *)0); + QCOMPARE(ctxt7->parentContext(), (QQmlContext *)0); + + delete ctxt7; + delete ctxt6; + delete ctxt5; + delete ctxt4; + delete ctxt3; + delete ctxt; +} + +class TestObject : public QObject +{ + Q_OBJECT + Q_PROPERTY(int a READ a NOTIFY aChanged) + Q_PROPERTY(int b READ b NOTIFY bChanged) + Q_PROPERTY(int c READ c NOTIFY cChanged) + +public: + TestObject() : _a(10), _b(10), _c(10) {} + + int a() const { return _a; } + void setA(int a) { _a = a; emit aChanged(); } + + int b() const { return _b; } + void setB(int b) { _b = b; emit bChanged(); } + + int c() const { return _c; } + void setC(int c) { _c = c; emit cChanged(); } + +signals: + void aChanged(); + void bChanged(); + void cChanged(); + +private: + int _a; + int _b; + int _c; +}; + +#define TEST_CONTEXT_PROPERTY(ctxt, name, value) \ +{ \ + QQmlComponent component(&engine); \ + component.setData("import QtQuick 2.0; QtObject { property variant test: " #name " }", QUrl()); \ +\ + QObject *obj = component.create(ctxt); \ +\ + QCOMPARE(obj->property("test"), value); \ +\ + delete obj; \ +} + +void tst_qqmlcontext::setContextProperty() +{ + QQmlContext ctxt(&engine); + QQmlContext ctxt2(&ctxt); + + TestObject obj1; + obj1.setA(3345); + TestObject obj2; + obj2.setA(-19); + + // Static context properties + ctxt.setContextProperty("a", QVariant(10)); + ctxt.setContextProperty("b", QVariant(9)); + ctxt2.setContextProperty("d", &obj2); + ctxt2.setContextProperty("b", QVariant(19)); + ctxt2.setContextProperty("c", QVariant(QString("Hello World!"))); + ctxt.setContextProperty("d", &obj1); + ctxt.setContextProperty("e", &obj1); + + TEST_CONTEXT_PROPERTY(&ctxt2, a, QVariant(10)); + TEST_CONTEXT_PROPERTY(&ctxt2, b, QVariant(19)); + TEST_CONTEXT_PROPERTY(&ctxt2, c, QVariant(QString("Hello World!"))); + TEST_CONTEXT_PROPERTY(&ctxt2, d.a, QVariant(-19)); + TEST_CONTEXT_PROPERTY(&ctxt2, e.a, QVariant(3345)); + + ctxt.setContextProperty("a", QVariant(13)); + ctxt.setContextProperty("b", QVariant(4)); + ctxt2.setContextProperty("b", QVariant(8)); + ctxt2.setContextProperty("c", QVariant(QString("Hi World!"))); + ctxt2.setContextProperty("d", &obj1); + obj1.setA(12); + + TEST_CONTEXT_PROPERTY(&ctxt2, a, QVariant(13)); + TEST_CONTEXT_PROPERTY(&ctxt2, b, QVariant(8)); + TEST_CONTEXT_PROPERTY(&ctxt2, c, QVariant(QString("Hi World!"))); + TEST_CONTEXT_PROPERTY(&ctxt2, d.a, QVariant(12)); + TEST_CONTEXT_PROPERTY(&ctxt2, e.a, QVariant(12)); + + // Changes in context properties + { + QQmlComponent component(&engine); + component.setData("import QtQuick 2.0; QtObject { property variant test: a }", QUrl()); + + QObject *obj = component.create(&ctxt2); + + QCOMPARE(obj->property("test"), QVariant(13)); + ctxt.setContextProperty("a", QVariant(19)); + QCOMPARE(obj->property("test"), QVariant(19)); + + delete obj; + } + { + QQmlComponent component(&engine); + component.setData("import QtQuick 2.0; QtObject { property variant test: b }", QUrl()); + + QObject *obj = component.create(&ctxt2); + + QCOMPARE(obj->property("test"), QVariant(8)); + ctxt.setContextProperty("b", QVariant(5)); + QCOMPARE(obj->property("test"), QVariant(8)); + ctxt2.setContextProperty("b", QVariant(1912)); + QCOMPARE(obj->property("test"), QVariant(1912)); + + delete obj; + } + { + QQmlComponent component(&engine); + component.setData("import QtQuick 2.0; QtObject { property variant test: e.a }", QUrl()); + + QObject *obj = component.create(&ctxt2); + + QCOMPARE(obj->property("test"), QVariant(12)); + obj1.setA(13); + QCOMPARE(obj->property("test"), QVariant(13)); + + delete obj; + } + + // New context properties + { + QQmlComponent component(&engine); + component.setData("import QtQuick 2.0; QtObject { property variant test: a }", QUrl()); + + QObject *obj = component.create(&ctxt2); + + QCOMPARE(obj->property("test"), QVariant(19)); + ctxt2.setContextProperty("a", QVariant(1945)); + QCOMPARE(obj->property("test"), QVariant(1945)); + + delete obj; + } + + // Setting an object-variant context property + { + QQmlComponent component(&engine); + component.setData("import QtQuick 2.0; QtObject { id: root; property int a: 10; property int test: ctxtProp.a; property variant obj: root; }", QUrl()); + + QQmlContext ctxt(engine.rootContext()); + ctxt.setContextProperty("ctxtProp", QVariant()); + + QTest::ignoreMessage(QtWarningMsg, "<Unknown File>:1: TypeError: Cannot read property 'a' of undefined"); + QObject *obj = component.create(&ctxt); + + QVariant v = obj->property("obj"); + + ctxt.setContextProperty("ctxtProp", v); + + QCOMPARE(obj->property("test"), QVariant(10)); + + delete obj; + } +} + +void tst_qqmlcontext::setContextObject() +{ + QQmlContext ctxt(&engine); + + TestObject to; + + to.setA(2); + to.setB(192); + to.setC(18); + + ctxt.setContextObject(&to); + ctxt.setContextProperty("c", QVariant(9)); + + // Static context properties + TEST_CONTEXT_PROPERTY(&ctxt, a, QVariant(2)); + TEST_CONTEXT_PROPERTY(&ctxt, b, QVariant(192)); + TEST_CONTEXT_PROPERTY(&ctxt, c, QVariant(9)); + + to.setA(12); + to.setB(100); + to.setC(7); + ctxt.setContextProperty("c", QVariant(3)); + + TEST_CONTEXT_PROPERTY(&ctxt, a, QVariant(12)); + TEST_CONTEXT_PROPERTY(&ctxt, b, QVariant(100)); + TEST_CONTEXT_PROPERTY(&ctxt, c, QVariant(3)); + + // Changes in context properties + { + QQmlComponent component(&engine); + component.setData("import QtQuick 2.0; QtObject { property variant test: a }", QUrl()); + + QObject *obj = component.create(&ctxt); + + QCOMPARE(obj->property("test"), QVariant(12)); + to.setA(14); + QCOMPARE(obj->property("test"), QVariant(14)); + + delete obj; + } +} + +void tst_qqmlcontext::destruction() +{ + QQmlContext *ctxt = new QQmlContext(&engine); + + QObject obj; + QQmlEngine::setContextForObject(&obj, ctxt); + QQmlExpression expr(ctxt, 0, "a"); + + QCOMPARE(ctxt, QQmlEngine::contextForObject(&obj)); + QCOMPARE(ctxt, expr.context()); + + delete ctxt; ctxt = 0; + + QCOMPARE(ctxt, QQmlEngine::contextForObject(&obj)); + QCOMPARE(ctxt, expr.context()); +} + +void tst_qqmlcontext::idAsContextProperty() +{ + QQmlComponent component(&engine); + component.setData("import QtQuick 2.0; QtObject { property variant a; a: QtObject { id: myObject } }", QUrl()); + + QObject *obj = component.create(); + QVERIFY(obj); + + QVariant a = obj->property("a"); + QVERIFY(a.userType() == QMetaType::QObjectStar); + + QVariant ctxt = qmlContext(obj)->contextProperty("myObject"); + QVERIFY(ctxt.userType() == QMetaType::QObjectStar); + + QVERIFY(a == ctxt); + + delete obj; +} + +// Internal contexts should be read-only +void tst_qqmlcontext::readOnlyContexts() +{ + QQmlComponent component(&engine); + component.setData("import QtQuick 2.0; QtObject { id: me }", QUrl()); + + QObject *obj = component.create(); + QVERIFY(obj); + + QQmlContext *context = qmlContext(obj); + QVERIFY(context); + + QVERIFY(qvariant_cast<QObject*>(context->contextProperty("me")) == obj); + QVERIFY(context->contextObject() == obj); + + QTest::ignoreMessage(QtWarningMsg, "QQmlContext: Cannot set property on internal context."); + context->setContextProperty("hello", 12); + QVERIFY(context->contextProperty("hello") == QVariant()); + + QTest::ignoreMessage(QtWarningMsg, "QQmlContext: Cannot set property on internal context."); + context->setContextProperty("hello", obj); + QVERIFY(context->contextProperty("hello") == QVariant()); + + QTest::ignoreMessage(QtWarningMsg, "QQmlContext: Cannot set context object for internal context."); + context->setContextObject(0); + QVERIFY(context->contextObject() == obj); + + delete obj; +} + +void tst_qqmlcontext::nameForObject() +{ + QObject o1; + QObject o2; + QObject o3; + + QQmlEngine engine; + + // As a context property + engine.rootContext()->setContextProperty("o1", &o1); + engine.rootContext()->setContextProperty("o2", &o2); + engine.rootContext()->setContextProperty("o1_2", &o1); + + QCOMPARE(engine.rootContext()->nameForObject(&o1), QString("o1")); + QCOMPARE(engine.rootContext()->nameForObject(&o2), QString("o2")); + QCOMPARE(engine.rootContext()->nameForObject(&o3), QString()); + + // As an id + QQmlComponent component(&engine); + component.setData("import QtQuick 2.0; QtObject { id: root; property QtObject o: QtObject { id: nested } }", QUrl()); + + QObject *o = component.create(); + QVERIFY(o != 0); + + QCOMPARE(qmlContext(o)->nameForObject(o), QString("root")); + QCOMPARE(qmlContext(o)->nameForObject(qvariant_cast<QObject*>(o->property("o"))), QString("nested")); + QCOMPARE(qmlContext(o)->nameForObject(&o1), QString()); + + 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_qqmlcontext::refreshExpressionsCrash() +{ + { + QQmlEngine engine; + + DeleteCommand command; + engine.rootContext()->setContextProperty("deleteCommand", &command); + // We use a fresh context here to bypass any root-context optimizations in + // the engine + QQmlContext ctxt(engine.rootContext()); + + QQmlComponent 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; + + QQmlContextData::get(&ctxt)->refreshExpressions(); + + delete o1; + } + { + QQmlEngine engine; + + DeleteCommand command; + engine.rootContext()->setContextProperty("deleteCommand", &command); + // We use a fresh context here to bypass any root-context optimizations in + // the engine + QQmlContext ctxt(engine.rootContext()); + + QQmlComponent 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; + + QQmlContextData::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_qqmlcontext::refreshExpressions() +{ + QQmlEngine engine; + QQmlComponent component(&engine, testFileUrl("refreshExpressions.qml")); + QQmlComponent component2(&engine, testFileUrl("RefreshExpressionsType.qml")); + + CountCommand command; + engine.rootContext()->setContextProperty("countCommand", &command); + + // We use a fresh context here to bypass any root-context optimizations in + // the engine + QQmlContext context(engine.rootContext()); + QQmlContext context2(&context); + + QObject *o1 = component.create(&context); + QObject *o2 = component.create(&context2); + QObject *o3 = component2.create(&context); + + QCOMPARE(command.count, 5); + + QQmlContextData::get(&context)->refreshExpressions(); + + QCOMPARE(command.count, 10); + + delete o3; + delete o2; + delete o1; +} + +// Test that updating the root context, only causes expressions in contexts with an +// unresolved name to reevaluate +void tst_qqmlcontext::refreshExpressionsRootContext() +{ + QQmlEngine engine; + + CountCommand command; + engine.rootContext()->setContextProperty("countCommand", &command); + + QQmlComponent component(&engine, testFileUrl("refreshExpressions.qml")); + QQmlComponent component2(&engine, testFileUrl("refreshExpressionsRootContext.qml")); + + QQmlContext context(engine.rootContext()); + QQmlContext context2(engine.rootContext()); + + QString warning = component2.url().toString() + QLatin1String(":4: ReferenceError: Can't find variable: unresolvedName"); + + QObject *o1 = component.create(&context); + + QTest::ignoreMessage(QtWarningMsg, qPrintable(warning)); + QObject *o2 = component2.create(&context2); + + QCOMPARE(command.count, 3); + + QTest::ignoreMessage(QtWarningMsg, qPrintable(warning)); + QQmlContextData::get(engine.rootContext())->refreshExpressions(); + + QCOMPARE(command.count, 4); + + delete o2; + delete o1; +} + +void tst_qqmlcontext::qtbug_22535() +{ + QQmlEngine engine; + QQmlComponent component(&engine, testFileUrl("qtbug_22535.qml")); + QQmlContext context(engine.rootContext()); + + QObject *o = component.create(&context); + + // Don't crash! + delete o; +} + +QTEST_MAIN(tst_qqmlcontext) + +#include "tst_qqmlcontext.moc" |