Fix global object handling in worker script JS files.
authorMichael Brasser <michael.brasser@jollamobile.com>
Mon, 17 Feb 2014 15:35:20 +0000 (09:35 -0600)
committerThe Qt Project <gerrit-noreply@qt-project.org>
Tue, 25 Feb 2014 19:01:12 +0000 (20:01 +0100)
Task-number: QTBUG-36874
Task-number: QTBUG-36881
Change-Id: Iacf4807dd37862e792ad1ba4ce540a6d48f1e495
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
src/qml/qml/qqmlcontextwrapper.cpp
tests/auto/qml/qquickworkerscript/data/script_function.js [new file with mode: 0644]
tests/auto/qml/qquickworkerscript/data/script_global.js [new file with mode: 0644]
tests/auto/qml/qquickworkerscript/data/script_global2.js [new file with mode: 0644]
tests/auto/qml/qquickworkerscript/data/script_var.js [new file with mode: 0644]
tests/auto/qml/qquickworkerscript/data/worker_function.qml [new file with mode: 0644]
tests/auto/qml/qquickworkerscript/data/worker_global.qml [new file with mode: 0644]
tests/auto/qml/qquickworkerscript/data/worker_global2.qml [new file with mode: 0644]
tests/auto/qml/qquickworkerscript/data/worker_var.qml [new file with mode: 0644]
tests/auto/qml/qquickworkerscript/tst_qquickworkerscript.cpp

index 1ca9c6a..d221e07 100644 (file)
@@ -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 (file)
index 0000000..c0391dd
--- /dev/null
@@ -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 (file)
index 0000000..cce4f2c
--- /dev/null
@@ -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 (file)
index 0000000..0867f7e
--- /dev/null
@@ -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 (file)
index 0000000..77107e8
--- /dev/null
@@ -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 (file)
index 0000000..f8d01dc
--- /dev/null
@@ -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 (file)
index 0000000..546afd2
--- /dev/null
@@ -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 (file)
index 0000000..42cad38
--- /dev/null
@@ -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 (file)
index 0000000..ea6a23c
--- /dev/null
@@ -0,0 +1,5 @@
+import QtQuick 2.0
+
+BaseWorker {
+    source: "script_var.js"
+}
index a799fc4..57dc988 100644 (file)
@@ -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<QQuickWorkerScript*>(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<QQuickWorkerScript*>(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<QQuickWorkerScript*>(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<QQuickWorkerScript*>(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()