Skip to content

Commit

Permalink
test(worker): adding infrastructure to run tests in WebWorkers - #92
Browse files Browse the repository at this point in the history
  • Loading branch information
rodneyrehm committed Dec 20, 2015
1 parent 00bfb4c commit c5572f4
Show file tree
Hide file tree
Showing 4 changed files with 234 additions and 1 deletion.
62 changes: 62 additions & 0 deletions test/helper/test-worker.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
define([
'intern/dojo/Promise',
], function(Promise) {

function WorkerProxy() {
this.counter = 0;
this.deferreds = {};
this.worker = new Worker('../../test/helper/worker.js');
this.worker.addEventListener('message', this._handleMessage.bind(this), false);
}

WorkerProxy.prototype = {
_handleMessage: function(event) {
var id = event.data.id;
var dfd = this.deferreds[id];
if (!dfd) {
return;
}

if (event.data.error) {
var _error = new Error(event.data.error.split('\n')[0]);
_error.stack = event.data.error;
dfd.reject(_error);
} else {
dfd.resolve(event.data.result);
}

delete this.deferreds[id];
},

_wrapTest: function(promise, deferred, callback) {
promise.then(
deferred.callback(callback),
deferred.reject.bind(deferred)
);
},

terminate: function() {
this.worker && this.worker.terminate();
this.worker = null;
},

run: function(modules, callback) {
var id = this.counter++;
this.worker.postMessage({
id: id,
modules: (typeof modules === 'string' ? [modules] : modules) || [],
callback: String(callback),
});
var dfd = new Promise.Deferred();
this.deferreds[id] = dfd;
dfd.promise.test = this._wrapTest.bind(this, dfd.promise);
return dfd.promise;
},
};

if (typeof window === undefined || !window.Worker) {
return null;
}

return WorkerProxy;
});
49 changes: 49 additions & 0 deletions test/helper/worker.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*eslint-env worker*/
importScripts('../../node_modules/requirejs/require.js');

require.config({
paths: {
// map to AMD files
'ally.js': '../../dist/amd',
// provide paths to dependencies
'array.prototype.findindex': '../../node_modules/array.prototype.findindex/index',
'domtokenlist-shim': '../../node_modules/domtokenlist-shim/dist/domtokenlist',
'css.escape': '../../node_modules/css.escape/css.escape',
platform: '../../node_modules/platform/platform',
},
});

function stringToCallable(text) {
var argumentNames;
var functionBody = text.replace(/\(([^\)]+)\)/, function(match, args) {
argumentNames = args.replace(/\s+/, '').split(',');
return '';
}).replace(/^function[^\{]+\{([\w\W]+)\}$/, '$1');
return Function.apply(Function, argumentNames.concat([functionBody]));
}

onmessage = function(event) {
var callback = stringToCallable(event.data.callback);
require(event.data.modules, function() {
var result;
var error;

try {
result = callback.apply(null, arguments);
} catch(e) {
error = e;
}

postMessage({
id: event.data.id,
result: result,
error: error && error.stack,
});
}, function(error) {
postMessage({
id: event.data.id,
result: undefined,
error: error.stack,
});
});
};
3 changes: 2 additions & 1 deletion test/intern.base-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ define([
'test/unit/query.focusable.test',
'test/unit/query.tabbable.test',
'test/unit/query.tabsequence.sort-area.test',
'test/unit/query.tabsequence.sort-tabindex.test.js',
'test/unit/query.tabsequence.sort-tabindex.test',
'test/unit/query.tabsequence.test',
'test/unit/style.focus-within.test',
'test/unit/style.focus-source.test',
Expand All @@ -117,6 +117,7 @@ define([
'test/unit/when.focusable.test',
'test/unit/when.key.test',
'test/unit/when.visible-area.test',
'test/unit/core.worker.test',
],

// Functional test suite(s) to run in each browser once non-functional tests are completed
Expand Down
121 changes: 121 additions & 0 deletions test/unit/core.worker.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
define([
'intern!object',
'intern/chai!expect',
'../helper/test-worker',
'ally/version',
], function(registerSuite, expect, TestWorker, version) {

registerSuite(function() {
var worker;
var suite = {
name: 'core: WebWorker',

beforeEach: function() {
if (!TestWorker) {
return;
}

worker = new TestWorker();
},
afterEach: function() {
worker && worker.terminate();
worker = null;
},

'ally.js/version': function() {
if (!worker) {
this.skip('Worker not supported');
}

var deferred = this.async(10000);
worker.run('ally.js/version', function(_version) {
return _version;
}).test(deferred, function(_version) {
expect(_version).to.equal(version);
});
},
'ally.js/ally': function() {
if (!worker) {
this.skip('Worker not supported');
}

var deferred = this.async(10000);
worker.run('ally.js/ally', function(_module) {
return typeof _module;
}).test(deferred, function(type) {
expect(type).to.equal('object');
});
},
};

var modules = [
'ally.js/element/disabled',
'ally.js/event/active-element',
'ally.js/event/shadow-focus',
'ally.js/fix/pointer-focus-children',
'ally.js/fix/pointer-focus-input',
'ally.js/fix/pointer-focus-parent',
'ally.js/get/active-elements',
'ally.js/get/focus-target',
'ally.js/get/insignificant-branches',
'ally.js/get/parents',
'ally.js/get/shadow-host-parents',
'ally.js/get/shadow-host',
'ally.js/is/disabled',
'ally.js/is/focus-relevant',
'ally.js/is/focusable',
'ally.js/is/native-disabled-supported',
'ally.js/is/only-tabbable',
'ally.js/is/shadowed',
'ally.js/is/tabbable',
'ally.js/is/valid-area',
'ally.js/is/valid-tabindex',
'ally.js/is/visible',
'ally.js/maintain/disabled',
'ally.js/maintain/hidden',
'ally.js/observe/interaction-type',
'ally.js/prototype/element.prototype.matches',
'ally.js/prototype/svgelement.prototype.focus',
'ally.js/prototype/window.customevent',
'ally.js/query/first-tabbable',
'ally.js/query/focusable',
'ally.js/query/tabbable',
'ally.js/query/tabsequence.sort-area',
'ally.js/query/tabsequence.sort-tabindex',
'ally.js/query/tabsequence',
'ally.js/style/focus-within',
'ally.js/style/focus-source',
'ally.js/util/context-to-element',
'ally.js/util/decorate-context',
'ally.js/util/decorate-service',
'ally.js/util/merge-dom-order',
'ally.js/util/node-array',
'ally.js/util/tabindex-value',
'ally.js/util/visible-area',
'ally.js/when/focusable',
'ally.js/when/key',
'ally.js/when/visible-area',
];

function generateTestForModule(module) {
return function() {
if (!worker) {
this.skip('Worker not supported');
}

var deferred = this.async(10000);
worker.run(module, function(_module) {
return Boolean(_module);
}).test(deferred, function(_module) {
expect(_module).to.equal(true);
});
};
}

modules.forEach(function(module) {
suite[module] = generateTestForModule(module);
});

return suite;
});
});

0 comments on commit c5572f4

Please sign in to comment.