From 7d25db8ff452926e58b7a66608666b35c194fc69 Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Mon, 17 Feb 2014 09:35:20 -0600 Subject: Fix global object handling in worker script JS files. Task-number: QTBUG-36874 Task-number: QTBUG-36881 Change-Id: Iacf4807dd37862e792ad1ba4ce540a6d48f1e495 Reviewed-by: Simon Hausmann --- src/qml/qml/qqmlcontextwrapper.cpp | 14 ++-- .../qml/qquickworkerscript/data/script_function.js | 8 +++ .../qml/qquickworkerscript/data/script_global.js | 5 ++ .../qml/qquickworkerscript/data/script_global2.js | 6 ++ .../auto/qml/qquickworkerscript/data/script_var.js | 6 ++ .../qquickworkerscript/data/worker_function.qml | 5 ++ .../qml/qquickworkerscript/data/worker_global.qml | 5 ++ .../qml/qquickworkerscript/data/worker_global2.qml | 5 ++ .../qml/qquickworkerscript/data/worker_var.qml | 5 ++ .../qquickworkerscript/tst_qquickworkerscript.cpp | 83 +++++++++++++++++++++- 10 files changed, 134 insertions(+), 8 deletions(-) create mode 100644 tests/auto/qml/qquickworkerscript/data/script_function.js create mode 100644 tests/auto/qml/qquickworkerscript/data/script_global.js create mode 100644 tests/auto/qml/qquickworkerscript/data/script_global2.js create mode 100644 tests/auto/qml/qquickworkerscript/data/script_var.js create mode 100644 tests/auto/qml/qquickworkerscript/data/worker_function.qml create mode 100644 tests/auto/qml/qquickworkerscript/data/worker_global.qml create mode 100644 tests/auto/qml/qquickworkerscript/data/worker_global2.qml create mode 100644 tests/auto/qml/qquickworkerscript/data/worker_var.qml diff --git a/src/qml/qml/qqmlcontextwrapper.cpp b/src/qml/qml/qqmlcontextwrapper.cpp index 1ca9c6ac12..d221e072f7 100644 --- a/src/qml/qml/qqmlcontextwrapper.cpp +++ b/src/qml/qml/qqmlcontextwrapper.cpp @@ -288,6 +288,13 @@ void QmlContextWrapper::put(Managed *m, const StringRef name, const ValueRef val return; } + PropertyAttributes attrs; + Property *pd = wrapper->__getOwnProperty__(name, &attrs); + if (pd) { + wrapper->putValue(pd, attrs, value); + return; + } + if (wrapper->isNullWrapper) { if (wrapper && wrapper->readOnly) { QString error = QLatin1String("Invalid write to global property \"") + name->toQString() + @@ -301,13 +308,6 @@ void QmlContextWrapper::put(Managed *m, const StringRef name, const ValueRef val return; } - PropertyAttributes attrs; - Property *pd = wrapper->__getOwnProperty__(name, &attrs); - if (pd) { - wrapper->putValue(pd, attrs, value); - return; - } - // Its possible we could delay the calculation of the "actual" context (in the case // of sub contexts) until it is definately needed. QQmlContextData *context = wrapper->getContext(); diff --git a/tests/auto/qml/qquickworkerscript/data/script_function.js b/tests/auto/qml/qquickworkerscript/data/script_function.js new file mode 100644 index 0000000000..c0391dd0ae --- /dev/null +++ b/tests/auto/qml/qquickworkerscript/data/script_function.js @@ -0,0 +1,8 @@ +function func() { + return "World" +} + +WorkerScript.onMessage = function(msg) { + WorkerScript.sendMessage(msg + " " + func()) +} + diff --git a/tests/auto/qml/qquickworkerscript/data/script_global.js b/tests/auto/qml/qquickworkerscript/data/script_global.js new file mode 100644 index 0000000000..cce4f2ceca --- /dev/null +++ b/tests/auto/qml/qquickworkerscript/data/script_global.js @@ -0,0 +1,5 @@ +WorkerScript.onMessage = function(msg) { + world = "World" + WorkerScript.sendMessage(msg + " " + world) +} + diff --git a/tests/auto/qml/qquickworkerscript/data/script_global2.js b/tests/auto/qml/qquickworkerscript/data/script_global2.js new file mode 100644 index 0000000000..0867f7ee76 --- /dev/null +++ b/tests/auto/qml/qquickworkerscript/data/script_global2.js @@ -0,0 +1,6 @@ +world = "World" + +WorkerScript.onMessage = function(msg) { + WorkerScript.sendMessage(msg + " " + world) +} + diff --git a/tests/auto/qml/qquickworkerscript/data/script_var.js b/tests/auto/qml/qquickworkerscript/data/script_var.js new file mode 100644 index 0000000000..77107e8344 --- /dev/null +++ b/tests/auto/qml/qquickworkerscript/data/script_var.js @@ -0,0 +1,6 @@ +var world = "World" + +WorkerScript.onMessage = function(msg) { + WorkerScript.sendMessage(msg + " " + world) +} + diff --git a/tests/auto/qml/qquickworkerscript/data/worker_function.qml b/tests/auto/qml/qquickworkerscript/data/worker_function.qml new file mode 100644 index 0000000000..f8d01dcfcc --- /dev/null +++ b/tests/auto/qml/qquickworkerscript/data/worker_function.qml @@ -0,0 +1,5 @@ +import QtQuick 2.0 + +BaseWorker { + source: "script_function.js" +} diff --git a/tests/auto/qml/qquickworkerscript/data/worker_global.qml b/tests/auto/qml/qquickworkerscript/data/worker_global.qml new file mode 100644 index 0000000000..546afd2f39 --- /dev/null +++ b/tests/auto/qml/qquickworkerscript/data/worker_global.qml @@ -0,0 +1,5 @@ +import QtQuick 2.0 + +BaseWorker { + source: "script_global.js" +} diff --git a/tests/auto/qml/qquickworkerscript/data/worker_global2.qml b/tests/auto/qml/qquickworkerscript/data/worker_global2.qml new file mode 100644 index 0000000000..42cad3852b --- /dev/null +++ b/tests/auto/qml/qquickworkerscript/data/worker_global2.qml @@ -0,0 +1,5 @@ +import QtQuick 2.0 + +BaseWorker { + source: "script_global2.js" +} diff --git a/tests/auto/qml/qquickworkerscript/data/worker_var.qml b/tests/auto/qml/qquickworkerscript/data/worker_var.qml new file mode 100644 index 0000000000..ea6a23cd3e --- /dev/null +++ b/tests/auto/qml/qquickworkerscript/data/worker_var.qml @@ -0,0 +1,5 @@ +import QtQuick 2.0 + +BaseWorker { + source: "script_var.js" +} diff --git a/tests/auto/qml/qquickworkerscript/tst_qquickworkerscript.cpp b/tests/auto/qml/qquickworkerscript/tst_qquickworkerscript.cpp index a799fc4fc4..57dc98849c 100644 --- a/tests/auto/qml/qquickworkerscript/tst_qquickworkerscript.cpp +++ b/tests/auto/qml/qquickworkerscript/tst_qquickworkerscript.cpp @@ -68,6 +68,9 @@ private slots: void script_included(); void scriptError_onLoad(); void scriptError_onCall(); + void script_function(); + void script_var(); + void script_global(); void stressDispose(); private: @@ -235,7 +238,6 @@ void tst_QQuickWorkerScript::script_included() waitForEchoMessage(worker); const QMetaObject *mo = worker->metaObject(); - QEXPECT_FAIL("", "It is not possible to write to the global object right now", Continue); QCOMPARE(mo->property(mo->indexOfProperty("response")).read(worker).toString(), value + " World"); qApp->processEvents(); @@ -283,6 +285,85 @@ void tst_QQuickWorkerScript::scriptError_onCall() delete worker; } +void tst_QQuickWorkerScript::script_function() +{ + QQmlComponent component(&m_engine, testFileUrl("worker_function.qml")); + QQuickWorkerScript *worker = qobject_cast(component.create()); + QVERIFY(worker != 0); + + QString value("Hello"); + + QVERIFY(QMetaObject::invokeMethod(worker, "testSend", Q_ARG(QVariant, value))); + waitForEchoMessage(worker); + + const QMetaObject *mo = worker->metaObject(); + QCOMPARE(mo->property(mo->indexOfProperty("response")).read(worker).toString(), value + " World"); + + qApp->processEvents(); + delete worker; +} + +void tst_QQuickWorkerScript::script_var() +{ + QQmlComponent component(&m_engine, testFileUrl("worker_var.qml")); + QQuickWorkerScript *worker = qobject_cast(component.create()); + QVERIFY(worker != 0); + + QString value("Hello"); + + QVERIFY(QMetaObject::invokeMethod(worker, "testSend", Q_ARG(QVariant, value))); + waitForEchoMessage(worker); + + const QMetaObject *mo = worker->metaObject(); + QCOMPARE(mo->property(mo->indexOfProperty("response")).read(worker).toString(), value + " World"); + + qApp->processEvents(); + delete worker; +} + +void tst_QQuickWorkerScript::script_global() +{ + { + QQmlComponent component(&m_engine, testFileUrl("worker_global.qml")); + QQuickWorkerScript *worker = qobject_cast(component.create()); + QVERIFY(worker != 0); + + QString value("Hello"); + + QtMessageHandler previousMsgHandler = qInstallMessageHandler(qquickworkerscript_warningsHandler); + + QVERIFY(QMetaObject::invokeMethod(worker, "testSend", Q_ARG(QVariant, value))); + + QTRY_COMPARE(qquickworkerscript_lastWarning, + testFileUrl("script_global.js").toString() + QLatin1String(":2: Invalid write to global property \"world\"")); + + qInstallMessageHandler(previousMsgHandler); + + qApp->processEvents(); + delete worker; + } + + { + QQmlComponent component(&m_engine, testFileUrl("worker_global2.qml")); + QQuickWorkerScript *worker = qobject_cast(component.create()); + QVERIFY(worker != 0); + + QString value("Hello"); + + QtMessageHandler previousMsgHandler = qInstallMessageHandler(qquickworkerscript_warningsHandler); + + QVERIFY(QMetaObject::invokeMethod(worker, "testSend", Q_ARG(QVariant, value))); + + QTRY_COMPARE(qquickworkerscript_lastWarning, + testFileUrl("script_global.js").toString() + QLatin1String(":2: Invalid write to global property \"world\"")); + + qInstallMessageHandler(previousMsgHandler); + + qApp->processEvents(); + delete worker; + } +} + // Rapidly create and destroy worker scripts to test resources are being disposed // in the correct isolate void tst_QQuickWorkerScript::stressDispose() -- cgit v1.2.3