diff -r 000000000000 -r 6474c204b198 addon-sdk/source/lib/sdk/test/utils.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/addon-sdk/source/lib/sdk/test/utils.js Wed Dec 31 06:09:35 2014 +0100 @@ -0,0 +1,109 @@ +/* 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/. */ + +'use strict'; + +module.metadata = { + 'stability': 'unstable' +}; + +const { defer } = require('../core/promise'); +const { setInterval, clearInterval } = require('../timers'); + +function getTestNames (exports) + Object.keys(exports).filter(name => /^test/.test(name)) + +function isTestAsync (fn) fn.length > 1 +function isHelperAsync (fn) fn.length > 2 + +/* + * Takes an `exports` object of a test file and a function `beforeFn` + * to be run before each test. `beforeFn` is called with a `name` string + * as the first argument of the test name, and may specify a second + * argument function `done` to indicate that this function should + * resolve asynchronously + */ +function before (exports, beforeFn) { + getTestNames(exports).map(name => { + let testFn = exports[name]; + if (!isTestAsync(testFn) && !isHelperAsync(beforeFn)) { + exports[name] = function (assert) { + beforeFn(name, assert); + testFn(assert); + }; + } + else if (isTestAsync(testFn) && !isHelperAsync(beforeFn)) { + exports[name] = function (assert, done) { + beforeFn(name, assert); + testFn(assert, done); + }; + } + else if (!isTestAsync(testFn) && isHelperAsync(beforeFn)) { + exports[name] = function (assert, done) { + beforeFn(name, assert, () => { + testFn(assert); + done(); + }); + }; + } else if (isTestAsync(testFn) && isHelperAsync(beforeFn)) { + exports[name] = function (assert, done) { + beforeFn(name, assert, () => { + testFn(assert, done); + }); + }; + } + }); +} +exports.before = before; + +/* + * Takes an `exports` object of a test file and a function `afterFn` + * to be run after each test. `afterFn` is called with a `name` string + * as the first argument of the test name, and may specify a second + * argument function `done` to indicate that this function should + * resolve asynchronously + */ +function after (exports, afterFn) { + getTestNames(exports).map(name => { + let testFn = exports[name]; + if (!isTestAsync(testFn) && !isHelperAsync(afterFn)) { + exports[name] = function (assert) { + testFn(assert); + afterFn(name, assert); + }; + } + else if (isTestAsync(testFn) && !isHelperAsync(afterFn)) { + exports[name] = function (assert, done) { + testFn(assert, () => { + afterFn(name, assert); + done(); + }); + }; + } + else if (!isTestAsync(testFn) && isHelperAsync(afterFn)) { + exports[name] = function (assert, done) { + testFn(assert); + afterFn(name, assert, done); + }; + } else if (isTestAsync(testFn) && isHelperAsync(afterFn)) { + exports[name] = function (assert, done) { + testFn(assert, () => { + afterFn(name, assert, done); + }); + }; + } + }); +} +exports.after = after; + +function waitUntil (predicate, delay) { + let { promise, resolve } = defer(); + let interval = setInterval(() => { + if (!predicate()) return; + clearInterval(interval); + resolve(); + }, delay || 10); + return promise; +} +exports.waitUntil = waitUntil;