diff options
Diffstat (limited to 'tests/auto/qml')
47 files changed, 3177 insertions, 138 deletions
diff --git a/tests/auto/qml/debugger/qqmldebugclient/tst_qqmldebugclient.cpp b/tests/auto/qml/debugger/qqmldebugclient/tst_qqmldebugclient.cpp index 9377ef6a8f..1682913bc3 100644 --- a/tests/auto/qml/debugger/qqmldebugclient/tst_qqmldebugclient.cpp +++ b/tests/auto/qml/debugger/qqmldebugclient/tst_qqmldebugclient.cpp @@ -72,7 +72,7 @@ private slots: void tst_QQmlDebugClient::initTestCase() { const QString waitingMsg = QString("QML Debugger: Waiting for connection on port %1...").arg(PORT); - QTest::ignoreMessage(QtWarningMsg, waitingMsg.toAscii().constData()); + QTest::ignoreMessage(QtDebugMsg, waitingMsg.toAscii().constData()); new QQmlEngine(this); m_conn = new QQmlDebugConnection(this); @@ -80,7 +80,7 @@ void tst_QQmlDebugClient::initTestCase() QQmlDebugTestClient client("tst_QQmlDebugClient::handshake()", m_conn); QQmlDebugTestService service("tst_QQmlDebugClient::handshake()"); - QTest::ignoreMessage(QtWarningMsg, "QML Debugger: Connection established."); + QTest::ignoreMessage(QtDebugMsg, "QML Debugger: Connection established."); for (int i = 0; i < 50; ++i) { // try for 5 seconds ... m_conn->connectToHost("127.0.0.1", PORT); @@ -172,7 +172,7 @@ void tst_QQmlDebugClient::sequentialConnect() QTest::qWait(100); connection2.connectToHost("127.0.0.1", PORT); - QTest::ignoreMessage(QtWarningMsg, "QML Debugger: Connection established."); + QTest::ignoreMessage(QtDebugMsg, "QML Debugger: Connection established."); QVERIFY(connection2.waitForConnected()); QVERIFY(connection2.isConnected()); QTRY_VERIFY(client2.state() == QQmlDebugClient::Enabled); diff --git a/tests/auto/qml/debugger/qqmldebugjs/tst_qqmldebugjs.cpp b/tests/auto/qml/debugger/qqmldebugjs/tst_qqmldebugjs.cpp index 9cd021d5e9..f4a9a4add7 100644 --- a/tests/auto/qml/debugger/qqmldebugjs/tst_qqmldebugjs.cpp +++ b/tests/auto/qml/debugger/qqmldebugjs/tst_qqmldebugjs.cpp @@ -303,6 +303,8 @@ signals: void breakAfterCompileRequested(); void result(); void stopped(); + void scriptsResult(); + void evaluateResult(); private: void sendMessage(const QByteArray &); @@ -939,6 +941,12 @@ void QJSDebugClient::messageReceived(const QByteArray &data) } else { // DO NOTHING } + //Emit separate signals for scripts ane evaluate + //as the associated test cases are flaky + if (debugCommand == "scripts") + emit scriptsResult(); + if (debugCommand == "evaluate") + emit evaluateResult(); } else if (type == QLatin1String(EVENT)) { QString event(value.value(QLatin1String(EVENT)).toString()); @@ -1685,8 +1693,8 @@ void tst_QQmlDebugJS::evaluateInGlobalScope() QVERIFY(init()); client->connect(); - client->evaluate(QLatin1String("print('Hello World')"), true); - QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result()))); + client->evaluate(QLatin1String("console.log('Hello World')"), true); + QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(evaluateResult()))); //Verify the value of 'print' QString jsonString(client->response); @@ -1720,7 +1728,7 @@ void tst_QQmlDebugJS::evaluateInLocalScope() int frameIndex = body.value("index").toInt(); client->evaluate(QLatin1String("root.a"), frameIndex); - QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result()))); + QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(evaluateResult()))); //Verify the value of 'timer.interval' jsonString = client->response; @@ -1759,7 +1767,7 @@ void tst_QQmlDebugJS::getScripts() client->connect(); client->scripts(); - QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result()))); + QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(scriptsResult()))); QString jsonString(client->response); QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap(); diff --git a/tests/auto/qml/debugger/qqmldebugservice/tst_qqmldebugservice.cpp b/tests/auto/qml/debugger/qqmldebugservice/tst_qqmldebugservice.cpp index a7fc284443..6e14c03a4c 100644 --- a/tests/auto/qml/debugger/qqmldebugservice/tst_qqmldebugservice.cpp +++ b/tests/auto/qml/debugger/qqmldebugservice/tst_qqmldebugservice.cpp @@ -77,13 +77,13 @@ private slots: void tst_QQmlDebugService::initTestCase() { const QString waitingMsg = QString("QML Debugger: Waiting for connection on port %1...").arg(PORT); - QTest::ignoreMessage(QtWarningMsg, waitingMsg.toAscii().constData()); + QTest::ignoreMessage(QtDebugMsg, waitingMsg.toAscii().constData()); new QQmlEngine(this); m_conn = new QQmlDebugConnection(this); - QTest::ignoreMessage(QtWarningMsg, "QML Debugger: Connection established."); + QTest::ignoreMessage(QtDebugMsg, "QML Debugger: Connection established."); for (int i = 0; i < 50; ++i) { // try for 5 seconds ... m_conn->connectToHost("127.0.0.1", PORT); diff --git a/tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp b/tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp index a35aafff4d..e409f3c8b6 100644 --- a/tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp +++ b/tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp @@ -137,11 +137,15 @@ QQmlDebugObjectReference tst_QQmlEngineDebugService::findRootObject(int context, QQmlDebugRootContextQuery *q_context = m_dbg->queryRootContexts(q_engines->engines()[0].debugId(), this); waitForQuery(q_context); - if (q_context->rootContext().objects().count() == 0) + if (q_context->rootContext().contexts().count() == 0 || + q_context->rootContext().contexts().last().objects().count() == 0) return QQmlDebugObjectReference(); + + //Contexts are in a stack + int count = q_context->rootContext().contexts().count(); QQmlDebugObjectQuery *q_obj = recursive ? - m_dbg->queryObjectRecursive(q_context->rootContext().objects()[context], this) : - m_dbg->queryObject(q_context->rootContext().objects()[context], this); + m_dbg->queryObjectRecursive(q_context->rootContext().contexts()[count - context - 1].objects()[0], this) : + m_dbg->queryObject(q_context->rootContext().contexts()[count - context - 1].objects()[0], this); waitForQuery(q_obj); QQmlDebugObjectReference result = q_obj->object(); @@ -301,7 +305,7 @@ void tst_QQmlEngineDebugService::initTestCase() qRegisterMetaType<QQmlDebugWatch::State>(); qmlRegisterType<NonScriptProperty>("Test", 1, 0, "NonScriptPropertyElement"); - QTest::ignoreMessage(QtWarningMsg, "QML Debugger: Waiting for connection on port 3768..."); + QTest::ignoreMessage(QtDebugMsg, "QML Debugger: Waiting for connection on port 3768..."); m_engine = new QQmlEngine(this); QList<QByteArray> qml; @@ -386,7 +390,7 @@ void tst_QQmlEngineDebugService::initTestCase() m_conn = new QQmlDebugConnection(this); m_conn->connectToHost("127.0.0.1", 3768); - QTest::ignoreMessage(QtWarningMsg, "QML Debugger: Connection established."); + QTest::ignoreMessage(QtDebugMsg, "QML Debugger: Connection established."); bool ok = m_conn->waitForConnected(); QVERIFY(ok); QTRY_VERIFY(QQmlDebugService::hasDebuggingClient()); @@ -493,8 +497,9 @@ void tst_QQmlEngineDebugService::watch_object() QQmlDebugRootContextQuery *q_context = m_dbg->queryRootContexts(q_engines->engines()[0].debugId(), this); waitForQuery(q_context); - QVERIFY(q_context->rootContext().objects().count() > 0); - QQmlDebugObjectQuery *q_obj = m_dbg->queryObject(q_context->rootContext().objects()[0], this); + QVERIFY(q_context->rootContext().contexts().count()); + QVERIFY(q_context->rootContext().contexts().last().objects().count() > 0); + QQmlDebugObjectQuery *q_obj = m_dbg->queryObject(q_context->rootContext().contexts().last().objects()[0], this); waitForQuery(q_obj); QQmlDebugObjectReference obj = q_obj->object(); @@ -705,12 +710,9 @@ void tst_QQmlEngineDebugService::queryRootContexts() QCOMPARE(context.debugId(), QQmlDebugService::idForObject(actualContext)); QCOMPARE(context.name(), actualContext->objectName()); - QCOMPARE(context.objects().count(), 4); // 4 qml component objects created for context in main() - // root context query sends only root object data - it doesn't fill in // the children or property info - QCOMPARE(context.objects()[0].properties().count(), 0); - QCOMPARE(context.objects()[0].children().count(), 0); + QCOMPARE(context.objects().count(), 0); QCOMPARE(context.contexts().count(), 5); QVERIFY(context.contexts()[0].debugId() >= 0); @@ -734,7 +736,7 @@ void tst_QQmlEngineDebugService::queryObject() QQmlDebugRootContextQuery *q_context = m_dbg->queryRootContexts(q_engines->engines()[0].debugId(), this); waitForQuery(q_context); - QQmlDebugObjectReference rootObject = q_context->rootContext().objects()[0]; + QQmlDebugObjectReference rootObject = q_context->rootContext().contexts().last().objects()[0]; QQmlDebugObjectQuery *q_obj = 0; @@ -815,7 +817,7 @@ void tst_QQmlEngineDebugService::queryExpressionResult() QQmlDebugRootContextQuery *q_context = m_dbg->queryRootContexts(q_engines->engines()[0].debugId(), this); waitForQuery(q_context); - int objectId = q_context->rootContext().objects()[0].debugId(); + int objectId = q_context->rootContext().contexts().last().objects()[0].debugId(); QQmlDebugExpressionQuery *q_expr; @@ -1164,8 +1166,9 @@ void tst_QQmlEngineDebugService::queryObjectTree() QQmlDebugRootContextQuery *q_context = m_dbg->queryRootContexts(q_engines->engines()[0].debugId(), this); waitForQuery(q_context); - QVERIFY(q_context->rootContext().objects().count() > sourceIndex); - QQmlDebugObjectReference rootObject = q_context->rootContext().objects()[sourceIndex]; + QVERIFY(q_context->rootContext().contexts().count() >= sourceIndex); + int count = q_context->rootContext().contexts().count(); + QQmlDebugObjectReference rootObject = q_context->rootContext().contexts()[count - sourceIndex - 1].objects()[0]; QQmlDebugObjectQuery *q_obj = m_dbg->queryObjectRecursive(rootObject, this); waitForQuery(q_obj); diff --git a/tests/auto/qml/debugger/qqmlinspector/tst_qqmlinspector.cpp b/tests/auto/qml/debugger/qqmlinspector/tst_qqmlinspector.cpp index def704060c..e30b847139 100644 --- a/tests/auto/qml/debugger/qqmlinspector/tst_qqmlinspector.cpp +++ b/tests/auto/qml/debugger/qqmlinspector/tst_qqmlinspector.cpp @@ -141,7 +141,7 @@ void tst_QQmlInspector::cleanupTestCase() void tst_QQmlInspector::init() { - const QString executable = SRCDIR"/app/app"; + const QString executable = "app/app"; const QString argument = "-qmljsdebugger=port:"STR_PORT",block"; m_process = new QQmlDebugProcess(executable); diff --git a/tests/auto/qml/debugger/qqmlinspector/tst_qqmlinspector.pro b/tests/auto/qml/debugger/qqmlinspector/tst_qqmlinspector.pro index c24accac1a..b4ca60b547 100644 --- a/tests/auto/qml/debugger/qqmlinspector/tst_qqmlinspector.pro +++ b/tests/auto/qml/debugger/qqmlinspector/tst_qqmlinspector.pro @@ -7,7 +7,6 @@ SOURCES += tst_qqmlinspector.cpp INCLUDEPATH += ../shared include(../shared/debugutil.pri) -DEFINES += SRCDIR=\\\"$$PWD\\\" CONFIG += parallel_test declarative_debug QT += qml-private testlib diff --git a/tests/auto/qml/debugger/shared/qqmldebugclient.h b/tests/auto/qml/debugger/shared/qqmldebugclient.h index d3e5cd59a4..1b05e86a64 100644 --- a/tests/auto/qml/debugger/shared/qqmldebugclient.h +++ b/tests/auto/qml/debugger/shared/qqmldebugclient.h @@ -47,7 +47,7 @@ #include <private/qtqmlglobal_p.h> class QQmlDebugConnectionPrivate; -class Q_QML_PRIVATE_EXPORT QQmlDebugConnection : public QIODevice +class QQmlDebugConnection : public QIODevice { Q_OBJECT Q_DISABLE_COPY(QQmlDebugConnection) @@ -81,7 +81,7 @@ private: }; class QQmlDebugClientPrivate; -class Q_QML_PRIVATE_EXPORT QQmlDebugClient : public QObject +class QQmlDebugClient : public QObject { Q_OBJECT Q_DECLARE_PRIVATE(QQmlDebugClient) diff --git a/tests/auto/qml/debugger/shared/qqmlenginedebug_p.h b/tests/auto/qml/debugger/shared/qqmlenginedebug_p.h index 70f04d3a19..2ebdebca53 100644 --- a/tests/auto/qml/debugger/shared/qqmlenginedebug_p.h +++ b/tests/auto/qml/debugger/shared/qqmlenginedebug_p.h @@ -73,7 +73,7 @@ class QQmlDebugObjectReference; class QQmlDebugFileReference; class QQmlDebugEngineReference; class QQmlEngineDebugPrivate; -class Q_QML_PRIVATE_EXPORT QQmlEngineDebug : public QObject +class QQmlEngineDebug : public QObject { Q_OBJECT public: @@ -121,7 +121,7 @@ private: Q_DECLARE_PRIVATE(QQmlEngineDebug) }; -class Q_QML_PRIVATE_EXPORT QQmlDebugWatch : public QObject +class QQmlDebugWatch : public QObject { Q_OBJECT public: @@ -152,7 +152,7 @@ private: int m_objectDebugId; }; -class Q_QML_PRIVATE_EXPORT QQmlDebugPropertyWatch : public QQmlDebugWatch +class QQmlDebugPropertyWatch : public QQmlDebugWatch { Q_OBJECT public: @@ -165,7 +165,7 @@ private: QString m_name; }; -class Q_QML_PRIVATE_EXPORT QQmlDebugObjectExpressionWatch : public QQmlDebugWatch +class QQmlDebugObjectExpressionWatch : public QQmlDebugWatch { Q_OBJECT public: @@ -180,7 +180,7 @@ private: }; -class Q_QML_PRIVATE_EXPORT QQmlDebugQuery : public QObject +class QQmlDebugQuery : public QObject { Q_OBJECT public: @@ -202,7 +202,7 @@ private: State m_state; }; -class Q_QML_PRIVATE_EXPORT QQmlDebugFileReference +class QQmlDebugFileReference { public: QQmlDebugFileReference(); @@ -223,7 +223,7 @@ private: int m_columnNumber; }; -class Q_QML_PRIVATE_EXPORT QQmlDebugEngineReference +class QQmlDebugEngineReference { public: QQmlDebugEngineReference(); @@ -240,7 +240,7 @@ private: QString m_name; }; -class Q_QML_PRIVATE_EXPORT QQmlDebugObjectReference +class QQmlDebugObjectReference { public: QQmlDebugObjectReference(); @@ -271,7 +271,7 @@ private: QList<QQmlDebugObjectReference> m_children; }; -class Q_QML_PRIVATE_EXPORT QQmlDebugContextReference +class QQmlDebugContextReference { public: QQmlDebugContextReference(); @@ -292,7 +292,7 @@ private: QList<QQmlDebugContextReference> m_contexts; }; -class Q_QML_PRIVATE_EXPORT QQmlDebugPropertyReference +class QQmlDebugPropertyReference { public: QQmlDebugPropertyReference(); @@ -317,7 +317,7 @@ private: }; -class Q_QML_PRIVATE_EXPORT QQmlDebugEnginesQuery : public QQmlDebugQuery +class QQmlDebugEnginesQuery : public QQmlDebugQuery { Q_OBJECT public: @@ -332,7 +332,7 @@ private: QList<QQmlDebugEngineReference> m_engines; }; -class Q_QML_PRIVATE_EXPORT QQmlDebugRootContextQuery : public QQmlDebugQuery +class QQmlDebugRootContextQuery : public QQmlDebugQuery { Q_OBJECT public: @@ -347,7 +347,7 @@ private: QQmlDebugContextReference m_context; }; -class Q_QML_PRIVATE_EXPORT QQmlDebugObjectQuery : public QQmlDebugQuery +class QQmlDebugObjectQuery : public QQmlDebugQuery { Q_OBJECT public: @@ -363,7 +363,7 @@ private: }; -class Q_QML_PRIVATE_EXPORT QQmlDebugExpressionQuery : public QQmlDebugQuery +class QQmlDebugExpressionQuery : public QQmlDebugQuery { Q_OBJECT public: diff --git a/tests/auto/qml/parserstress/tst_parserstress.cpp b/tests/auto/qml/parserstress/tst_parserstress.cpp index a179a24f5f..eb477af521 100644 --- a/tests/auto/qml/parserstress/tst_parserstress.cpp +++ b/tests/auto/qml/parserstress/tst_parserstress.cpp @@ -128,8 +128,7 @@ void tst_parserstress::ecmascript() QQmlComponent component(&engine); - QString dummyFile = QFINDTESTDATA("dummy.qml"); - component.setData(qmlData, QUrl::fromLocalFile(dummyFile)); + component.setData(qmlData, QUrl()); QFileInfo info(file); diff --git a/tests/auto/qml/qjsengine/tst_qjsengine.cpp b/tests/auto/qml/qjsengine/tst_qjsengine.cpp index 66fef8e2dd..6f9cc93757 100644 --- a/tests/auto/qml/qjsengine/tst_qjsengine.cpp +++ b/tests/auto/qml/qjsengine/tst_qjsengine.cpp @@ -899,6 +899,7 @@ void tst_QJSEngine::jsParseDate() void tst_QJSEngine::newQObject() { QJSEngine eng; + QObject temp; { QJSValue qobject = eng.newQObject(0); @@ -907,11 +908,11 @@ void tst_QJSEngine::newQObject() QCOMPARE(qobject.toQObject(), (QObject *)0); } { - QJSValue qobject = eng.newQObject(this); + QJSValue qobject = eng.newQObject(&temp); QVERIFY(!qobject.isUndefined()); QCOMPARE(qobject.isQObject(), true); QCOMPARE(qobject.isObject(), true); - QCOMPARE(qobject.toQObject(), (QObject *)this); + QCOMPARE(qobject.toQObject(), (QObject *)&temp); QVERIFY(!qobject.isCallable()); // prototype should be QObject.prototype QCOMPARE(qobject.prototype().isObject(), true); @@ -1068,6 +1069,7 @@ void tst_QJSEngine::newQObject_sameQObject() #if 0 // FIXME: No prototype API in QScriptEngine void tst_QJSEngine::newQObject_defaultPrototype() { + QObject temp; QScriptEngine eng; // newQObject() should set the default prototype, if one has been registered { @@ -1076,14 +1078,14 @@ void tst_QJSEngine::newQObject_defaultPrototype() QScriptValue qobjectProto = eng.newObject(); eng.setDefaultPrototype(qMetaTypeId<QObject*>(), qobjectProto); { - QScriptValue ret = eng.newQObject(this); + QScriptValue ret = eng.newQObject(&temp); QVERIFY(ret.prototype().equals(qobjectProto)); } QScriptValue tstProto = eng.newObject(); int typeId = qRegisterMetaType<tst_QJSEngine*>("tst_QJSEngine*"); eng.setDefaultPrototype(typeId, tstProto); { - QScriptValue ret = eng.newQObject(this); + QScriptValue ret = eng.newQObject(temp); QVERIFY(ret.prototype().equals(tstProto)); } @@ -1261,7 +1263,8 @@ void tst_QJSEngine::newQMetaObject() QVERIFY(instanceofJS(inst, qclass3).strictlyEquals(false)); } { - QScriptValue inst = qclass4.callAsConstructor(QScriptValueList() << eng.newQObject(this)); + QObject temp; + QScriptValue inst = qclass4.callAsConstructor(QScriptValueList() << eng.newQObject(&temp)); QVERIFY(inst.isQObject()); QVERIFY(inst.toQObject() != 0); QCOMPARE(inst.toQObject()->parent(), (QObject*)this); @@ -2887,6 +2890,7 @@ void tst_QJSEngine::castWithPrototypeChain() QScriptEngine eng; Bar bar; Baz baz; + QObject temp; QScriptValue barProto = eng.toScriptValue(&bar); QScriptValue bazProto = eng.toScriptValue(&baz); eng.setDefaultPrototype(qMetaTypeId<Bar*>(), barProto); @@ -2954,7 +2958,7 @@ void tst_QJSEngine::castWithPrototypeChain() QVERIFY(pbar == 0); } - bazProto.setPrototype(eng.newQObject(this)); + bazProto.setPrototype(eng.newQObject(&temp)); { Baz *pbaz = qscriptvalue_cast<Baz*>(baz2Value); QVERIFY(pbaz != 0); @@ -3756,8 +3760,9 @@ private: QScriptEngine* m_engine; protected: void run() { + QObject temp; m_engine = new QScriptEngine(); - m_engine->setGlobalObject(m_engine->newQObject(this)); + m_engine->setGlobalObject(m_engine->newQObject(&temp)); m_engine->evaluate("while (1) { sleep(); }"); delete m_engine; } @@ -4941,6 +4946,7 @@ void tst_QJSEngine::reentrancy_Array() void tst_QJSEngine::reentrancy_objectCreation() { + QObject temp; QJSEngine eng1; QJSEngine eng2; { @@ -4957,8 +4963,8 @@ void tst_QJSEngine::reentrancy_objectCreation() QCOMPARE(qjsvalue_cast<QRegExp>(r2), qjsvalue_cast<QRegExp>(r1)); } { - QJSValue o1 = eng1.newQObject(this); - QJSValue o2 = eng2.newQObject(this); + QJSValue o1 = eng1.newQObject(&temp); + QJSValue o2 = eng2.newQObject(&temp); QCOMPARE(o1.toQObject(), o2.toQObject()); QCOMPARE(o2.toQObject(), o1.toQObject()); } diff --git a/tests/auto/qml/qjsvalue/tst_qjsvalue.cpp b/tests/auto/qml/qjsvalue/tst_qjsvalue.cpp index cec10ccf38..ad655217ad 100644 --- a/tests/auto/qml/qjsvalue/tst_qjsvalue.cpp +++ b/tests/auto/qml/qjsvalue/tst_qjsvalue.cpp @@ -986,6 +986,7 @@ Q_DECLARE_METATYPE(QVariant) void tst_QJSValue::toVariant() { QJSEngine eng; + QObject temp; QJSValue undefined = eng.toScriptValue(QVariant()); QCOMPARE(undefined.toVariant(), QVariant()); @@ -1020,11 +1021,11 @@ void tst_QJSValue::toVariant() QJSValue object = eng.newObject(); QCOMPARE(object.toVariant(), QVariant(QVariantMap())); - QJSValue qobject = eng.newQObject(this); + QJSValue qobject = eng.newQObject(&temp); { QVariant var = qobject.toVariant(); QCOMPARE(var.userType(), int(QMetaType::QObjectStar)); - QCOMPARE(qVariantValue<QObject*>(var), (QObject *)this); + QCOMPARE(qVariantValue<QObject*>(var), (QObject *)&temp); } { @@ -1130,10 +1131,11 @@ Q_DECLARE_METATYPE(QPushButton*); void tst_QJSValue::toQObject() { QJSEngine eng; + QObject temp; - QJSValue qobject = eng.newQObject(this); - QCOMPARE(qobject.toQObject(), (QObject *)this); - QCOMPARE(qjsvalue_cast<QObject*>(qobject), (QObject *)this); + QJSValue qobject = eng.newQObject(&temp); + QCOMPARE(qobject.toQObject(), (QObject *)&temp); + QCOMPARE(qjsvalue_cast<QObject*>(qobject), (QObject *)&temp); QCOMPARE(qjsvalue_cast<QWidget*>(qobject), (QWidget *)0); QWidget widget; @@ -2168,6 +2170,7 @@ void tst_QJSValue::getSetData_objects_data() { #if 0 // FIXME: no setData/data API newEngine(); + QObject *temp = new QObject; QTest::addColumn<QJSValue>("object"); @@ -2175,7 +2178,7 @@ void tst_QJSValue::getSetData_objects_data() QTest::newRow("object from engine") << engine->newObject(); QTest::newRow("Array") << engine->newArray(); QTest::newRow("Date") << engine->evaluate("new Date(12324)"); - QTest::newRow("QObject") << engine->newQObject(this); + QTest::newRow("QObject") << engine->newQObject(temp); QTest::newRow("RegExp") << engine->newRegExp(QRegExp()); #endif } @@ -2265,6 +2268,7 @@ public: void tst_QJSValue::getSetScriptClass_emptyClass_data() { newEngine(); + QObject *temp = new QObject; QTest::addColumn<QJSValue>("value"); QTest::newRow("invalid") << QJSValue(); @@ -2281,7 +2285,7 @@ void tst_QJSValue::getSetScriptClass_emptyClass_data() QTest::newRow("undefined") << QJSValue(engine->toScriptValue(QVariant())); QTest::newRow("object") << QJSValue(engine->newObject()); QTest::newRow("date") << QJSValue(engine->evaluate("new Date()")); - QTest::newRow("qobject") << QJSValue(engine->newQObject(this)); + QTest::newRow("qobject") << QJSValue(engine->newQObject(temp)); } void tst_QJSValue::getSetScriptClass_emptyClass() @@ -2341,9 +2345,10 @@ void tst_QJSValue::getSetScriptClass_QVariant() void tst_QJSValue::getSetScriptClass_QObject() { QScriptEngine eng; + QObject temp; TestScriptClass testClass(&eng); { - QJSValue obj = eng.newQObject(this); + QJSValue obj = eng.newQObject(&temp); QVERIFY(obj.isQObject()); obj.setScriptClass(&testClass); QCOMPARE(obj.scriptClass(), (QScriptClass*)&testClass); @@ -2999,6 +3004,7 @@ void tst_QJSValue::lessThan() void tst_QJSValue::equals() { QJSEngine eng; + QObject temp; QVERIFY(QJSValue().equals(QJSValue())); @@ -3088,8 +3094,8 @@ void tst_QJSValue::equals() QCOMPARE(obj1.equals(obj1), true); QCOMPARE(obj2.equals(obj2), true); - QJSValue qobj1 = eng.newQObject(this); - QJSValue qobj2 = eng.newQObject(this); + QJSValue qobj1 = eng.newQObject(&temp); + QJSValue qobj2 = eng.newQObject(&temp); QJSValue qobj3 = eng.newQObject(0); // FIXME: No ScriptOwnership: QJSValue qobj4 = eng.newQObject(new QObject(), QScriptEngine::ScriptOwnership); @@ -3137,6 +3143,7 @@ void tst_QJSValue::equals() void tst_QJSValue::strictlyEquals() { QJSEngine eng; + QObject temp; QVERIFY(QJSValue().strictlyEquals(QJSValue())); @@ -3242,8 +3249,8 @@ void tst_QJSValue::strictlyEquals() QCOMPARE(obj2.strictlyEquals(obj2), true); QVERIFY(!obj1.strictlyEquals(QJSValue())); - QJSValue qobj1 = eng.newQObject(this); - QJSValue qobj2 = eng.newQObject(this); + QJSValue qobj1 = eng.newQObject(&temp); + QJSValue qobj2 = eng.newQObject(&temp); QVERIFY(qobj1.strictlyEquals(qobj2)); { @@ -3482,13 +3489,14 @@ void tst_QJSValue::prettyPrinter() void tst_QJSValue::engineDeleted() { QJSEngine *eng = new QJSEngine; + QObject temp; QJSValue v1 = eng->toScriptValue(123); QVERIFY(v1.isNumber()); QJSValue v2 = eng->toScriptValue(QString("ciao")); QVERIFY(v2.isString()); QJSValue v3 = eng->newObject(); QVERIFY(v3.isObject()); - QJSValue v4 = eng->newQObject(this); + QJSValue v4 = eng->newQObject(&temp); QVERIFY(v4.isQObject()); QJSValue v5 = "Hello"; QVERIFY(v2.isString()); diff --git a/tests/auto/qml/qqmlcomponent/data/TestComponent.2.qml b/tests/auto/qml/qqmlcomponent/data/TestComponent.2.qml new file mode 100644 index 0000000000..fca43fe2dc --- /dev/null +++ b/tests/auto/qml/qqmlcomponent/data/TestComponent.2.qml @@ -0,0 +1,591 @@ +import QtQuick 2.0 + +Item { + id: root + objectName: "root" + property int zero: 0 + + Item { + id: c1 + objectName: "c1" + property int one: zero + 1 + + Item { + id: c1c1 + objectName: "c1c1" + property bool two: c2c1c1.two + } + + Item { + id: c1c2 + objectName: "c1c2" + property string three: "three" + + Rectangle { + id: c1c2c3 + objectName: "c1c2c3" + property alias othercolor: c2c1.color + color: if (c2c1.color == Qt.rgba(0,0,1)) Qt.rgba(1,0,0); else Qt.rgba(0,1,0); + } + } + } + + Item { + id: c2 + objectName: "c2" + property string two: "two" + + Rectangle { + id: c2c1 + objectName: "c2c1" + property string three: "2" + c1c2.three + color: "blue" + + MouseArea { + id: c2c1c1 + objectName: "c2c1c1" + property bool two: false + onClicked: two = !two + } + + Item { + id: c2c1c2 + objectName: "c2c1c2" + property string three: "1" + parent.three + } + } + } + + Item { + id: c3 + objectName: "c3" + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + } + + property bool success: true + Component.onCompleted: { + // test state after initial bindings evaluation + if (zero != 0) success = false; + if (c1.one != 1) success = false; + if (c1c1.two != false) success = false; + if (c1c2.three != "three") success = false; + if (c1c2c3.color != Qt.rgba(1,0,0)) success = false; + if (c2.two != "two") success = false; + if (c2c1.three != "2three") success = false; + if (c2c1.color != Qt.rgba(0,0,1)) success = false; + if (c2c1c1.two != false) success = false; + if (c2c1c2.three != "12three") success = false; + if (c3.children.length != 500) success = false; + + // now retrigger bindings evaluation + root.zero = 5; + if (c1.one != 6) success = false; + c2c1c1.two = true; + if (c1c1.two != true) success = false; + c1c2.three = "3"; + if (c2c1.three != "23") success = false; + if (c2c1c2.three != "123") success = false; + c2c1.color = Qt.rgba(1,0,0); + if (c1c2c3.color != Qt.rgba(0,1,0)) success = false; + if (c1c2c3.othercolor != Qt.rgba(1,0,0)) success = false; + } +} diff --git a/tests/auto/qml/qqmlcomponent/data/TestComponent.qml b/tests/auto/qml/qqmlcomponent/data/TestComponent.qml new file mode 100644 index 0000000000..64cec1cd06 --- /dev/null +++ b/tests/auto/qml/qqmlcomponent/data/TestComponent.qml @@ -0,0 +1,534 @@ +import QtQuick 2.0 + +Item { + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} +} diff --git a/tests/auto/qml/qqmlcomponent/qqmlcomponent.pro b/tests/auto/qml/qqmlcomponent/qqmlcomponent.pro index cf1c398ce5..6667513395 100644 --- a/tests/auto/qml/qqmlcomponent/qqmlcomponent.pro +++ b/tests/auto/qml/qqmlcomponent/qqmlcomponent.pro @@ -2,7 +2,11 @@ CONFIG += testcase TARGET = tst_qqmlcomponent macx:CONFIG -= app_bundle -SOURCES += tst_qqmlcomponent.cpp +INCLUDEPATH += ../../shared/ +SOURCES += tst_qqmlcomponent.cpp \ + ../../shared/testhttpserver.cpp + +HEADERS += ../../shared/testhttpserver.h include (../../shared/util.pri) @@ -10,4 +14,4 @@ TESTDATA = data/* CONFIG += parallel_test -QT += core-private gui-private qml-private network testlib +QT += core-private gui-private qml-private quick-private network testlib diff --git a/tests/auto/qml/qqmlcomponent/tst_qqmlcomponent.cpp b/tests/auto/qml/qqmlcomponent/tst_qqmlcomponent.cpp index 603c091a03..10181aa9b8 100644 --- a/tests/auto/qml/qqmlcomponent/tst_qqmlcomponent.cpp +++ b/tests/auto/qml/qqmlcomponent/tst_qqmlcomponent.cpp @@ -45,8 +45,14 @@ #include <QtQml/qqmlcomponent.h> #include <QtQml/qqmlproperty.h> #include <QtQml/qqmlincubator.h> +#include <QtQuick> +#include <QtQuick/private/qquickrectangle_p.h> +#include <QtQuick/private/qquickmousearea_p.h> #include <qcolor.h> #include "../../shared/util.h" +#include "testhttpserver.h" + +#define SERVER_PORT 14450 class MyIC : public QObject, public QQmlIncubationController { @@ -59,6 +65,37 @@ protected: } }; +class ComponentWatcher : public QObject +{ + Q_OBJECT +public: + ComponentWatcher(QQmlComponent *comp) : loading(0), error(0), ready(0) { + connect(comp, SIGNAL(statusChanged(QQmlComponent::Status)), + this, SLOT(statusChanged(QQmlComponent::Status))); + } + + int loading; + int error; + int ready; + +public slots: + void statusChanged(QQmlComponent::Status status) { + switch (status) { + case QQmlComponent::Loading: + ++loading; + break; + case QQmlComponent::Error: + ++error; + break; + case QQmlComponent::Ready: + ++ready; + break; + default: + break; + } + } +}; + class tst_qqmlcomponent : public QQmlDataTest { Q_OBJECT @@ -72,6 +109,8 @@ private slots: void qmlCreateObjectWithProperties(); void qmlIncubateObject(); void qmlCreateParentReference(); + void async(); + void asyncHierarchy(); private: QQmlEngine engine; @@ -213,6 +252,68 @@ void tst_qqmlcomponent::qmlCreateParentReference() QCOMPARE(warnings.count(), 0); } +void tst_qqmlcomponent::async() +{ + TestHTTPServer server(SERVER_PORT); + QVERIFY(server.isValid()); + server.serveDirectory(dataDirectory()); + + QQmlComponent component(&engine); + ComponentWatcher watcher(&component); + component.loadUrl(QUrl("http://127.0.0.1:14450/TestComponent.qml"), QQmlComponent::Asynchronous); + QCOMPARE(watcher.loading, 1); + QTRY_VERIFY(component.isReady()); + QCOMPARE(watcher.ready, 1); + QCOMPARE(watcher.error, 0); + + QObject *object = component.create(); + QVERIFY(object != 0); + + delete object; +} + +void tst_qqmlcomponent::asyncHierarchy() +{ + TestHTTPServer server(SERVER_PORT); + QVERIFY(server.isValid()); + server.serveDirectory(dataDirectory()); + + // ensure that the item hierarchy is compiled correctly. + QQmlComponent component(&engine); + ComponentWatcher watcher(&component); + component.loadUrl(QUrl("http://127.0.0.1:14450/TestComponent.2.qml"), QQmlComponent::Asynchronous); + QCOMPARE(watcher.loading, 1); + QTRY_VERIFY(component.isReady()); + QCOMPARE(watcher.ready, 1); + QCOMPARE(watcher.error, 0); + + QObject *root = component.create(); + QVERIFY(root != 0); + + // ensure that the parent-child relationship hierarchy is correct + QQuickItem *c1 = root->findChild<QQuickItem*>("c1", Qt::FindDirectChildrenOnly); + QVERIFY(c1); + QQuickItem *c1c1 = c1->findChild<QQuickItem*>("c1c1", Qt::FindDirectChildrenOnly); + QVERIFY(c1c1); + QQuickItem *c1c2 = c1->findChild<QQuickItem*>("c1c2", Qt::FindDirectChildrenOnly); + QVERIFY(c1c2); + QQuickRectangle *c1c2c3 = c1c2->findChild<QQuickRectangle*>("c1c2c3", Qt::FindDirectChildrenOnly); + QVERIFY(c1c2c3); + QQuickItem *c2 = root->findChild<QQuickItem*>("c2", Qt::FindDirectChildrenOnly); + QVERIFY(c2); + QQuickRectangle *c2c1 = c2->findChild<QQuickRectangle*>("c2c1", Qt::FindDirectChildrenOnly); + QVERIFY(c2c1); + QQuickMouseArea *c2c1c1 = c2c1->findChild<QQuickMouseArea*>("c2c1c1", Qt::FindDirectChildrenOnly); + QVERIFY(c2c1c1); + QQuickItem *c2c1c2 = c2c1->findChild<QQuickItem*>("c2c1c2", Qt::FindDirectChildrenOnly); + QVERIFY(c2c1c2); + + // ensure that values and bindings are assigned correctly + QVERIFY(root->property("success").toBool()); + + delete root; +} + QTEST_MAIN(tst_qqmlcomponent) #include "tst_qqmlcomponent.moc" diff --git a/tests/auto/qml/qqmlcontext/tst_qqmlcontext.cpp b/tests/auto/qml/qqmlcontext/tst_qqmlcontext.cpp index 6125362365..6525bde9b8 100644 --- a/tests/auto/qml/qqmlcontext/tst_qqmlcontext.cpp +++ b/tests/auto/qml/qqmlcontext/tst_qqmlcontext.cpp @@ -617,7 +617,7 @@ void tst_qqmlcontext::refreshExpressionsRootContext() QQmlContext context(engine.rootContext()); QQmlContext context2(engine.rootContext()); - QString warning = component2.url().toString() + QLatin1String(":4: ReferenceError: Can't find variable: unresolvedName"); + QString warning = component2.url().toString() + QLatin1String(":4: ReferenceError: unresolvedName is not defined"); QObject *o1 = component.create(&context); diff --git a/tests/auto/qml/qqmlecmascript/data/ComponentWithVarProp.qml b/tests/auto/qml/qqmlecmascript/data/ComponentWithVarProp.qml new file mode 100644 index 0000000000..3105b8c79f --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/ComponentWithVarProp.qml @@ -0,0 +1,5 @@ +import QtQuick 2.0 + +Item { + property var varprop: true +} diff --git a/tests/auto/qml/qqmlecmascript/data/dynamicDeletion.3.qml b/tests/auto/qml/qqmlecmascript/data/dynamicDeletion.3.qml new file mode 100644 index 0000000000..3739150bc4 --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/dynamicDeletion.3.qml @@ -0,0 +1,30 @@ +import QtQuick 2.0 +import Qt.test 1.0 + +Item { + id: root + property bool test: false + property QtObject objectProperty + + onObjectPropertyChanged: { + root.test = true; + } + + property Component c: Component { + id: dynamicComponent + QtObject { + id: dynamicObject + } + } + + function create() { + root.objectProperty = root.c.createObject(root); + } + + function destroy() { + root.test = false; // reset test + root.objectProperty.destroy(100); + // in cpp, wait objectProperty deletion, inspect "test" and "objectProperty" + // test should be true and value of objectProperty should be zero. + } +} diff --git a/tests/auto/qml/qqmlecmascript/data/moduleapi/qobjectModuleApiWriting.qml b/tests/auto/qml/qqmlecmascript/data/moduleapi/qobjectModuleApiWriting.qml index be647ca57f..e4a68d14ea 100644 --- a/tests/auto/qml/qqmlecmascript/data/moduleapi/qobjectModuleApiWriting.qml +++ b/tests/auto/qml/qqmlecmascript/data/moduleapi/qobjectModuleApiWriting.qml @@ -6,6 +6,7 @@ QtObject { property int secondProperty: 2 property int readOnlyProperty: QtTest.qobjectTestProperty property int writableProperty: QtTest.qobjectTestWritableProperty + property int writableFinalProperty: QtTest.qobjectTestWritableFinalProperty onFirstPropertyChanged: { // In this case, we want to attempt to set the module API property. @@ -16,11 +17,14 @@ QtObject { } onSecondPropertyChanged: { - // In this case, we want to attempt to set the module API property. - // This should succeed, as the module API property is writable. + // In this case, we want to attempt to set the module API properties. + // This should succeed, as the module API properties are writable. if (secondProperty != QtTest.qobjectTestWritableProperty) { QtTest.qobjectTestWritableProperty = secondProperty; // should succeed. } + if (secondProperty != QtTest.qobjectTestWritableFinalProperty) { + QtTest.qobjectTestWritableFinalProperty = secondProperty; // should succeed. + } } } diff --git a/tests/auto/qml/qqmlecmascript/data/propertyVarOwnership.5.qml b/tests/auto/qml/qqmlecmascript/data/propertyVarOwnership.5.qml new file mode 100644 index 0000000000..ad5807b1cf --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/propertyVarOwnership.5.qml @@ -0,0 +1,28 @@ +import QtQuick 2.0 +import Qt.test 1.0 as ModuleApi + +Item { + id: testOwnership + property bool test: false + + function runTest() { + var o; + var c = Qt.createComponent("ComponentWithVarProp.qml"); + if (c.status == Component.Ready) { + o = c.createObject(); + } else { + return; // failed to create component. + } + o.varprop = true; // causes initialization of varProperties. + ModuleApi.trackObject(o); // stores QObject ptr + if (ModuleApi.trackedObject() == null) return; // is still valid, should have a valid v8object. + o = new Date(); // causes object to be gc-able. + gc(); // collect object's v8object + varProperties, queues deleteLater. + if (ModuleApi.trackedObject() != null) return; // v8object was previously collected. + ModuleApi.setTrackedObjectProperty("varprop"); // deferences varProperties of object. + test = !(ModuleApi.trackedObjectProperty("varprop")); // deferences varProperties of object. + // if we didn't crash, success. + } +} + + diff --git a/tests/auto/qml/qqmlecmascript/data/qtbug_24448.js b/tests/auto/qml/qqmlecmascript/data/qtbug_24448.js new file mode 100644 index 0000000000..eefe00337c --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/qtbug_24448.js @@ -0,0 +1,6 @@ +var test = false; +try { + eval(foo); +} catch (e) { + test = (typeof foo) === "undefined"; +} diff --git a/tests/auto/qml/qqmlecmascript/data/qtbug_24448.qml b/tests/auto/qml/qqmlecmascript/data/qtbug_24448.qml new file mode 100644 index 0000000000..d8d305d104 --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/qtbug_24448.qml @@ -0,0 +1,7 @@ +import "qtbug_24448.js" as Test +import QtQuick 2.0 + +QtObject { + property bool test: Test.test +} + diff --git a/tests/auto/qml/qqmlecmascript/testtypes.cpp b/tests/auto/qml/qqmlecmascript/testtypes.cpp index 78119cb776..64e91fbc95 100644 --- a/tests/auto/qml/qqmlecmascript/testtypes.cpp +++ b/tests/auto/qml/qqmlecmascript/testtypes.cpp @@ -140,6 +140,7 @@ static QObject *qobject_api(QQmlEngine *engine, QJSEngine *scriptEngine) testQObjectApi *o = new testQObjectApi(); o->setQObjectTestProperty(20); o->setQObjectTestWritableProperty(50); + o->setQObjectTestWritableFinalProperty(10); return o; } diff --git a/tests/auto/qml/qqmlecmascript/testtypes.h b/tests/auto/qml/qqmlecmascript/testtypes.h index 1d68e8ae13..54fab26405 100644 --- a/tests/auto/qml/qqmlecmascript/testtypes.h +++ b/tests/auto/qml/qqmlecmascript/testtypes.h @@ -978,10 +978,11 @@ class testQObjectApi : public QObject Q_ENUMS(MyEnum) Q_PROPERTY (int qobjectTestProperty READ qobjectTestProperty NOTIFY qobjectTestPropertyChanged) Q_PROPERTY (int qobjectTestWritableProperty READ qobjectTestWritableProperty WRITE setQObjectTestWritableProperty NOTIFY qobjectTestWritablePropertyChanged) + Q_PROPERTY (int qobjectTestWritableFinalProperty READ qobjectTestWritableFinalProperty WRITE setQObjectTestWritableFinalProperty NOTIFY qobjectTestWritableFinalPropertyChanged FINAL) public: testQObjectApi(QObject* parent = 0) - : QObject(parent), m_testProperty(0), m_testWritableProperty(0), m_methodCallCount(0) + : QObject(parent), m_testProperty(0), m_testWritableProperty(0), m_testWritableFinalProperty(0), m_methodCallCount(0), m_trackedObject(0) { } @@ -991,20 +992,31 @@ public: Q_INVOKABLE int qobjectEnumTestMethod(MyEnum val) { return (static_cast<int>(val) + 5); } Q_INVOKABLE int qobjectTestMethod(int increment = 1) { m_methodCallCount += increment; return m_methodCallCount; } + Q_INVOKABLE void trackObject(QObject *obj) { m_trackedObject = obj; } + Q_INVOKABLE QObject *trackedObject() const { return m_trackedObject; } + Q_INVOKABLE void setTrackedObjectProperty(const QString &propName) const { m_trackedObject->setProperty(qPrintable(propName), QVariant(5)); } + Q_INVOKABLE QVariant trackedObjectProperty(const QString &propName) const { return m_trackedObject->property(qPrintable(propName)); } + int qobjectTestProperty() const { return m_testProperty; } void setQObjectTestProperty(int tp) { m_testProperty = tp; emit qobjectTestPropertyChanged(tp); } int qobjectTestWritableProperty() const { return m_testWritableProperty; } void setQObjectTestWritableProperty(int tp) { m_testWritableProperty = tp; emit qobjectTestWritablePropertyChanged(tp); } + int qobjectTestWritableFinalProperty() const { return m_testWritableFinalProperty; } + void setQObjectTestWritableFinalProperty(int tp) { m_testWritableFinalProperty = tp; emit qobjectTestWritableFinalPropertyChanged(); } + signals: void qobjectTestPropertyChanged(int testProperty); void qobjectTestWritablePropertyChanged(int testWritableProperty); + void qobjectTestWritableFinalPropertyChanged(); private: int m_testProperty; int m_testWritableProperty; + int m_testWritableFinalProperty; int m_methodCallCount; + QObject *m_trackedObject; }; class CircularReferenceObject : public QObject, diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp index b475e991b2..861ff2e641 100644 --- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp +++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp @@ -208,6 +208,7 @@ private slots: void deleteLater(); void in(); void typeOf(); + void qtbug_24448(); void sharedAttachedObject(); void objectName(); void writeRemovesBinding(); @@ -1288,6 +1289,28 @@ void tst_qqmlecmascript::dynamicDestruction() delete o; } + + { + // QTBUG-23451 + QQmlGuard<QObject> createdQmlObject = 0; + QQmlComponent component(&engine, testFileUrl("dynamicDeletion.3.qml")); + QObject *o = component.create(); + QVERIFY(o != 0); + QVERIFY(qvariant_cast<QObject*>(o->property("objectProperty")) == 0); + QMetaObject::invokeMethod(o, "create"); + createdQmlObject = qvariant_cast<QObject*>(o->property("objectProperty")); + QVERIFY(createdQmlObject); + QMetaObject::invokeMethod(o, "destroy"); + QVERIFY(qvariant_cast<bool>(o->property("test")) == false); + for (int ii = 0; createdQmlObject && ii < 50; ++ii) { // After 5 seconds we should give up + QTest::qWait(100); + QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); + QCoreApplication::processEvents(); + } + QVERIFY(qvariant_cast<QObject*>(o->property("objectProperty")) == 0); + QVERIFY(qvariant_cast<bool>(o->property("test")) == true); + delete o; + } } /* @@ -1417,10 +1440,10 @@ void tst_qqmlecmascript::scriptErrors() QString url = component.url().toString(); QString warning1 = url.left(url.length() - 3) + "js:2: Error: Invalid write to global property \"a\""; - QString warning2 = url + ":5: ReferenceError: Can't find variable: a"; + QString warning2 = url + ":5: ReferenceError: a is not defined"; QString warning3 = url.left(url.length() - 3) + "js:4: Error: Invalid write to global property \"a\""; - QString warning4 = url + ":13: ReferenceError: Can't find variable: a"; - QString warning5 = url + ":11: ReferenceError: Can't find variable: a"; + QString warning4 = url + ":13: ReferenceError: a is not defined"; + QString warning5 = url + ":11: ReferenceError: a is not defined"; QString warning6 = url + ":10: Unable to assign [undefined] to int"; QString warning7 = url + ":15: Error: Cannot assign to read-only property \"trueProperty\""; QString warning8 = url + ":16: Error: Cannot assign to non-existent property \"fakeProperty\""; @@ -3090,18 +3113,18 @@ void tst_qqmlecmascript::moduleApi_data() QTest::newRow("qobject, writing + readonly constraints") << testFileUrl("moduleapi/qobjectModuleApiWriting.qml") << QString() - << (QStringList() << QString(QLatin1String("file://") + testFileUrl("moduleapi/qobjectModuleApiWriting.qml").toLocalFile() + QLatin1String(":14: Error: Cannot assign to read-only property \"qobjectTestProperty\""))) - << (QStringList() << "readOnlyProperty" << "writableProperty") - << (QVariantList() << 20 << 50) - << (QStringList() << "firstProperty" << "writableProperty") + << (QStringList() << QString(testFileUrl("moduleapi/qobjectModuleApiWriting.qml").toString() + QLatin1String(":15: Error: Cannot assign to read-only property \"qobjectTestProperty\""))) + << (QStringList() << "readOnlyProperty" << "writableProperty" << "writableFinalProperty") + << (QVariantList() << 20 << 50 << 10) + << (QStringList() << "firstProperty" << "secondProperty") << (QVariantList() << 30 << 30) - << (QStringList() << "readOnlyProperty" << "writableProperty") - << (QVariantList() << 20 << 30); + << (QStringList() << "readOnlyProperty" << "writableProperty" << "writableFinalProperty") + << (QVariantList() << 20 << 30 << 30); QTest::newRow("script, writing + readonly constraints") << testFileUrl("moduleapi/scriptModuleApiWriting.qml") << QString() - << (QStringList() << QString(QLatin1String("file://") + testFileUrl("moduleapi/scriptModuleApiWriting.qml").toLocalFile() + QLatin1String(":21: Error: Cannot assign to read-only property \"scriptTestProperty\""))) + << (QStringList() << QString(testFileUrl("moduleapi/scriptModuleApiWriting.qml").toString() + QLatin1String(":21: Error: Cannot assign to read-only property \"scriptTestProperty\""))) << (QStringList() << "readBack" << "unchanged") << (QVariantList() << 13 << 42) << (QStringList() << "firstProperty" << "secondProperty") @@ -3210,35 +3233,35 @@ void tst_qqmlecmascript::importScripts_data() QTest::newRow("parent scope shouldn't be inherited by import with imports") << testFileUrl("jsimportfail/failOne.qml") << QString() - << (QStringList() << QString(QLatin1String("file://") + testFileUrl("jsimportfail/failOne.qml").toLocalFile() + QLatin1String(":6: TypeError: Cannot call method 'greetingString' of undefined"))) + << (QStringList() << QString(testFileUrl("jsimportfail/failOne.qml").toString() + QLatin1String(":6: TypeError: Cannot call method 'greetingString' of undefined"))) << (QStringList() << QLatin1String("importScriptFunctionValue")) << (QVariantList() << QVariant(QString())); QTest::newRow("javascript imports in an import should be private to the import scope") << testFileUrl("jsimportfail/failTwo.qml") << QString() - << (QStringList() << QString(QLatin1String("file://") + testFileUrl("jsimportfail/failTwo.qml").toLocalFile() + QLatin1String(":6: ReferenceError: Can't find variable: ImportOneJs"))) + << (QStringList() << QString(testFileUrl("jsimportfail/failTwo.qml").toString() + QLatin1String(":6: ReferenceError: ImportOneJs is not defined"))) << (QStringList() << QLatin1String("importScriptFunctionValue")) << (QVariantList() << QVariant(QString())); QTest::newRow("module imports in an import should be private to the import scope") << testFileUrl("jsimportfail/failThree.qml") << QString() - << (QStringList() << QString(QLatin1String("file://") + testFileUrl("jsimportfail/failThree.qml").toLocalFile() + QLatin1String(":7: TypeError: Cannot read property 'JsQtTest' of undefined"))) + << (QStringList() << QString(testFileUrl("jsimportfail/failThree.qml").toString() + QLatin1String(":7: TypeError: Cannot read property 'JsQtTest' of undefined"))) << (QStringList() << QLatin1String("importedModuleAttachedPropertyValue")) << (QVariantList() << QVariant(false)); QTest::newRow("typenames in an import should be private to the import scope") << testFileUrl("jsimportfail/failFour.qml") << QString() - << (QStringList() << QString(QLatin1String("file://") + testFileUrl("jsimportfail/failFour.qml").toLocalFile() + QLatin1String(":6: ReferenceError: Can't find variable: JsQtTest"))) + << (QStringList() << QString(testFileUrl("jsimportfail/failFour.qml").toString() + QLatin1String(":6: ReferenceError: JsQtTest is not defined"))) << (QStringList() << QLatin1String("importedModuleEnumValue")) << (QVariantList() << QVariant(0)); QTest::newRow("import with imports has it's own activation scope") << testFileUrl("jsimportfail/failFive.qml") << QString() - << (QStringList() << QString(QLatin1String("file://") + testFileUrl("jsimportfail/importWithImports.js").toLocalFile() + QLatin1String(":8: ReferenceError: Can't find variable: Component"))) + << (QStringList() << QString(testFileUrl("jsimportfail/importWithImports.js").toString() + QLatin1String(":8: ReferenceError: Component is not defined"))) << (QStringList() << QLatin1String("componentError")) << (QVariantList() << QVariant(0)); @@ -3252,7 +3275,7 @@ void tst_qqmlecmascript::importScripts_data() QTest::newRow("pragma library imports shouldn't inherit parent imports or scope") << testFileUrl("jsimportfail/testImportPragmaLibrary.qml") << QString() - << (QStringList() << QString(QLatin1String("file://") + testFileUrl("jsimportfail/importPragmaLibrary.js").toLocalFile() + QLatin1String(":6: ReferenceError: Can't find variable: Component"))) + << (QStringList() << QString(testFileUrl("jsimportfail/importPragmaLibrary.js").toString() + QLatin1String(":6: ReferenceError: Component is not defined"))) << (QStringList() << QLatin1String("testValue")) << (QVariantList() << QVariant(0)); @@ -3889,6 +3912,15 @@ void tst_qqmlecmascript::propertyVarOwnership() delete object; } + // Garbage collection cannot result in attempted dereference of empty handle + { + QQmlComponent component(&engine, testFileUrl("propertyVarOwnership.5.qml")); + QObject *object = component.create(); + QVERIFY(object != 0); + QMetaObject::invokeMethod(object, "runTest"); + QCOMPARE(object->property("test").toBool(), true); + delete object; + } } void tst_qqmlecmascript::propertyVarImplicitOwnership() @@ -5028,13 +5060,13 @@ void tst_qqmlecmascript::functionAssignment_fromBinding() QQmlComponent component(&engine, testFileUrl("functionAssignment.1.qml")); QString url = component.url().toString(); - QString w1 = url + ":4: Unable to assign a function to a property of any type other than var."; - QString w2 = url + ":5: Invalid use of Qt.binding() in a binding declaration."; - QString w3 = url + ":6: Invalid use of Qt.binding() in a binding declaration."; + QString w1 = url + ":4:25: Unable to assign a function to a property of any type other than var."; + QString w2 = url + ":5:25: Invalid use of Qt.binding() in a binding declaration."; + QString w3 = url + ":6:21: Invalid use of Qt.binding() in a binding declaration."; QTest::ignoreMessage(QtWarningMsg, w1.toLatin1().constData()); QTest::ignoreMessage(QtWarningMsg, w2.toLatin1().constData()); QTest::ignoreMessage(QtWarningMsg, w3.toLatin1().constData()); - + MyQmlObject *o = qobject_cast<MyQmlObject *>(component.create()); QVERIFY(o != 0); @@ -5090,11 +5122,11 @@ void tst_qqmlecmascript::functionAssignmentfromJS_invalid() QVERIFY(!o->property("a").isValid()); QString url = component.url().toString(); - QString warning = url + ":67: Unable to assign QString to int"; + QString warning = url + ":67:17: Unable to assign QString to int"; QTest::ignoreMessage(QtWarningMsg, warning.toLatin1().constData()); o->setProperty("assignWrongType", true); - warning = url + ":71: Unable to assign QString to int"; + warning = url + ":71:29: Unable to assign QString to int"; QTest::ignoreMessage(QtWarningMsg, warning.toLatin1().constData()); o->setProperty("assignWrongTypeToValueType", true); @@ -5404,17 +5436,9 @@ void tst_qqmlecmascript::typeOf() { QQmlComponent component(&engine, testFileUrl("typeOf.qml")); - // These warnings should not happen once QTBUG-21864 is fixed - QString warning1 = component.url().toString() + QLatin1String(":16: Error: Cannot assign [undefined] to QString"); - QString warning2 = component.url().resolved(QUrl("typeOf.js")).toString() + QLatin1String(":1: ReferenceError: Can't find variable: a"); - - QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1)); - QTest::ignoreMessage(QtWarningMsg, qPrintable(warning2)); - QObject *o = component.create(); QVERIFY(o != 0); - QEXPECT_FAIL("", "QTBUG-21864", Abort); QCOMPARE(o->property("test1").toString(), QLatin1String("undefined")); QCOMPARE(o->property("test2").toString(), QLatin1String("object")); QCOMPARE(o->property("test3").toString(), QLatin1String("number")); @@ -5428,6 +5452,14 @@ void tst_qqmlecmascript::typeOf() delete o; } +void tst_qqmlecmascript::qtbug_24448() +{ + QQmlComponent component(&engine, testFileUrl("qtbug_24448.qml")); + QScopedPointer<QObject> o(component.create()); + QVERIFY(o != 0); + QVERIFY(o->property("test").toBool()); +} + void tst_qqmlecmascript::sharedAttachedObject() { QQmlComponent component(&engine, testFileUrl("sharedAttachedObject.qml")); @@ -5578,9 +5610,9 @@ void tst_qqmlecmascript::revisionErrors() QQmlComponent component(&engine, testFileUrl("metaobjectRevisionErrors.qml")); QString url = component.url().toString(); - QString warning1 = url + ":8: ReferenceError: Can't find variable: prop2"; - QString warning2 = url + ":11: ReferenceError: Can't find variable: prop2"; - QString warning3 = url + ":13: ReferenceError: Can't find variable: method2"; + QString warning1 = url + ":8: ReferenceError: prop2 is not defined"; + QString warning2 = url + ":11: ReferenceError: prop2 is not defined"; + QString warning3 = url + ":13: ReferenceError: method2 is not defined"; QTest::ignoreMessage(QtWarningMsg, warning1.toLatin1().constData()); QTest::ignoreMessage(QtWarningMsg, warning2.toLatin1().constData()); @@ -5596,11 +5628,11 @@ void tst_qqmlecmascript::revisionErrors() // MyRevisionedSubclass 1.0 uses MyRevisionedClass revision 0 // method2, prop2 from MyRevisionedClass not available // method4, prop4 from MyRevisionedSubclass not available - QString warning1 = url + ":8: ReferenceError: Can't find variable: prop2"; - QString warning2 = url + ":14: ReferenceError: Can't find variable: prop2"; - QString warning3 = url + ":10: ReferenceError: Can't find variable: prop4"; - QString warning4 = url + ":16: ReferenceError: Can't find variable: prop4"; - QString warning5 = url + ":20: ReferenceError: Can't find variable: method2"; + QString warning1 = url + ":8: ReferenceError: prop2 is not defined"; + QString warning2 = url + ":14: ReferenceError: prop2 is not defined"; + QString warning3 = url + ":10: ReferenceError: prop4 is not defined"; + QString warning4 = url + ":16: ReferenceError: prop4 is not defined"; + QString warning5 = url + ":20: ReferenceError: method2 is not defined"; QTest::ignoreMessage(QtWarningMsg, warning1.toLatin1().constData()); QTest::ignoreMessage(QtWarningMsg, warning2.toLatin1().constData()); @@ -5617,9 +5649,9 @@ void tst_qqmlecmascript::revisionErrors() // MyRevisionedSubclass 1.1 uses MyRevisionedClass revision 1 // All properties/methods available, except MyRevisionedBaseClassUnregistered rev 1 - QString warning1 = url + ":30: ReferenceError: Can't find variable: methodD"; - QString warning2 = url + ":10: ReferenceError: Can't find variable: propD"; - QString warning3 = url + ":20: ReferenceError: Can't find variable: propD"; + QString warning1 = url + ":30: ReferenceError: methodD is not defined"; + QString warning2 = url + ":10: ReferenceError: propD is not defined"; + QString warning3 = url + ":20: ReferenceError: propD is not defined"; QTest::ignoreMessage(QtWarningMsg, warning1.toLatin1().constData()); QTest::ignoreMessage(QtWarningMsg, warning2.toLatin1().constData()); QTest::ignoreMessage(QtWarningMsg, warning3.toLatin1().constData()); diff --git a/tests/auto/qml/qqmlincubator/tst_qqmlincubator.cpp b/tests/auto/qml/qqmlincubator/tst_qqmlincubator.cpp index fc54f715c9..54a31aef1d 100644 --- a/tests/auto/qml/qqmlincubator/tst_qqmlincubator.cpp +++ b/tests/auto/qml/qqmlincubator/tst_qqmlincubator.cpp @@ -76,6 +76,7 @@ private slots: void nestedComponent(); void chainedAsynchronousIfNested(); void chainedAsynchronousIfNestedOnCompleted(); + void chainedAsynchronousClear(); void selfDelete(); void contextDelete(); @@ -934,6 +935,122 @@ void tst_qqmlincubator::chainedAsynchronousIfNestedOnCompleted() QVERIFY(incubator3.isReady()); } +// Checks that new AsynchronousIfNested incubators can be correctly cleared if started in +// componentCompleted(). +void tst_qqmlincubator::chainedAsynchronousClear() +{ + SelfRegisteringType::clearMe(); + + QQmlComponent component(&engine, testFileUrl("chainInCompletion.qml")); + QVERIFY(component.isReady()); + + QQmlComponent c1(&engine, testFileUrl("chainedAsynchronousIfNested.qml")); + QVERIFY(c1.isReady()); + + struct MyIncubator : public QQmlIncubator { + MyIncubator(MyIncubator *next, QQmlComponent *component, QQmlContext *ctxt) + : QQmlIncubator(AsynchronousIfNested), next(next), component(component), ctxt(ctxt) {} + + protected: + virtual void statusChanged(Status s) { + if (s == Ready && next) { + component->create(*next, 0, ctxt); + } + } + + private: + MyIncubator *next; + QQmlComponent *component; + QQmlContext *ctxt; + }; + + struct CallbackData { + CallbackData(QQmlComponent *c, MyIncubator *i, QQmlContext *ct) + : component(c), incubator(i), ctxt(ct) {} + QQmlComponent *component; + MyIncubator *incubator; + QQmlContext *ctxt; + static void callback(CompletionCallbackType *, void *data) { + CallbackData *d = (CallbackData *)data; + d->component->create(*d->incubator, 0, d->ctxt); + } + }; + + QQmlIncubator incubator(QQmlIncubator::Asynchronous); + component.create(incubator); + + QVERIFY(incubator.isLoading()); + QVERIFY(SelfRegisteringType::me() == 0); + + while (SelfRegisteringType::me() == 0 && incubator.isLoading()) { + bool b = false; + controller.incubateWhile(&b); + } + + QVERIFY(SelfRegisteringType::me() != 0); + QVERIFY(incubator.isLoading()); + + MyIncubator incubator3(0, &c1, qmlContext(SelfRegisteringType::me())); + MyIncubator incubator2(&incubator3, &c1, qmlContext(SelfRegisteringType::me())); + MyIncubator incubator1(&incubator2, &c1, qmlContext(SelfRegisteringType::me())); + + // start incubator1 in componentComplete + CallbackData cd(&c1, &incubator1, qmlContext(SelfRegisteringType::me())); + CompletionCallbackType::registerCallback(&CallbackData::callback, &cd); + + while (!incubator1.isLoading()) { + QVERIFY(incubator.isLoading()); + QVERIFY(incubator2.isNull()); + QVERIFY(incubator3.isNull()); + + bool b = false; + controller.incubateWhile(&b); + } + + QVERIFY(incubator.isLoading()); + QVERIFY(incubator1.isLoading()); + QVERIFY(incubator2.isNull()); + QVERIFY(incubator3.isNull()); + + while (incubator1.isLoading()) { + QVERIFY(incubator.isLoading()); + QVERIFY(incubator1.isLoading()); + QVERIFY(incubator2.isNull()); + QVERIFY(incubator3.isNull()); + + bool b = false; + controller.incubateWhile(&b); + } + + QVERIFY(incubator.isLoading()); + QVERIFY(incubator1.isReady()); + QVERIFY(incubator2.isLoading()); + QVERIFY(incubator3.isNull()); + + while (incubator2.isLoading()) { + QVERIFY(incubator.isLoading()); + QVERIFY(incubator1.isReady()); + QVERIFY(incubator2.isLoading()); + QVERIFY(incubator3.isNull()); + + bool b = false; + controller.incubateWhile(&b); + } + + QVERIFY(incubator.isLoading()); + QVERIFY(incubator1.isReady()); + QVERIFY(incubator2.isReady()); + QVERIFY(incubator3.isLoading()); + + // Any in loading state will become null when cleared. + incubator.clear(); + + QVERIFY(incubator.isNull()); + QVERIFY(incubator1.isReady()); + QVERIFY(incubator2.isReady()); + QVERIFY(incubator3.isNull()); +} + void tst_qqmlincubator::selfDelete() { struct MyIncubator : public QQmlIncubator { diff --git a/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp b/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp index 10b9b83999..aa22450bd3 100644 --- a/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp +++ b/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp @@ -143,7 +143,7 @@ void tst_qqmlproperty::qmlmetaproperty() { QQmlProperty prop; - QWeakPointer<QQmlBinding> binding(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext())); + QWeakPointer<QQmlAbstractBinding> binding(QQmlAbstractBinding::getPointer(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext()))); QVERIFY(binding != 0); QWeakPointer<QQmlExpression> expression(new QQmlExpression()); QVERIFY(expression != 0); @@ -246,7 +246,7 @@ void tst_qqmlproperty::qmlmetaproperty_object() { QQmlProperty prop(&object); - QWeakPointer<QQmlBinding> binding(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext())); + QWeakPointer<QQmlAbstractBinding> binding(QQmlAbstractBinding::getPointer(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext()))); QVERIFY(binding != 0); QWeakPointer<QQmlExpression> expression(new QQmlExpression()); QVERIFY(expression != 0); @@ -292,8 +292,8 @@ void tst_qqmlproperty::qmlmetaproperty_object() { QQmlProperty prop(&dobject); - QWeakPointer<QQmlBinding> binding(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext())); - binding.data()->setTarget(prop); + QWeakPointer<QQmlAbstractBinding> binding(QQmlAbstractBinding::getPointer(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext()))); + static_cast<QQmlBinding *>(binding.data())->setTarget(prop); QVERIFY(binding != 0); QWeakPointer<QQmlExpression> expression(new QQmlExpression()); QVERIFY(expression != 0); @@ -347,7 +347,7 @@ void tst_qqmlproperty::qmlmetaproperty_object_string() { QQmlProperty prop(&object, QString("defaultProperty")); - QWeakPointer<QQmlBinding> binding(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext())); + QWeakPointer<QQmlAbstractBinding> binding(QQmlAbstractBinding::getPointer(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext()))); QVERIFY(binding != 0); QWeakPointer<QQmlExpression> expression(new QQmlExpression()); QVERIFY(expression != 0); @@ -393,8 +393,8 @@ void tst_qqmlproperty::qmlmetaproperty_object_string() { QQmlProperty prop(&dobject, QString("defaultProperty")); - QWeakPointer<QQmlBinding> binding(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext())); - binding.data()->setTarget(prop); + QWeakPointer<QQmlAbstractBinding> binding(QQmlAbstractBinding::getPointer(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext()))); + static_cast<QQmlBinding *>(binding.data())->setTarget(prop); QVERIFY(binding != 0); QWeakPointer<QQmlExpression> expression(new QQmlExpression()); QVERIFY(expression != 0); @@ -442,8 +442,8 @@ void tst_qqmlproperty::qmlmetaproperty_object_string() { QQmlProperty prop(&dobject, QString("onClicked")); - QWeakPointer<QQmlBinding> binding(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext())); - binding.data()->setTarget(prop); + QWeakPointer<QQmlAbstractBinding> binding(QQmlAbstractBinding::getPointer(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext()))); + static_cast<QQmlBinding *>(binding.data())->setTarget(prop); QVERIFY(binding != 0); QWeakPointer<QQmlExpression> expression(new QQmlExpression()); QVERIFY(expression != 0); @@ -490,8 +490,8 @@ void tst_qqmlproperty::qmlmetaproperty_object_string() { QQmlProperty prop(&dobject, QString("onPropertyWithNotifyChanged")); - QWeakPointer<QQmlBinding> binding(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext())); - binding.data()->setTarget(prop); + QWeakPointer<QQmlAbstractBinding> binding(QQmlAbstractBinding::getPointer(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext()))); + static_cast<QQmlBinding *>(binding.data())->setTarget(prop); QVERIFY(binding != 0); QWeakPointer<QQmlExpression> expression(new QQmlExpression()); QVERIFY(expression != 0); @@ -544,7 +544,7 @@ void tst_qqmlproperty::qmlmetaproperty_object_context() { QQmlProperty prop(&object, engine.rootContext()); - QWeakPointer<QQmlBinding> binding(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext())); + QWeakPointer<QQmlAbstractBinding> binding(QQmlAbstractBinding::getPointer(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext()))); QVERIFY(binding != 0); QWeakPointer<QQmlExpression> expression(new QQmlExpression()); QVERIFY(expression != 0); @@ -590,8 +590,8 @@ void tst_qqmlproperty::qmlmetaproperty_object_context() { QQmlProperty prop(&dobject, engine.rootContext()); - QWeakPointer<QQmlBinding> binding(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext())); - binding.data()->setTarget(prop); + QWeakPointer<QQmlAbstractBinding> binding(QQmlAbstractBinding::getPointer(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext()))); + static_cast<QQmlBinding *>(binding.data())->setTarget(prop); QVERIFY(binding != 0); QWeakPointer<QQmlExpression> expression(new QQmlExpression()); QVERIFY(expression != 0); @@ -645,7 +645,7 @@ void tst_qqmlproperty::qmlmetaproperty_object_string_context() { QQmlProperty prop(&object, QString("defaultProperty"), engine.rootContext()); - QWeakPointer<QQmlBinding> binding(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext())); + QWeakPointer<QQmlAbstractBinding> binding(QQmlAbstractBinding::getPointer(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext()))); QVERIFY(binding != 0); QWeakPointer<QQmlExpression> expression(new QQmlExpression()); QVERIFY(expression != 0); @@ -691,8 +691,8 @@ void tst_qqmlproperty::qmlmetaproperty_object_string_context() { QQmlProperty prop(&dobject, QString("defaultProperty"), engine.rootContext()); - QWeakPointer<QQmlBinding> binding(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext())); - binding.data()->setTarget(prop); + QWeakPointer<QQmlAbstractBinding> binding(QQmlAbstractBinding::getPointer(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext()))); + static_cast<QQmlBinding *>(binding.data())->setTarget(prop); QVERIFY(binding != 0); QWeakPointer<QQmlExpression> expression(new QQmlExpression()); QVERIFY(expression != 0); @@ -740,8 +740,8 @@ void tst_qqmlproperty::qmlmetaproperty_object_string_context() { QQmlProperty prop(&dobject, QString("onClicked"), engine.rootContext()); - QWeakPointer<QQmlBinding> binding(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext())); - binding.data()->setTarget(prop); + QWeakPointer<QQmlAbstractBinding> binding(QQmlAbstractBinding::getPointer(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext()))); + static_cast<QQmlBinding *>(binding.data())->setTarget(prop); QVERIFY(binding != 0); QWeakPointer<QQmlExpression> expression(new QQmlExpression()); QVERIFY(expression != 0); @@ -788,8 +788,8 @@ void tst_qqmlproperty::qmlmetaproperty_object_string_context() { QQmlProperty prop(&dobject, QString("onPropertyWithNotifyChanged"), engine.rootContext()); - QWeakPointer<QQmlBinding> binding(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext())); - binding.data()->setTarget(prop); + QWeakPointer<QQmlAbstractBinding> binding(QQmlAbstractBinding::getPointer(new QQmlBinding(QLatin1String("null"), 0, engine.rootContext()))); + static_cast<QQmlBinding *>(binding.data())->setTarget(prop); QVERIFY(binding != 0); QWeakPointer<QQmlExpression> expression(new QQmlExpression()); QVERIFY(expression != 0); @@ -1553,8 +1553,6 @@ void tst_qqmlproperty::crashOnValueProperty() delete engine; engine = 0; - QSKIP("QTBUG-24734: test accesses deleted QML engine from QQmlProperty::propertyTypeName()"); - QCOMPARE(p.propertyTypeName(), "int"); QCOMPARE(p.read(), QVariant(10)); p.write(QVariant(20)); diff --git a/tests/auto/qml/qqmlqt/data/TestComponent.2.qml b/tests/auto/qml/qqmlqt/data/TestComponent.2.qml new file mode 100644 index 0000000000..d6e99028b5 --- /dev/null +++ b/tests/auto/qml/qqmlqt/data/TestComponent.2.qml @@ -0,0 +1,592 @@ +import QtQuick 2.0 + +Item { + id: root + objectName: "root" + property int zero: 0 + + Item { + id: c1 + objectName: "c1" + property int one: zero + 1 + + Item { + id: c1c1 + objectName: "c1c1" + property bool two: c2c1c1.two + } + + Item { + id: c1c2 + objectName: "c1c2" + property string three: "three" + + Rectangle { + id: c1c2c3 + objectName: "c1c2c3" + property alias othercolor: c2c1.color + color: if (c2c1.color == Qt.rgba(0,0,1)) Qt.rgba(1,0,0); else Qt.rgba(0,1,0); + } + } + } + + Item { + id: c2 + objectName: "c2" + property string two: "two" + + Rectangle { + id: c2c1 + objectName: "c2c1" + property string three: "2" + c1c2.three + color: "blue" + + MouseArea { + id: c2c1c1 + objectName: "c2c1c1" + property bool two: false + onClicked: two = !two + } + + Item { + id: c2c1c2 + objectName: "c2c1c2" + property string three: "1" + parent.three + } + } + } + + Item { + id: c3 + objectName: "c3" + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + } + + property alias c1one: c1.one + property bool success: true + Component.onCompleted: { + // test state after initial bindings evaluation + if (zero != 0) success = false; + if (c1.one != 1) success = false; + if (c1c1.two != false) success = false; + if (c1c2.three != "three") success = false; + if (c1c2c3.color != Qt.rgba(1,0,0)) success = false; + if (c2.two != "two") success = false; + if (c2c1.three != "2three") success = false; + if (c2c1.color != Qt.rgba(0,0,1)) success = false; + if (c2c1c1.two != false) success = false; + if (c2c1c2.three != "12three") success = false; + if (c3.children.length != 500) success = false; + + // now retrigger bindings evaluation + root.zero = 5; + if (c1.one != 6) success = false; + c2c1c1.two = true; + if (c1c1.two != true) success = false; + c1c2.three = "3"; + if (c2c1.three != "23") success = false; + if (c2c1c2.three != "123") success = false; + c2c1.color = Qt.rgba(1,0,0); + if (c1c2c3.color != Qt.rgba(0,1,0)) success = false; + if (c1c2c3.othercolor != Qt.rgba(1,0,0)) success = false; + } +} diff --git a/tests/auto/qml/qqmlqt/data/TestComponent.3.qml b/tests/auto/qml/qqmlqt/data/TestComponent.3.qml new file mode 100644 index 0000000000..81ea07cb88 --- /dev/null +++ b/tests/auto/qml/qqmlqt/data/TestComponent.3.qml @@ -0,0 +1,89 @@ +import QtQuick 2.0 + +Item { + id: root + objectName: "root" + property int zero: 0 + property int one: 1 + + Item { + id: c1 + objectName: "c1" + property int one: zero + parent.one + + Item { + id: c1c1 + objectName: "c1c1" + property bool two: c2c1c1.two + } + + Item { + id: c1c2 + objectName: "c1c2" + property string three: "three" + + Rectangle { + id: c1c2c3 + objectName: "c1c2c3" + property alias othercolor: c2c1.color + color: if (c2c1.color == Qt.rgba(0,0,1)) Qt.rgba(1,0,0); else Qt.rgba(0,1,0); + } + } + } + + Item { + id: c2 + objectName: "c2" + property string two: "two" + + Rectangle { + id: c2c1 + objectName: "c2c1" + property string three: "2" + c1c2.three + color: "blue" + + MouseArea { + id: c2c1c1 + objectName: "c2c1c1" + property bool two: false + onClicked: two = !two + } + + Item { + id: c2c1c2 + objectName: "c2c1c2" + property string three: "1" + parent.three + } + } + } + + property alias c1one: c1.one + property bool success: true + Component.onCompleted: { + // test state after initial bindings evaluation + if (zero != 0) success = false; + if (c1.one != 1) success = false; + if (c1c1.two != false) success = false; + if (c1c2.three != "three") success = false; + if (c1c2c3.color != Qt.rgba(1,0,0)) success = false; + if (c2.two != "two") success = false; + if (c2c1.three != "2three") success = false; + if (c2c1.color != Qt.rgba(0,0,1)) success = false; + if (c2c1c1.two != false) success = false; + if (c2c1c2.three != "12three") success = false; + + // now retrigger bindings evaluation + root.zero = 5; + if (c1.one != 6) success = false; + root.one = 50; + if (c1.one != 55) success = false; + c2c1c1.two = true; + if (c1c1.two != true) success = false; + c1c2.three = "3"; + if (c2c1.three != "23") success = false; + if (c2c1c2.three != "123") success = false; + c2c1.color = Qt.rgba(1,0,0); + if (c1c2c3.color != Qt.rgba(0,1,0)) success = false; + if (c1c2c3.othercolor != Qt.rgba(1,0,0)) success = false; + } +} diff --git a/tests/auto/qml/qqmlqt/data/TestComponent.qml b/tests/auto/qml/qqmlqt/data/TestComponent.qml new file mode 100644 index 0000000000..64cec1cd06 --- /dev/null +++ b/tests/auto/qml/qqmlqt/data/TestComponent.qml @@ -0,0 +1,534 @@ +import QtQuick 2.0 + +Item { + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} +} diff --git a/tests/auto/qml/qqmlqt/data/createComponent.2.qml b/tests/auto/qml/qqmlqt/data/createComponent.2.qml new file mode 100644 index 0000000000..36e2b23c9f --- /dev/null +++ b/tests/auto/qml/qqmlqt/data/createComponent.2.qml @@ -0,0 +1,27 @@ +import QtQuick 2.0 + +Item { + property bool success: false + property var syncComponent + property var asyncComponent + + function asyncStatusChanged() { + if (asyncComponent.status == Component.Ready && syncComponent.status == Component.Ready) { + success = true; + var ao = asyncComponent.createObject(); + var so = syncComponent.createObject(); + if (ao.c1one != 6) success = false; + if (so.c1one != 55) success = false; + ao.destroy(); + so.destroy(); + } + } + + Component.onCompleted: { + asyncComponent = Qt.createComponent("TestComponent.2.qml", Component.Asynchronous); + if (asyncComponent.status != Component.Loading) + return; + asyncComponent.statusChanged.connect(asyncStatusChanged); + syncComponent = Qt.createComponent("TestComponent.3.qml", Component.PreferSynchronous); + } +} diff --git a/tests/auto/qml/qqmlqt/data/createComponent.qml b/tests/auto/qml/qqmlqt/data/createComponent.qml index 3ebc9f14f8..01b6490419 100644 --- a/tests/auto/qml/qqmlqt/data/createComponent.qml +++ b/tests/auto/qml/qqmlqt/data/createComponent.qml @@ -9,6 +9,14 @@ QtObject { property QtObject incorectArgCount1: Qt.createComponent() property QtObject incorectArgCount2: Qt.createComponent("main.qml", 10) + property bool asyncResult: false + property var asyncComponent + + function asyncStatusChanged() { + if (asyncComponent.status == Component.Ready) + asyncResult = true; + } + Component.onCompleted: { emptyArg = (Qt.createComponent("") == null); var r = Qt.createComponent("createComponentData.qml"); @@ -16,5 +24,10 @@ QtObject { var a = Qt.createComponent("http://www.example.com/test.qml"); absoluteUrl = a.url; + + asyncComponent = Qt.createComponent("TestComponent.qml", Component.Asynchronous); + if (asyncComponent.status != Component.Loading) + return; + asyncComponent.statusChanged.connect(asyncStatusChanged); } } diff --git a/tests/auto/qml/qqmlqt/tst_qqmlqt.cpp b/tests/auto/qml/qqmlqt/tst_qqmlqt.cpp index a679188cb7..d3dc3e7343 100644 --- a/tests/auto/qml/qqmlqt/tst_qqmlqt.cpp +++ b/tests/auto/qml/qqmlqt/tst_qqmlqt.cpp @@ -395,6 +395,7 @@ void tst_qqmlqt::md5() void tst_qqmlqt::createComponent() { + { QQmlComponent component(&engine, testFileUrl("createComponent.qml")); QString warning1 = component.url().toString() + ":9: Error: Qt.createComponent(): Invalid arguments"; @@ -408,7 +409,19 @@ void tst_qqmlqt::createComponent() QCOMPARE(object->property("absoluteUrl").toString(), QString("http://www.example.com/test.qml")); QCOMPARE(object->property("relativeUrl").toString(), testFileUrl("createComponentData.qml").toString()); + QTRY_VERIFY(object->property("asyncResult").toBool()); + delete object; + } + + // simultaneous sync and async compilation + { + QQmlComponent component(&engine, testFileUrl("createComponent.2.qml")); + QObject *object = component.create(); + QVERIFY(object != 0); + QTRY_VERIFY(object->property("success").toBool()); + delete object; + } } void tst_qqmlqt::createComponent_pragmaLibrary() diff --git a/tests/auto/qml/qqmlvaluetypes/tst_qqmlvaluetypes.cpp b/tests/auto/qml/qqmlvaluetypes/tst_qqmlvaluetypes.cpp index c37a42fee5..54791fc340 100644 --- a/tests/auto/qml/qqmlvaluetypes/tst_qqmlvaluetypes.cpp +++ b/tests/auto/qml/qqmlvaluetypes/tst_qqmlvaluetypes.cpp @@ -890,7 +890,7 @@ void tst_qqmlvaluetypes::bindingAssignment() // function assignment should fail without crashing { - QString warning1 = testFileUrl("bindingAssignment.2.qml").toString() + QLatin1String(":6: Invalid use of Qt.binding() in a binding declaration."); + QString warning1 = testFileUrl("bindingAssignment.2.qml").toString() + QLatin1String(":6:13: Invalid use of Qt.binding() in a binding declaration."); QString warning2 = testFileUrl("bindingAssignment.2.qml").toString() + QLatin1String(":10: Error: Cannot assign JavaScript function to value-type property"); QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1)); QTest::ignoreMessage(QtWarningMsg, qPrintable(warning2)); diff --git a/tests/auto/qml/qquickfolderlistmodel/qquickfolderlistmodel.pro b/tests/auto/qml/qquickfolderlistmodel/qquickfolderlistmodel.pro index 2726e20577..68c0d79f92 100644 --- a/tests/auto/qml/qquickfolderlistmodel/qquickfolderlistmodel.pro +++ b/tests/auto/qml/qquickfolderlistmodel/qquickfolderlistmodel.pro @@ -10,3 +10,5 @@ TESTDATA = data/* CONFIG += parallel_test QT += core-private gui-private qml-private testlib + +win32:CONFIG += insignificant_test # QTBUG-24777 diff --git a/tests/auto/qml/qquickworkerscript/tst_qquickworkerscript.cpp b/tests/auto/qml/qquickworkerscript/tst_qquickworkerscript.cpp index 6569b877fe..2eadc461cf 100644 --- a/tests/auto/qml/qquickworkerscript/tst_qquickworkerscript.cpp +++ b/tests/auto/qml/qquickworkerscript/tst_qquickworkerscript.cpp @@ -275,7 +275,7 @@ void tst_QQuickWorkerScript::scriptError_onCall() QVERIFY(QMetaObject::invokeMethod(worker, "testSend", Q_ARG(QVariant, value))); QTRY_COMPARE(qquickworkerscript_lastWarning, - testFileUrl("script_error_onCall.js").toString() + QLatin1String(":4: ReferenceError: Can't find variable: getData")); + testFileUrl("script_error_onCall.js").toString() + QLatin1String(":4: ReferenceError: getData is not defined")); qInstallMsgHandler(previousMsgHandler); qApp->processEvents(); diff --git a/tests/auto/qml/v4/data/equals.qml b/tests/auto/qml/v4/data/equals.qml new file mode 100644 index 0000000000..c32603cc7e --- /dev/null +++ b/tests/auto/qml/v4/data/equals.qml @@ -0,0 +1,48 @@ +import QtQuick 2.0 + +QtObject { + property QtObject myprop1: null + property QtObject myprop2: QtObject {} + property real zero: 0 + property bool falseProp: false + + property bool test1: myprop1 == false + property bool test2: myprop1 == null + property bool test3: 5 == myprop1 + property bool test4: null == myprop1 + property bool test5: myprop1 != false + property bool test6: myprop1 != null + property bool test7: 5 != myprop1 + property bool test8: null != myprop1 + + property bool test9: myprop2 == false + property bool test10: myprop2 == null + property bool test11: 5 == myprop2 + property bool test12: null == myprop2 + property bool test13: myprop2 != false + property bool test14: myprop2 != null + property bool test15: 5 != myprop2 + property bool test16: null != myprop2 + + property bool test17: myprop1 == myprop1 + property bool test18: myprop1 != myprop1 + property bool test19: myprop1 == myprop2 + property bool test20: myprop1 != myprop2 + property bool test21: myprop2 == myprop2 + property bool test22: myprop2 != myprop2 + + property bool test23: myprop1 == "hello" + property bool test24: myprop1 != "hello" + property bool test25: myprop2 == "hello" + property bool test26: myprop2 != "hello" + + property bool test27: falseProp == zero + property bool test28: falseProp != zero + property bool test29: falseProp == 1 + property bool test30: falseProp != 1 + property bool test31: true == zero + property bool test32: true != zero + property bool test33: true == 1 + property bool test34: true != 1 +} + diff --git a/tests/auto/qml/v4/data/logicalAnd.2.qml b/tests/auto/qml/v4/data/logicalAnd.2.qml new file mode 100644 index 0000000000..cc3d75bd90 --- /dev/null +++ b/tests/auto/qml/v4/data/logicalAnd.2.qml @@ -0,0 +1,6 @@ +import Qt.v4 1.0 + +Result { + property string s: "foo" && "bar" + result: s == "bar" +} diff --git a/tests/auto/qml/v4/data/logicalAnd.3.qml b/tests/auto/qml/v4/data/logicalAnd.3.qml new file mode 100644 index 0000000000..6527f05d07 --- /dev/null +++ b/tests/auto/qml/v4/data/logicalAnd.3.qml @@ -0,0 +1,8 @@ +import Qt.v4 1.0 + +Result { + property string s: "" + property bool flag: true + + result: (s && flag) == "" +} diff --git a/tests/auto/qml/v4/data/logicalAnd.4.qml b/tests/auto/qml/v4/data/logicalAnd.4.qml new file mode 100644 index 0000000000..fbcee91699 --- /dev/null +++ b/tests/auto/qml/v4/data/logicalAnd.4.qml @@ -0,0 +1,8 @@ +import Qt.v4 1.0 + +Result { + property string s: "foo" + property bool flag: true + + result: (!flag && s) == false +} diff --git a/tests/auto/qml/v4/data/logicalAnd.5.qml b/tests/auto/qml/v4/data/logicalAnd.5.qml new file mode 100644 index 0000000000..f0698463fe --- /dev/null +++ b/tests/auto/qml/v4/data/logicalAnd.5.qml @@ -0,0 +1,7 @@ +import Qt.v4 1.0 + +Result { + property bool flag: true + + result: (null && flag) == null +} diff --git a/tests/auto/qml/v4/data/logicalAnd.6.qml b/tests/auto/qml/v4/data/logicalAnd.6.qml new file mode 100644 index 0000000000..e98b5c99cd --- /dev/null +++ b/tests/auto/qml/v4/data/logicalAnd.6.qml @@ -0,0 +1,9 @@ +import Qt.v4 1.0 + +Result { + property string s: "" + property bool flag: true + property string subresult: s && flag + + result: subresult === "" +} diff --git a/tests/auto/qml/v4/data/logicalAnd.7.qml b/tests/auto/qml/v4/data/logicalAnd.7.qml new file mode 100644 index 0000000000..0f19d3fb40 --- /dev/null +++ b/tests/auto/qml/v4/data/logicalAnd.7.qml @@ -0,0 +1,9 @@ +import Qt.v4 1.0 + +Result { + property real nan: Number.NaN + property bool flag: true + property real subresult: nan && flag + + result: isNaN(subresult) +} diff --git a/tests/auto/qml/v4/data/logicalAnd.qml b/tests/auto/qml/v4/data/logicalAnd.qml new file mode 100644 index 0000000000..40fc3616c2 --- /dev/null +++ b/tests/auto/qml/v4/data/logicalAnd.qml @@ -0,0 +1,6 @@ +import Qt.v4 1.0 + +Result { + property int a: 10 + result: a == 10 && a == 2 +} diff --git a/tests/auto/qml/v4/data/nestedLogicalAnd.qml b/tests/auto/qml/v4/data/nestedLogicalAnd.qml new file mode 100644 index 0000000000..1358fcea64 --- /dev/null +++ b/tests/auto/qml/v4/data/nestedLogicalAnd.qml @@ -0,0 +1,14 @@ +import Qt.v4 1.0 + +Result { + property bool val1: false + property bool val2: true + property bool val3: false + + property bool b1: (true && true && false) + property bool b2: (true && (false && true)) + property bool b3: ((true && true) && true) + property bool b4: (val1 && (val2 && val3)) ? true : false + + result: !b1 && !b2 && b3 && !b4 +} diff --git a/tests/auto/qml/v4/data/strictEquals.qml b/tests/auto/qml/v4/data/strictEquals.qml new file mode 100644 index 0000000000..3f4d0d8b3f --- /dev/null +++ b/tests/auto/qml/v4/data/strictEquals.qml @@ -0,0 +1,48 @@ +import QtQuick 2.0 + +QtObject { + property QtObject myprop1: null + property QtObject myprop2: QtObject {} + property real zero: 0 + property bool falseProp: false + + property bool test1: myprop1 === false + property bool test2: myprop1 === null + property bool test3: 5 === myprop1 + property bool test4: null === myprop1 + property bool test5: myprop1 !== false + property bool test6: myprop1 !== null + property bool test7: 5 !== myprop1 + property bool test8: null !== myprop1 + + property bool test9: myprop2 === false + property bool test10: myprop2 === null + property bool test11: 5 === myprop2 + property bool test12: null === myprop2 + property bool test13: myprop2 !== false + property bool test14: myprop2 !== null + property bool test15: 5 !== myprop2 + property bool test16: null !== myprop2 + + property bool test17: myprop1 === myprop1 + property bool test18: myprop1 !== myprop1 + property bool test19: myprop1 === myprop2 + property bool test20: myprop1 !== myprop2 + property bool test21: myprop2 === myprop2 + property bool test22: myprop2 !== myprop2 + + property bool test23: myprop1 === "hello" + property bool test24: myprop1 !== "hello" + property bool test25: myprop2 === "hello" + property bool test26: myprop2 !== "hello" + + property bool test27: falseProp === zero + property bool test28: falseProp !== zero + property bool test29: falseProp === 1 + property bool test30: falseProp !== 1 + property bool test31: true === zero + property bool test32: true !== zero + property bool test33: true === 1 + property bool test34: true !== 1 +} + diff --git a/tests/auto/qml/v4/tst_v4.cpp b/tests/auto/qml/v4/tst_v4.cpp index 91a32268cf..1c89617157 100644 --- a/tests/auto/qml/v4/tst_v4.cpp +++ b/tests/auto/qml/v4/tst_v4.cpp @@ -64,6 +64,8 @@ private slots: void unnecessaryReeval(); void logicalOr(); void nestedLogicalOr(); + void logicalAnd(); + void nestedLogicalAnd(); void conditionalExpr(); void qtscript(); void qtscript_data(); @@ -122,6 +124,8 @@ void tst_v4::qtscript_data() { QTest::addColumn<QString>("file"); + QTest::newRow("equals") << "equals.qml"; + QTest::newRow("strict equals") << "strictEquals.qml"; QTest::newRow("qreal -> int rounding") << "qrealToIntRounding.qml"; QTest::newRow("exception on fetch") << "fetchException.qml"; QTest::newRow("logical or") << "logicalOr.qml"; @@ -208,6 +212,115 @@ void tst_v4::nestedLogicalOr() delete o; } +void tst_v4::logicalAnd() +{ + { + QQmlComponent component(&engine, testFileUrl("logicalAnd.qml")); + + QObject *o = component.create(); + QVERIFY(o != 0); + + ResultObject *ro = qobject_cast<ResultObject *>(o); + QVERIFY(ro != 0); + + QCOMPARE(ro->result(), 0); + delete o; + } + + { + QQmlComponent component(&engine, testFileUrl("logicalAnd.2.qml")); + + QObject *o = component.create(); + QVERIFY(o != 0); + + ResultObject *ro = qobject_cast<ResultObject *>(o); + QVERIFY(ro != 0); + + QCOMPARE(ro->result(), 1); + delete o; + } + + { + QQmlComponent component(&engine, testFileUrl("logicalAnd.3.qml")); + + QObject *o = component.create(); + QVERIFY(o != 0); + + ResultObject *ro = qobject_cast<ResultObject *>(o); + QVERIFY(ro != 0); + + QCOMPARE(ro->result(), 1); + delete o; + } + + { + // QTBUG-24660 + QQmlComponent component(&engine, testFileUrl("logicalAnd.4.qml")); + + QObject *o = component.create(); + QVERIFY(o != 0); + + ResultObject *ro = qobject_cast<ResultObject *>(o); + QVERIFY(ro != 0); + + QCOMPARE(ro->result(), 1); + delete o; + } + + { + QQmlComponent component(&engine, testFileUrl("logicalAnd.5.qml")); + + QObject *o = component.create(); + QVERIFY(o != 0); + + ResultObject *ro = qobject_cast<ResultObject *>(o); + QVERIFY(ro != 0); + + QCOMPARE(ro->result(), 1); + delete o; + } + + { + QQmlComponent component(&engine, testFileUrl("logicalAnd.6.qml")); + + QObject *o = component.create(); + QVERIFY(o != 0); + + ResultObject *ro = qobject_cast<ResultObject *>(o); + QVERIFY(ro != 0); + + QCOMPARE(ro->result(), 1); + delete o; + } + + { + QQmlComponent component(&engine, testFileUrl("logicalAnd.7.qml")); + + QObject *o = component.create(); + QVERIFY(o != 0); + + ResultObject *ro = qobject_cast<ResultObject *>(o); + QVERIFY(ro != 0); + + QCOMPARE(ro->result(), 1); + delete o; + } +} + +void tst_v4::nestedLogicalAnd() +{ + QQmlComponent component(&engine, testFileUrl("nestedLogicalAnd.qml")); + + QObject *o = component.create(); + QVERIFY(o != 0); + + ResultObject *ro = qobject_cast<ResultObject *>(o); + QVERIFY(ro != 0); + + QCOMPARE(ro->result(), 1); + delete o; +} + void tst_v4::conditionalExpr() { { |