can
Version:
MIT-licensed, client-side, JavaScript framework that makes building rich web applications easy.
326 lines (289 loc) • 9.67 kB
JavaScript
define([
"doh/main",
"dojo/has",
"dojo/sniff"
], function(doh, has, sniff){
// summary:
// Test the loading of Dojo in the WebWorker environment.
has.add("webworkers", (typeof Worker === 'function'));
if(has("webworkers")){
// Tests will still pass when workers not available but warning issued.
var fixtures = {
deferred: function(){
this.deferred = new doh.Deferred();
}
};
var tearDowns = {
killWorker: function(){
var self = this;
this.deferred.then(function(){
self.worker.terminate();
});
},
killBlobWorker: function(){
var self = this;
this.deferred.then(function(){
if(has("blobs") && has("convertObjectUrl")){
self.worker.terminate();
window.URL.revokeObjectURL(self.workerBlobURL);
}
});
}
};
function reflectConsole(message){
if(message.data.consoleType in console){
if(has("opera") && opera.postError){
opera.postError(message.data.consoleType.toUpperCase() + ": Platform does not support Blobs");
}else{
console[message.data.consoleType](message.data.value);
}
}else{
if(has("opera") && opera.postError){
opera.postError("ERROR: Could not reflect console message type: " + message.data.consoleType);
}else{
console.error("Could not reflect console message type: " + message.data.consoleType);
}
}
}
doh.register("tests._base.hostenv_webworkers", [{
name: "Loading Dojo core inside worker",
setUp: fixtures.deferred,
tearDown: tearDowns.killWorker,
timeout: 5000,
runTest: function(){
// summary:
// Test whether dojo can be loaded in the worker
var self = this;
this.worker = new Worker("../../dojo/tests/_base/loader/hostenv_webworkers/worker1.js");
this.worker.addEventListener("message", function (message){
if(message.data.type === "testResult"){
if(message.data.value){
self.deferred.resolve();
}else{
self.deferred.reject();
}
}else if(message.data.type === "console"){
reflectConsole(message);
}
}, false);
return this.deferred;
}
}, {
name: "Load a dojo script via require",
setUp: fixtures.deferred,
tearDown: tearDowns.killWorker,
timeout: 5000,
runTest: function(){
// summary:
// Test whether require works in the worker.
var self = this;
this.worker = new Worker("../../dojo/tests/_base/loader/hostenv_webworkers/worker2.js");
this.worker.addEventListener("message", function (message){
if(message.data.type === "testResult"){
if(message.data.value){
self.deferred.resolve();
}else{
self.deferred.reject();
}
}else if(message.data.type === "console"){
reflectConsole(message);
}
}, false);
return this.deferred;
}
}, {
name: "Load a dojo script via require in async mode",
setUp: fixtures.deferred,
tearDown: tearDowns.killWorker,
timeout: 5000,
runTest: function(){
// summary:
// Test whether require works in the worker when in async mode.
var self = this;
this.worker = new Worker("../../dojo/tests/_base/loader/hostenv_webworkers/worker3.js");
this.worker.addEventListener("message", function(message){
if(message.data.type === "testResult"){
if(message.data.value){
self.deferred.resolve();
}else{
self.deferred.reject();
}
}else if(message.data.type === "console"){
reflectConsole(message);
}
}, false);
return this.deferred;
}
}, {
name: "Load a dojo script via require in a subworker",
setUp: fixtures.deferred,
tearDown: tearDowns.killWorker,
timeout: 5000,
runTest: function(){
// summary:
// Test whether Dojo will load in a subworker.
// description:
// This is more complex as two workers are created. The first acts as a
// middleman between this function and the subworker. Some browsers do not
// support subworkers at writing (eg. Chrome - see:
// https://code.google.com/p/chromium/issues/detail?id=31666 for current status).
// Test issues a warning if subworks not available but passes the test.
var self = this;
this.worker = new Worker("../../dojo/tests/_base/loader/hostenv_webworkers/worker4.js");
this.worker.addEventListener("message", function(message){
if(message.data.type === "testResult"){
if(message.data.value){
self.deferred.resolve();
}else{
self.deferred.reject();
}
}else if(message.data.type === "console"){
reflectConsole(message);
}
}, false);
return this.deferred;
}
}, {
name: "Test for loading in a blob worker",
setUp: fixtures.deferred,
tearDown: tearDowns.killBlobWorker,
timeout: 5000,
runTest: function(){
// summary:
// Test for loading dojo and using require in a blob worker
has.add("blobs", (typeof Blob === 'function'));
has.add("convertObjectUrl", function(){
var URL = window.URL || window.webkitURL;
if(URL !== undefined){
return (typeof URL.createObjectURL === 'function');
}
return false;
});
if(has("blobs") && has("convertObjectUrl")){
function getBaseAbsoluteUrl(){
// summary:
// Blobs need absolute urls to be used within them as relative is relative
// to blob://<object>.
// TODO:
// Is there a better way of calculating the absolute url base path?
var baseUrl = require.rawConfig.baseUrl.split("/");
var absoluteUrl = location.pathname.split("/");
absoluteUrl.pop();
absoluteUrl.pop();
baseUrl.pop();
return location.protocol + "//" + location.host + absoluteUrl.join("/") + "/" + baseUrl.join("/") + "/";
}
var workerBlob = new Blob([
'var dojoConfig = {' +
'"baseUrl":"' + getBaseAbsoluteUrl() + '",' +
'"packages":[{"name":"dojo", "location":"dojo"}]' +
'};' +
'importScripts(' +
'dojoConfig.baseUrl+"dojo/dojo.js",' +
'dojoConfig.baseUrl+"dojo/tests/_base/loader/hostenv_webworkers/console.js"' +
');' +
'try{' +
'require(["dojo/tests/_base/loader/hostenv_webworkers/strings"], function(strings){' +
'this.postMessage({type:"testResult", "test":"require is working", "value":true});' +
'});' +
'}catch(e){' +
'this.postMessage({' +
'type:"testResult", "test":"require is working", "value":false' +
'});' +
'}'], {type: "text/javascript"});
var self = this;
var URL = window.URL || window.webkitURL;
self.workerBlobURL = URL.createObjectURL(workerBlob);
try{
this.worker = new Worker(self.workerBlobURL);
this.worker.addEventListener("message", function(message){
if(message.data.type === "testResult"){
if(message.data.value){
self.deferred.resolve();
}else{
self.deferred.reject();
}
}else if(message.data.type === "console"){
reflectConsole(message);
}
}, false);
}catch(e){
if(e.message.toLowerCase() === "securityerror"){
// IE does not support Webworkers from Blobs at present
console.warn("Blob workers are not supported");
self.deferred.resolve();
}else{
throw e;
}
}
return this.deferred;
}else{
if(window.opera){
opera.postError("WARN: Platform does not support Blobs");
}else{
console.log("Platform does not support Blobs");
}
}
}
}, {
name: "Test making a XHR request inside a worker using dojo/request",
setUp: fixtures.deferred,
tearDown: tearDowns.killWorker,
timeout: 5000,
runTest: function(){
// summary:
// Test using dojo/request in a worker
// description:
// This is a more advanced test to ensure Dojo's implementation of
// XHR works in the webworker. It is also a general test of loading
// components via require and then using them.
var self = this;
this.worker = new Worker("../../dojo/tests/_base/loader/hostenv_webworkers/worker5.js?v=4");
this.worker.addEventListener("message", function(message){
if(message.data.type === "testResult"){
if(message.data.value){
self.deferred.resolve();
}else{
self.deferred.reject();
}
}else if(message.data.type === "console"){
reflectConsole(message);
}
}, false);
return this.deferred;
}
}, {
name: "Test using dojo/on in a worker",
setUp: fixtures.deferred,
tearDown: tearDowns.killWorker,
timeout: 5000,
runTest: function(){
// summary:
// Test using dojo/on in a worker.
// description:
// Another advanced test to see if dojo/on works in workers where there is no DOM.
// Test waits for the worker to request a message and then send one. Worker uses
// dojo/on to listen for messages on the worker global. It responds with a
// pass for the test if it receives it correctly.
var self = this;
this.worker = new Worker("../../dojo/tests/_base/loader/hostenv_webworkers/worker6.js");
this.worker.addEventListener("message", function (message){
if(message.data.type === "testResult"){
if(message.data.value){
self.deferred.resolve();
}else{
self.deferred.reject();
}
}else if(message.data.type === "requestMessage"){
self.worker.postMessage({type: "gotMessage"})
}else if(message.data.type === "console"){
reflectConsole(message);
}
}, false);
return this.deferred;
}
}]);
}else{
console.warno("Platform does not support webworkers")
}
});