mirror of
https://github.com/roytam1/palemoon27.git
synced 2026-06-04 15:38:59 +00:00
388 lines
13 KiB
JavaScript
388 lines
13 KiB
JavaScript
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
// This file tests message ports and semantics of the frameworker which aren't
|
|
// directly related to the sandbox. See also browser_frameworker_sandbox.js.
|
|
|
|
function makeWorkerUrl(runner) {
|
|
let prefix = "http://example.com/browser/toolkit/components/social/test/browser/echo.sjs?";
|
|
if (typeof runner == "function") {
|
|
runner = "var run=" + runner.toSource() + ";run();";
|
|
}
|
|
return prefix + encodeURI(runner);
|
|
}
|
|
|
|
var getFrameWorkerHandle;
|
|
function test() {
|
|
waitForExplicitFinish();
|
|
|
|
let scope = {};
|
|
Cu.import("resource://gre/modules/FrameWorker.jsm", scope);
|
|
getFrameWorkerHandle = scope.getFrameWorkerHandle;
|
|
|
|
runTests(tests);
|
|
}
|
|
|
|
let tests = {
|
|
testSimple: function(cbnext) {
|
|
let run = function() {
|
|
onconnect = function(e) {
|
|
let port = e.ports[0];
|
|
port.onmessage = function(e) {
|
|
if (e.data.topic == "ping") {
|
|
port.postMessage({topic: "pong"});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
let worker = getFrameWorkerHandle(makeWorkerUrl(run), undefined, "testSimple");
|
|
|
|
worker.port.onmessage = function(e) {
|
|
if (e.data.topic == "pong") {
|
|
worker.terminate();
|
|
cbnext();
|
|
}
|
|
}
|
|
worker.port.postMessage({topic: "ping"})
|
|
},
|
|
|
|
// when the client closes early but the worker tries to send anyway...
|
|
// XXX - disabled due to bug 919878 - we close the frameworker before the
|
|
// remote browser has completed initializing, leading to failures. Given
|
|
// this can realistically only happen in this synthesized test environment,
|
|
// disabling just this test seems OK for now.
|
|
/***
|
|
testEarlyClose: function(cbnext) {
|
|
let run = function() {
|
|
onconnect = function(e) {
|
|
let port = e.ports[0];
|
|
port.postMessage({topic: "oh hai"});
|
|
}
|
|
}
|
|
|
|
let worker = getFrameWorkerHandle(makeWorkerUrl(run), undefined, "testEarlyClose");
|
|
worker.port.close();
|
|
worker.terminate();
|
|
cbnext();
|
|
},
|
|
***/
|
|
|
|
// Check we do get a social.port-closing message as the port is closed.
|
|
testPortClosingMessage: function(cbnext) {
|
|
// We use 2 ports - we close the first and report success via the second.
|
|
let run = function() {
|
|
let firstPort, secondPort;
|
|
onconnect = function(e) {
|
|
let port = e.ports[0];
|
|
if (firstPort === undefined) {
|
|
firstPort = port;
|
|
port.onmessage = function(e) {
|
|
if (e.data.topic == "social.port-closing") {
|
|
secondPort.postMessage({topic: "got-closing"});
|
|
}
|
|
}
|
|
} else {
|
|
secondPort = port;
|
|
// now both ports are connected we can trigger the client side
|
|
// closing the first.
|
|
secondPort.postMessage({topic: "connected"});
|
|
}
|
|
}
|
|
}
|
|
let workerurl = makeWorkerUrl(run);
|
|
let worker1 = getFrameWorkerHandle(workerurl, undefined, "testPortClosingMessage worker1");
|
|
let worker2 = getFrameWorkerHandle(workerurl, undefined, "testPortClosingMessage worker2");
|
|
worker2.port.onmessage = function(e) {
|
|
if (e.data.topic == "connected") {
|
|
// both ports connected, so close the first.
|
|
worker1.port.close();
|
|
} else if (e.data.topic == "got-closing") {
|
|
worker2.terminate();
|
|
cbnext();
|
|
}
|
|
}
|
|
},
|
|
|
|
// Tests that prototypes added to core objects work with data sent over
|
|
// the message ports.
|
|
testPrototypes: function(cbnext) {
|
|
let run = function() {
|
|
// Modify the Array prototype...
|
|
Array.prototype.customfunction = function() {};
|
|
onconnect = function(e) {
|
|
let port = e.ports[0];
|
|
port.onmessage = function(e) {
|
|
// Check the data we get via the port has the prototype modification
|
|
if (e.data.topic == "hello" && e.data.data.customfunction) {
|
|
port.postMessage({topic: "hello", data: [1,2,3]});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// hrmph - this kinda sucks as it is really just testing the actual
|
|
// implementation rather than the end result, but is OK for now.
|
|
// Really we are just testing that JSON.parse in the client window
|
|
// is called.
|
|
let fakeWindow = {
|
|
JSON: {
|
|
parse: function(s) {
|
|
let data = JSON.parse(s);
|
|
data.data.somextrafunction = function() {};
|
|
return data;
|
|
}
|
|
}
|
|
}
|
|
let worker = getFrameWorkerHandle(makeWorkerUrl(run), fakeWindow, "testPrototypes");
|
|
worker.port.onmessage = function(e) {
|
|
if (e.data.topic == "hello") {
|
|
ok(e.data.data.somextrafunction, "have someextrafunction")
|
|
worker.terminate();
|
|
cbnext();
|
|
}
|
|
}
|
|
worker.port.postMessage({topic: "hello", data: [1,2,3]});
|
|
},
|
|
|
|
testSameOriginImport: function(cbnext) {
|
|
let run = function() {
|
|
onconnect = function(e) {
|
|
let port = e.ports[0];
|
|
port.onmessage = function(e) {
|
|
if (e.data.topic == "ping") {
|
|
try {
|
|
importScripts("http://mochi.test:8888/error");
|
|
} catch(ex) {
|
|
port.postMessage({topic: "pong", data: ex});
|
|
return;
|
|
}
|
|
port.postMessage({topic: "pong", data: null});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
let worker = getFrameWorkerHandle(makeWorkerUrl(run), undefined, "testSameOriginImport");
|
|
worker.port.onmessage = function(e) {
|
|
if (e.data.topic == "pong") {
|
|
isnot(e.data.data, null, "check same-origin applied to importScripts");
|
|
worker.terminate();
|
|
cbnext();
|
|
}
|
|
}
|
|
worker.port.postMessage({topic: "ping"})
|
|
},
|
|
|
|
testRelativeImport: function(cbnext) {
|
|
let url = "https://example.com/browser/toolkit/components/social/test/browser/worker_relative.js";
|
|
let worker = getFrameWorkerHandle(url, undefined, "testSameOriginImport");
|
|
worker.port.onmessage = function(e) {
|
|
if (e.data.topic == "done") {
|
|
is(e.data.result, "ok", "check relative url in importScripts");
|
|
worker.terminate();
|
|
cbnext();
|
|
}
|
|
}
|
|
},
|
|
|
|
testNavigator: function(cbnext) {
|
|
let run = function() {
|
|
let port;
|
|
ononline = function() {
|
|
port.postMessage({topic: "ononline", data: navigator.onLine});
|
|
}
|
|
onoffline = function() {
|
|
port.postMessage({topic: "onoffline", data: navigator.onLine});
|
|
}
|
|
onconnect = function(e) {
|
|
port = e.ports[0];
|
|
port.postMessage({topic: "ready",
|
|
data: {
|
|
appName: navigator.appName,
|
|
appVersion: navigator.appVersion,
|
|
platform: navigator.platform,
|
|
userAgent: navigator.userAgent,
|
|
}
|
|
});
|
|
}
|
|
}
|
|
let ioService = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService2);
|
|
let oldManage = ioService.manageOfflineStatus;
|
|
let oldOffline = ioService.offline;
|
|
|
|
ioService.manageOfflineStatus = false;
|
|
let worker = getFrameWorkerHandle(makeWorkerUrl(run), undefined, "testNavigator");
|
|
let expected_topic = "onoffline";
|
|
let expected_data = false;
|
|
worker.port.onmessage = function(e) {
|
|
is(e.data.topic, "ready");
|
|
for each (let attr in ['appName', 'appVersion', 'platform', 'userAgent']) {
|
|
// each attribute must be a string with length > 0.
|
|
is(typeof e.data.data[attr], "string");
|
|
ok(e.data.data[attr].length > 0);
|
|
}
|
|
|
|
worker.port.onmessage = function(e) {
|
|
// a handler specifically for the offline notification.
|
|
is(e.data.topic, "onoffline");
|
|
is(e.data.data, false);
|
|
|
|
// add another handler specifically for the 'online' case.
|
|
worker.port.onmessage = function(e) {
|
|
is(e.data.topic, "ononline");
|
|
is(e.data.data, true);
|
|
// all good!
|
|
ioService.manageOfflineStatus = oldManage;
|
|
ioService.offline = oldOffline;
|
|
worker.terminate();
|
|
cbnext();
|
|
}
|
|
ioService.offline = false;
|
|
}
|
|
ioService.offline = true;
|
|
}
|
|
},
|
|
|
|
testMissingWorker: function(cbnext) {
|
|
// don't ever create this file! We want a 404.
|
|
let url = "https://example.com/browser/toolkit/components/social/test/browser/worker_is_missing.js";
|
|
let worker = getFrameWorkerHandle(url, undefined, "testMissingWorker");
|
|
Services.obs.addObserver(function handleError(subj, topic, data) {
|
|
Services.obs.removeObserver(handleError, "social:frameworker-error");
|
|
is(data, worker._worker.origin, "social:frameworker-error was handled");
|
|
worker.terminate();
|
|
cbnext();
|
|
}, 'social:frameworker-error', false);
|
|
worker.port.onmessage = function(e) {
|
|
ok(false, "social:frameworker-error was handled");
|
|
cbnext();
|
|
}
|
|
},
|
|
|
|
testNoConnectWorker: function(cbnext) {
|
|
let worker = getFrameWorkerHandle(makeWorkerUrl(function () {}),
|
|
undefined, "testNoConnectWorker");
|
|
Services.obs.addObserver(function handleError(subj, topic, data) {
|
|
Services.obs.removeObserver(handleError, "social:frameworker-error");
|
|
is(data, worker._worker.origin, "social:frameworker-error was handled");
|
|
worker.terminate();
|
|
cbnext();
|
|
}, 'social:frameworker-error', false);
|
|
worker.port.onmessage = function(e) {
|
|
ok(false, "social:frameworker-error was handled");
|
|
cbnext();
|
|
}
|
|
},
|
|
|
|
testEmptyWorker: function(cbnext) {
|
|
let worker = getFrameWorkerHandle(makeWorkerUrl(''),
|
|
undefined, "testEmptyWorker");
|
|
Services.obs.addObserver(function handleError(subj, topic, data) {
|
|
Services.obs.removeObserver(handleError, "social:frameworker-error");
|
|
is(data, worker._worker.origin, "social:frameworker-error was handled");
|
|
worker.terminate();
|
|
cbnext();
|
|
}, 'social:frameworker-error', false);
|
|
worker.port.onmessage = function(e) {
|
|
ok(false, "social:frameworker-error was handled");
|
|
cbnext();
|
|
}
|
|
},
|
|
|
|
testWorkerConnectError: function(cbnext) {
|
|
let run = function () {
|
|
onconnect = function(e) {
|
|
throw new Error("worker failure");
|
|
}
|
|
}
|
|
let worker = getFrameWorkerHandle(makeWorkerUrl(run),
|
|
undefined, "testWorkerConnectError");
|
|
Services.obs.addObserver(function handleError(subj, topic, data) {
|
|
Services.obs.removeObserver(handleError, "social:frameworker-error");
|
|
is(data, worker._worker.origin, "social:frameworker-error was handled");
|
|
worker.terminate();
|
|
cbnext();
|
|
}, 'social:frameworker-error', false);
|
|
worker.port.onmessage = function(e) {
|
|
ok(false, "social:frameworker-error was handled");
|
|
cbnext();
|
|
}
|
|
},
|
|
|
|
// This will create the worker, then send a message to the port, then close
|
|
// the port - all before the worker has actually initialized.
|
|
testCloseFirstSend: function(cbnext) {
|
|
let run = function() {
|
|
let numPings = 0, numCloses = 0;
|
|
onconnect = function(e) {
|
|
let port = e.ports[0];
|
|
port.onmessage = function(e) {
|
|
if (e.data.topic == "ping") {
|
|
numPings += 1;
|
|
} else if (e.data.topic == "social.port-closing") {
|
|
numCloses += 1;
|
|
} else if (e.data.topic == "get-counts") {
|
|
port.postMessage({topic: "result",
|
|
result: {ping: numPings, close: numCloses}});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
let worker = getFrameWorkerHandle(makeWorkerUrl(run), undefined, "testSendAndClose");
|
|
worker.port.postMessage({topic: "ping"});
|
|
worker.port.close();
|
|
let newPort = getFrameWorkerHandle(makeWorkerUrl(run), undefined, "testSendAndClose").port;
|
|
newPort.onmessage = function(e) {
|
|
if (e.data.topic == "result") {
|
|
is(e.data.result.ping, 1, "the worker got the ping");
|
|
is(e.data.result.close, 1, "the worker got 1 close message");
|
|
worker.terminate();
|
|
cbnext();
|
|
}
|
|
}
|
|
newPort.postMessage({topic: "get-counts"});
|
|
},
|
|
|
|
// Like testCloseFirstSend, although in this test the worker has already
|
|
// initialized (so the "connect pending ports" part of the worker isn't
|
|
// what needs to handle this case.)
|
|
testCloseAfterInit: function(cbnext) {
|
|
let run = function() {
|
|
let numPings = 0, numCloses = 0;
|
|
onconnect = function(e) {
|
|
let port = e.ports[0];
|
|
port.onmessage = function(e) {
|
|
if (e.data.topic == "ping") {
|
|
numPings += 1;
|
|
} else if (e.data.topic == "social.port-closing") {
|
|
numCloses += 1;
|
|
} else if (e.data.topic == "get-counts") {
|
|
port.postMessage({topic: "result",
|
|
result: {ping: numPings, close: numCloses}});
|
|
} else if (e.data.topic == "get-ready") {
|
|
port.postMessage({topic: "ready"});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
let worker = getFrameWorkerHandle(makeWorkerUrl(run), undefined, "testSendAndClose");
|
|
worker.port.onmessage = function(e) {
|
|
if (e.data.topic == "ready") {
|
|
let newPort = getFrameWorkerHandle(makeWorkerUrl(run), undefined, "testSendAndClose").port;
|
|
newPort.postMessage({topic: "ping"});
|
|
newPort.close();
|
|
worker.port.postMessage({topic: "get-counts"});
|
|
} else if (e.data.topic == "result") {
|
|
is(e.data.result.ping, 1, "the worker got the ping");
|
|
is(e.data.result.close, 1, "the worker got 1 close message");
|
|
worker.terminate();
|
|
cbnext();
|
|
}
|
|
}
|
|
worker.port.postMessage({topic: "get-ready"});
|
|
},
|
|
}
|