| <script> |
| |
| // FIXME: This really could be trimmed down from all the generic and commonjs crap. |
| |
| ;(function(){ |
| |
| // CommonJS require() |
| |
| function require(p){ |
| var path = require.resolve(p) |
| , mod = require.modules[path]; |
| if (!mod) throw new Error('failed to require "' + p + '"'); |
| if (!mod.exports) { |
| mod.exports = {}; |
| mod.call(mod.exports, mod, mod.exports, require.relative(path)); |
| } |
| return mod.exports; |
| } |
| |
| require.modules = {}; |
| |
| require.resolve = function (path){ |
| var orig = path |
| , reg = path + '.js' |
| , index = path + '/index.js'; |
| return require.modules[reg] && reg |
| || require.modules[index] && index |
| || orig; |
| }; |
| |
| require.register = function (path, fn){ |
| require.modules[path] = fn; |
| }; |
| |
| require.relative = function (parent) { |
| return function(p){ |
| if ('.' != p.charAt(0)) return require(p); |
| |
| var path = parent.split('/') |
| , segs = p.split('/'); |
| path.pop(); |
| |
| for (var i = 0; i < segs.length; i++) { |
| var seg = segs[i]; |
| if ('..' == seg) path.pop(); |
| else if ('.' != seg) path.push(seg); |
| } |
| |
| return require(path.join('/')); |
| }; |
| }; |
| |
| |
| require.register("browser/debug.js", function(module, exports, require){ |
| |
| module.exports = function(type){ |
| return function(){ |
| } |
| }; |
| |
| }); // module: browser/debug.js |
| |
| require.register("browser/events.js", function(module, exports, require){ |
| |
| /** |
| * Module exports. |
| */ |
| |
| exports.EventEmitter = EventEmitter; |
| |
| /** |
| * Check if `obj` is an array. |
| */ |
| |
| function isArray(obj) { |
| return '[object Array]' == {}.toString.call(obj); |
| } |
| |
| /** |
| * Event emitter constructor. |
| * |
| * @api public |
| */ |
| |
| function EventEmitter(){}; |
| |
| /** |
| * Adds a listener. |
| * |
| * @api public |
| */ |
| |
| EventEmitter.prototype.on = function (name, fn) { |
| if (!this.$events) { |
| this.$events = {}; |
| } |
| |
| if (!this.$events[name]) { |
| this.$events[name] = fn; |
| } else if (isArray(this.$events[name])) { |
| this.$events[name].push(fn); |
| } else { |
| this.$events[name] = [this.$events[name], fn]; |
| } |
| |
| return this; |
| }; |
| |
| EventEmitter.prototype.addListener = EventEmitter.prototype.on; |
| |
| /** |
| * Adds a volatile listener. |
| * |
| * @api public |
| */ |
| |
| EventEmitter.prototype.once = function (name, fn) { |
| var self = this; |
| |
| function on () { |
| self.removeListener(name, on); |
| fn.apply(this, arguments); |
| }; |
| |
| on.listener = fn; |
| this.on(name, on); |
| |
| return this; |
| }; |
| |
| /** |
| * Removes a listener. |
| * |
| * @api public |
| */ |
| |
| EventEmitter.prototype.removeListener = function (name, fn) { |
| if (this.$events && this.$events[name]) { |
| var list = this.$events[name]; |
| |
| if (isArray(list)) { |
| var pos = -1; |
| |
| for (var i = 0, l = list.length; i < l; i++) { |
| if (list[i] === fn || (list[i].listener && list[i].listener === fn)) { |
| pos = i; |
| break; |
| } |
| } |
| |
| if (pos < 0) { |
| return this; |
| } |
| |
| list.splice(pos, 1); |
| |
| if (!list.length) { |
| delete this.$events[name]; |
| } |
| } else if (list === fn || (list.listener && list.listener === fn)) { |
| delete this.$events[name]; |
| } |
| } |
| |
| return this; |
| }; |
| |
| /** |
| * Removes all listeners for an event. |
| * |
| * @api public |
| */ |
| |
| EventEmitter.prototype.removeAllListeners = function (name) { |
| if (name === undefined) { |
| this.$events = {}; |
| return this; |
| } |
| |
| if (this.$events && this.$events[name]) { |
| this.$events[name] = null; |
| } |
| |
| return this; |
| }; |
| |
| /** |
| * Gets all listeners for a certain event. |
| * |
| * @api public |
| */ |
| |
| EventEmitter.prototype.listeners = function (name) { |
| if (!this.$events) { |
| this.$events = {}; |
| } |
| |
| if (!this.$events[name]) { |
| this.$events[name] = []; |
| } |
| |
| if (!isArray(this.$events[name])) { |
| this.$events[name] = [this.$events[name]]; |
| } |
| |
| return this.$events[name]; |
| }; |
| |
| /** |
| * Emits an event. |
| * |
| * @api public |
| */ |
| |
| EventEmitter.prototype.emit = function (name) { |
| if (!this.$events) { |
| return false; |
| } |
| |
| var handler = this.$events[name]; |
| |
| if (!handler) { |
| return false; |
| } |
| |
| var args = [].slice.call(arguments, 1); |
| |
| if ('function' == typeof handler) { |
| handler.apply(this, args); |
| } else if (isArray(handler)) { |
| var listeners = handler.slice(); |
| |
| for (var i = 0, l = listeners.length; i < l; i++) { |
| listeners[i].apply(this, args); |
| } |
| } else { |
| return false; |
| } |
| |
| return true; |
| }; |
| }); // module: browser/events.js |
| |
| require.register("browser/path.js", function(module, exports, require){ |
| |
| }); // module: browser/path.js |
| |
| require.register("context.js", function(module, exports, require){ |
| |
| /** |
| * Expose `Context`. |
| */ |
| |
| module.exports = Context; |
| |
| /** |
| * Initialize a new `Context`. |
| * |
| * @api private |
| */ |
| |
| function Context(){} |
| |
| /** |
| * Set or get the context `Runnable` to `runnable`. |
| * |
| * @param {Runnable} runnable |
| * @return {Context} |
| * @api private |
| */ |
| |
| Context.prototype.runnable = function(runnable){ |
| if (0 == arguments.length) return this._runnable; |
| this.test = this._runnable = runnable; |
| return this; |
| }; |
| |
| /** |
| * Set test timeout `ms`. |
| * |
| * @param {Number} ms |
| * @return {Context} self |
| * @api private |
| */ |
| |
| Context.prototype.timeout = function(ms){ |
| if (arguments.length === 0) return this.runnable().timeout(); |
| this.runnable().timeout(ms); |
| return this; |
| }; |
| |
| /** |
| * Set test timeout `enabled`. |
| * |
| * @param {Boolean} enabled |
| * @return {Context} self |
| * @api private |
| */ |
| |
| Context.prototype.enableTimeouts = function (enabled) { |
| this.runnable().enableTimeouts(enabled); |
| return this; |
| }; |
| |
| |
| /** |
| * Set test slowness threshold `ms`. |
| * |
| * @param {Number} ms |
| * @return {Context} self |
| * @api private |
| */ |
| |
| Context.prototype.slow = function(ms){ |
| this.runnable().slow(ms); |
| return this; |
| }; |
| |
| /** |
| * Inspect the context void of `._runnable`. |
| * |
| * @return {String} |
| * @api private |
| */ |
| |
| Context.prototype.inspect = function(){ |
| return JSON.stringify(this, function(key, val){ |
| if ('_runnable' == key) return; |
| if ('test' == key) return; |
| return val; |
| }, 2); |
| }; |
| |
| }); // module: context.js |
| |
| require.register("hook.js", function(module, exports, require){ |
| |
| /** |
| * Module dependencies. |
| */ |
| |
| var Runnable = require('./runnable'); |
| |
| /** |
| * Expose `Hook`. |
| */ |
| |
| module.exports = Hook; |
| |
| /** |
| * Initialize a new `Hook` with the given `title` and callback `fn`. |
| * |
| * @param {String} title |
| * @param {Function} fn |
| * @api private |
| */ |
| |
| function Hook(title, fn) { |
| Runnable.call(this, title, fn); |
| this.type = 'hook'; |
| } |
| |
| /** |
| * Inherit from `Runnable.prototype`. |
| */ |
| |
| function F(){}; |
| F.prototype = Runnable.prototype; |
| Hook.prototype = new F; |
| Hook.prototype.constructor = Hook; |
| |
| |
| /** |
| * Get or set the test `err`. |
| * |
| * @param {Error} err |
| * @return {Error} |
| * @api public |
| */ |
| |
| Hook.prototype.error = function(err){ |
| if (0 == arguments.length) { |
| var err = this._error; |
| this._error = null; |
| return err; |
| } |
| |
| this._error = err; |
| }; |
| |
| }); // module: hook.js |
| |
| require.register("interfaces/bdd.js", function(module, exports, require){ |
| |
| /** |
| * Module dependencies. |
| */ |
| |
| var Suite = require('../suite') |
| , Test = require('../test') |
| , utils = require('../utils'); |
| |
| /** |
| * BDD-style interface: |
| * |
| * describe('Array', function(){ |
| * describe('#indexOf()', function(){ |
| * it('should return -1 when not present', function(){ |
| * |
| * }); |
| * |
| * it('should return the index when present', function(){ |
| * |
| * }); |
| * }); |
| * }); |
| * |
| */ |
| |
| module.exports = function(suite){ |
| var suites = [suite]; |
| |
| suite.on('pre-require', function(context, file, mocha){ |
| |
| /** |
| * Execute before running tests. |
| */ |
| |
| context.before = function(name, fn){ |
| suites[0].beforeAll(name, fn); |
| }; |
| |
| /** |
| * Execute after running tests. |
| */ |
| |
| context.after = function(name, fn){ |
| suites[0].afterAll(name, fn); |
| }; |
| |
| /** |
| * Execute before each test case. |
| */ |
| |
| context.beforeEach = function(name, fn){ |
| suites[0].beforeEach(name, fn); |
| }; |
| |
| /** |
| * Execute after each test case. |
| */ |
| |
| context.afterEach = function(name, fn){ |
| suites[0].afterEach(name, fn); |
| }; |
| |
| /** |
| * Describe a "suite" with the given `title` |
| * and callback `fn` containing nested suites |
| * and/or tests. |
| */ |
| |
| context.describe = context.context = function(title, fn){ |
| var suite = Suite.create(suites[0], title); |
| suite.file = file; |
| suites.unshift(suite); |
| fn.call(suite); |
| suites.shift(); |
| return suite; |
| }; |
| |
| /** |
| * Pending describe. |
| */ |
| |
| context.describe.skip = function(title, fn){ |
| var suite = Suite.create(suites[0], title); |
| suite.pending = true; |
| suites.unshift(suite); |
| fn.call(suite); |
| suites.shift(); |
| }; |
| |
| context.describe.only = function(title, fn){ |
| var suite = context.describe(title, fn); |
| mocha.grep(suite.fullTitle()); |
| return suite; |
| }; |
| |
| |
| /** |
| * Describe a specification or test-case |
| * with the given `title` and callback `fn` |
| * acting as a thunk. |
| */ |
| |
| context.it = function(title, fn){ |
| var suite = suites[0]; |
| if (suite.pending) var fn = null; |
| var test = new Test(title, fn); |
| test.file = file; |
| suite.addTest(test); |
| return test; |
| }; |
| |
| context.it.only = function(title, fn){ |
| var test = context.it(title, fn); |
| var reString = '^' + utils.escapeRegexp(test.fullTitle()) + '$'; |
| mocha.grep(new RegExp(reString)); |
| return test; |
| }; |
| |
| |
| /** |
| * Pending test case. |
| */ |
| |
| context.it.skip = function(title){ |
| context.it(title); |
| }; |
| }); |
| }; |
| |
| }); // module: interfaces/bdd.js |
| |
| require.register("interfaces/exports.js", function(module, exports, require){ |
| |
| /** |
| * Module dependencies. |
| SGMcan */ |
| |
| var Suite = require('../suite') |
| , Test = require('../test'); |
| |
| /** |
| * TDD-style interface: |
| * |
| * exports.Array = { |
| * '#indexOf()': { |
| * 'should return -1 when the value is not present': function(){ |
| * |
| * }, |
| * |
| * 'should return the correct index when the value is present': function(){ |
| * |
| * } |
| * } |
| * }; |
| * |
| */ |
| |
| module.exports = function(suite){ |
| var suites = [suite]; |
| |
| suite.on('require', visit); |
| |
| function visit(obj, file) { |
| var suite; |
| for (var key in obj) { |
| if ('function' == typeof obj[key]) { |
| var fn = obj[key]; |
| switch (key) { |
| case 'before': |
| suites[0].beforeAll(fn); |
| break; |
| case 'after': |
| suites[0].afterAll(fn); |
| break; |
| case 'beforeEach': |
| suites[0].beforeEach(fn); |
| break; |
| case 'afterEach': |
| suites[0].afterEach(fn); |
| break; |
| default: |
| var test = new Test(key, fn); |
| test.file = file; |
| suites[0].addTest(test); |
| } |
| } else { |
| var suite = Suite.create(suites[0], key); |
| suites.unshift(suite); |
| visit(obj[key]); |
| suites.shift(); |
| } |
| } |
| } |
| }; |
| |
| }); // module: interfaces/exports.js |
| |
| require.register("interfaces/index.js", function(module, exports, require){ |
| |
| exports.bdd = require('./bdd'); |
| exports.exports = require('./exports'); |
| |
| }); // module: interfaces/index.js |
| |
| require.register("mocha.js", function(module, exports, require){ |
| /*! |
| * mocha |
| * Copyright(c) 2011 TJ Holowaychuk <tj@vision-media.ca> |
| * MIT Licensed |
| */ |
| |
| /** |
| * Module dependencies. |
| */ |
| |
| var path = require('browser/path') |
| , utils = require('./utils'); |
| |
| /** |
| * Expose `Mocha`. |
| */ |
| |
| exports = module.exports = Mocha; |
| |
| /** |
| * To require local UIs and reporters when running in node. |
| */ |
| |
| if (typeof process !== 'undefined' && typeof process.cwd === 'function') { |
| var join = path.join |
| , cwd = process.cwd(); |
| module.paths.push(cwd, join(cwd, 'node_modules')); |
| } |
| |
| /** |
| * Expose internals. |
| */ |
| |
| exports.utils = utils; |
| exports.interfaces = require('./interfaces'); |
| exports.reporters = require('./reporters'); |
| exports.Runnable = require('./runnable'); |
| exports.Context = require('./context'); |
| exports.Runner = require('./runner'); |
| exports.Suite = require('./suite'); |
| exports.Hook = require('./hook'); |
| exports.Test = require('./test'); |
| |
| /** |
| * Setup mocha with `options`. |
| * |
| * Options: |
| * |
| * - `ui` name "bdd", "tdd", "exports" etc |
| * - `reporter` reporter instance, defaults to `mocha.reporters.spec` |
| * - `timeout` timeout in milliseconds |
| * - `bail` bail on the first test failure |
| * - `slow` milliseconds to wait before considering a test slow |
| * |
| * @param {Object} options |
| * @api public |
| */ |
| |
| function Mocha(options) { |
| options = options || {}; |
| this.files = []; |
| this.options = options; |
| this.grep(options.grep); |
| this.suite = new exports.Suite('', new exports.Context); |
| this.ui(options.ui); |
| this.bail(options.bail); |
| this.reporter(); |
| if (null != options.timeout) this.timeout(options.timeout); |
| if (options.enableTimeouts !== null) this.enableTimeouts(options.enableTimeouts); |
| if (options.slow) this.slow(options.slow); |
| |
| this.suite.on('pre-require', function (context) { |
| exports.afterEach = context.afterEach; |
| exports.after = context.after; |
| exports.beforeEach = context.beforeEach; |
| exports.before = context.before; |
| exports.describe = context.describe; |
| exports.it = context.it; |
| }); |
| } |
| |
| /** |
| * Enable or disable bailing on the first failure. |
| * |
| * @param {Boolean} [bail] |
| * @api public |
| */ |
| |
| Mocha.prototype.bail = function(bail){ |
| if (0 == arguments.length) bail = true; |
| this.suite.bail(bail); |
| return this; |
| }; |
| |
| /** |
| * Set reporter to `reporter`, defaults to "spec". |
| * |
| * @param {String|Function} reporter name or constructor |
| * @api public |
| */ |
| |
| Mocha.prototype.reporter = function(){ |
| var _reporter = require('./reporters/tap'); |
| this._reporter = _reporter; |
| }; |
| |
| /** |
| * Set test UI `name`, defaults to "bdd". |
| * |
| * @param {String} bdd |
| * @api public |
| */ |
| |
| Mocha.prototype.ui = function(name){ |
| name = name || 'bdd'; |
| this._ui = exports.interfaces[name]; |
| if (!this._ui) try { this._ui = require(name); } catch (err) {}; |
| if (!this._ui) throw new Error('invalid interface "' + name + '"'); |
| this._ui = this._ui(this.suite); |
| return this; |
| }; |
| |
| Mocha.prototype.grep = function(re){ |
| this.options.grep = 'string' == typeof re |
| ? new RegExp(utils.escapeRegexp(re)) |
| : re; |
| return this; |
| }; |
| |
| /** |
| * Set the timeout in milliseconds. |
| * |
| * @param {Number} timeout |
| * @return {Mocha} |
| * @api public |
| */ |
| |
| Mocha.prototype.timeout = function(timeout){ |
| this.suite.timeout(timeout); |
| return this; |
| }; |
| |
| /** |
| * Set slowness threshold in milliseconds. |
| * |
| * @param {Number} slow |
| * @return {Mocha} |
| * @api public |
| */ |
| |
| Mocha.prototype.slow = function(slow){ |
| this.suite.slow(slow); |
| return this; |
| }; |
| |
| /** |
| * Enable timeouts. |
| * |
| * @param {Boolean} enabled |
| * @return {Mocha} |
| * @api public |
| */ |
| |
| Mocha.prototype.enableTimeouts = function(enabled) { |
| this.suite.enableTimeouts(arguments.length && enabled !== undefined |
| ? enabled |
| : true); |
| return this |
| }; |
| |
| /** |
| * Makes all tests async (accepting a callback) |
| * |
| * @return {Mocha} |
| * @api public |
| */ |
| |
| Mocha.prototype.asyncOnly = function(){ |
| this.options.asyncOnly = true; |
| return this; |
| }; |
| |
| /** |
| * Run tests and invoke `fn()` when complete. |
| * |
| * @param {Function} fn |
| * @return {Runner} |
| * @api public |
| */ |
| |
| Mocha.prototype.run = function(fn){ |
| var suite = this.suite; |
| var options = this.options; |
| options.files = this.files; |
| var runner = new exports.Runner(suite); |
| var reporter = new this._reporter(runner, options); |
| if (options.grep) runner.grep(options.grep); |
| return runner.run(fn); |
| }; |
| |
| }); // module: mocha.js |
| |
| require.register("ms.js", function(module, exports, require){ |
| /** |
| * Helpers. |
| */ |
| |
| var s = 1000; |
| var m = s * 60; |
| var h = m * 60; |
| var d = h * 24; |
| var y = d * 365.25; |
| |
| /** |
| * Parse or format the given `val`. |
| * |
| * Options: |
| * |
| * - `long` verbose formatting [false] |
| * |
| * @param {String|Number} val |
| * @param {Object} options |
| * @return {String|Number} |
| * @api public |
| */ |
| |
| module.exports = function(val, options){ |
| options = options || {}; |
| if ('string' == typeof val) return parse(val); |
| return options.long ? longFormat(val) : shortFormat(val); |
| }; |
| |
| /** |
| * Parse the given `str` and return milliseconds. |
| * |
| * @param {String} str |
| * @return {Number} |
| * @api private |
| */ |
| |
| function parse(str) { |
| var match = /^((?:\d+)?\.?\d+) *(ms|seconds?|s|minutes?|m|hours?|h|days?|d|years?|y)?$/i.exec(str); |
| if (!match) return; |
| var n = parseFloat(match[1]); |
| var type = (match[2] || 'ms').toLowerCase(); |
| switch (type) { |
| case 'years': |
| case 'year': |
| case 'y': |
| return n * y; |
| case 'days': |
| case 'day': |
| case 'd': |
| return n * d; |
| case 'hours': |
| case 'hour': |
| case 'h': |
| return n * h; |
| case 'minutes': |
| case 'minute': |
| case 'm': |
| return n * m; |
| case 'seconds': |
| case 'second': |
| case 's': |
| return n * s; |
| case 'ms': |
| return n; |
| } |
| } |
| |
| /** |
| * Short format for `ms`. |
| * |
| * @param {Number} ms |
| * @return {String} |
| * @api private |
| */ |
| |
| function shortFormat(ms) { |
| if (ms >= d) return Math.round(ms / d) + 'd'; |
| if (ms >= h) return Math.round(ms / h) + 'h'; |
| if (ms >= m) return Math.round(ms / m) + 'm'; |
| if (ms >= s) return Math.round(ms / s) + 's'; |
| return ms + 'ms'; |
| } |
| |
| /** |
| * Long format for `ms`. |
| * |
| * @param {Number} ms |
| * @return {String} |
| * @api private |
| */ |
| |
| function longFormat(ms) { |
| return plural(ms, d, 'day') |
| || plural(ms, h, 'hour') |
| || plural(ms, m, 'minute') |
| || plural(ms, s, 'second') |
| || ms + ' ms'; |
| } |
| |
| /** |
| * Pluralization helper. |
| */ |
| |
| function plural(ms, n, name) { |
| if (ms < n) return; |
| if (ms < n * 1.5) return Math.floor(ms / n) + ' ' + name; |
| return Math.ceil(ms / n) + ' ' + name + 's'; |
| } |
| |
| }); // module: ms.js |
| |
| require.register("reporters/base.js", function(module, exports, require){ |
| |
| /** |
| * Module dependencies. |
| */ |
| |
| var ms = require('../ms') |
| , utils = require('../utils'); |
| |
| |
| /** |
| * Expose `Base`. |
| */ |
| |
| exports = module.exports = Base; |
| |
| /** |
| * Enable coloring by default. |
| */ |
| |
| exports.useColors = false; |
| |
| /** |
| * Inline diffs instead of +/- |
| */ |
| |
| exports.inlineDiffs = false; |
| |
| /** |
| * Default symbol map. |
| */ |
| |
| exports.symbols = { |
| ok: '✓', |
| err: '✖', |
| dot: '․' |
| }; |
| |
| /** |
| * Expose term window size, with some |
| * defaults for when stderr is not a tty. |
| */ |
| |
| exports.window = { |
| width: 75 |
| }; |
| |
| |
| /** |
| * Outut the given `failures` as a list. |
| * |
| * @param {Array} failures |
| * @api public |
| */ |
| |
| exports.list = function(failures){ |
| |
| }; |
| |
| /** |
| * Initialize a new `Base` reporter. |
| * |
| * All other reporters generally |
| * inherit from this reporter, providing |
| * stats such as test duration, number |
| * of tests passed / failed etc. |
| * |
| * @param {Runner} runner |
| * @api public |
| */ |
| |
| function Base(runner) { |
| if (!runner) return; |
| this.runner = runner; |
| } |
| |
| |
| }); // module: reporters/base.js |
| |
| require.register("reporters/index.js", function(module, exports, require){ |
| |
| exports.Base = require('./base'); |
| exports.TAP = require('./tap'); |
| |
| }); // module: reporters/index.js |
| |
| require.register("reporters/tap.js", function(module, exports, require){ |
| |
| /** |
| * Module dependencies. |
| */ |
| |
| var Base = require('./base') |
| , color = Base.color; |
| |
| |
| function Logger() { |
| this.items = []; |
| } |
| |
| Logger.prototype.log = function(message) { |
| this.items.push(message); |
| } |
| |
| Logger.prototype.flush = function() { |
| var body = document.documentElement; |
| body.textContent = ''; |
| body.appendChild(document.createElement('style')).textContent = 'item { display: block; }'; |
| this.items.forEach(function(item) { |
| body.appendChild(document.createElement('item')).textContent = item; |
| }); |
| } |
| |
| /** |
| * Expose `TAP`. |
| */ |
| |
| exports = module.exports = TAP; |
| |
| /** |
| * Initialize a new `TAP` reporter. |
| * |
| * @param {Runner} runner |
| * @api public |
| */ |
| |
| function TAP(runner) { |
| Base.call(this, runner); |
| var logger = new Logger(); |
| |
| var self = this |
| , stats = this.stats |
| , n = 1 |
| , passes = 0 |
| , failures = 0; |
| |
| runner.on('start', function(){ |
| var total = runner.grepTotal(runner.suite); |
| logger.log('Running ' + total + ' tests'); |
| }); |
| |
| runner.on('test end', function(){ |
| ++n; |
| }); |
| |
| runner.on('pending', function(test){ |
| logger.log('ok ' + n + ' ' + title(test) + ' # SKIP -'); |
| }); |
| |
| runner.on('pass', function(test){ |
| passes++; |
| logger.log('ok ' + n + ' ' + title(test)); |
| }); |
| |
| runner.on('fail', function(test, err){ |
| failures++; |
| logger.log('not ok ' + n + ' ' + title(test)); |
| if (err.stack) logger.log(err.stack.replace(/^/gm, ' ')); |
| }); |
| |
| runner.on('end', function(){ |
| logger.log((passes + failures) + ' tests'); |
| logger.log(passes + ' pass'); |
| logger.log(failures + ' fail'); |
| logger.flush(); |
| window.internals && window.internals.notifyTestComplete(internals.contentAsText()); |
| }); |
| } |
| |
| /** |
| * Return a TAP-safe title of `test` |
| * |
| * @param {Object} test |
| * @return {String} |
| * @api private |
| */ |
| |
| function title(test) { |
| return test.fullTitle().replace(/#/g, ''); |
| } |
| |
| }); // module: reporters/tap.js |
| |
| require.register("runnable.js", function(module, exports, require){ |
| |
| /** |
| * Module dependencies. |
| */ |
| |
| var EventEmitter = require('browser/events').EventEmitter |
| , debug = require('browser/debug')('mocha:runnable') |
| , milliseconds = require('./ms'); |
| |
| /** |
| * Object#toString(). |
| */ |
| |
| var toString = Object.prototype.toString; |
| |
| /** |
| * Expose `Runnable`. |
| */ |
| |
| module.exports = Runnable; |
| |
| /** |
| * Initialize a new `Runnable` with the given `title` and callback `fn`. |
| * |
| * @param {String} title |
| * @param {Function} fn |
| * @api private |
| */ |
| |
| function Runnable(title, fn) { |
| this.title = title; |
| this.fn = fn; |
| this.async = fn && fn.length; |
| this.sync = ! this.async; |
| this._timeout = 2000; |
| this._slow = 75; |
| this._enableTimeouts = true; |
| this.timedOut = false; |
| } |
| |
| /** |
| * Inherit from `EventEmitter.prototype`. |
| */ |
| |
| function F(){}; |
| F.prototype = EventEmitter.prototype; |
| Runnable.prototype = new F; |
| Runnable.prototype.constructor = Runnable; |
| |
| |
| /** |
| * Set & get timeout `ms`. |
| * |
| * @param {Number|String} ms |
| * @return {Runnable|Number} ms or self |
| * @api private |
| */ |
| |
| Runnable.prototype.timeout = function(ms){ |
| if (0 == arguments.length) return this._timeout; |
| if ('string' == typeof ms) ms = milliseconds(ms); |
| debug('timeout %d', ms); |
| this._timeout = ms; |
| if (this.timer) this.resetTimeout(); |
| return this; |
| }; |
| |
| /** |
| * Set & get slow `ms`. |
| * |
| * @param {Number|String} ms |
| * @return {Runnable|Number} ms or self |
| * @api private |
| */ |
| |
| Runnable.prototype.slow = function(ms){ |
| if (0 === arguments.length) return this._slow; |
| if ('string' == typeof ms) ms = milliseconds(ms); |
| debug('timeout %d', ms); |
| this._slow = ms; |
| return this; |
| }; |
| |
| /** |
| * Set and & get timeout `enabled`. |
| * |
| * @param {Boolean} enabled |
| * @return {Runnable|Boolean} enabled or self |
| * @api private |
| */ |
| |
| Runnable.prototype.enableTimeouts = function(enabled){ |
| if (arguments.length === 0) return this._enableTimeouts; |
| debug('enableTimeouts %s', enabled); |
| this._enableTimeouts = enabled; |
| return this; |
| }; |
| |
| /** |
| * Return the full title generated by recursively |
| * concatenating the parent's full title. |
| * |
| * @return {String} |
| * @api public |
| */ |
| |
| Runnable.prototype.fullTitle = function(){ |
| return this.parent.fullTitle() + ' ' + this.title; |
| }; |
| |
| /** |
| * Clear the timeout. |
| * |
| * @api private |
| */ |
| |
| Runnable.prototype.clearTimeout = function(){ |
| clearTimeout(this.timer); |
| }; |
| |
| /** |
| * Inspect the runnable void of private properties. |
| * |
| * @return {String} |
| * @api private |
| */ |
| |
| Runnable.prototype.inspect = function(){ |
| return JSON.stringify(this, function(key, val){ |
| if ('_' == key[0]) return; |
| if ('parent' == key) return '#<Suite>'; |
| if ('ctx' == key) return '#<Context>'; |
| return val; |
| }, 2); |
| }; |
| |
| /** |
| * Reset the timeout. |
| * |
| * @api private |
| */ |
| |
| Runnable.prototype.resetTimeout = function(){ |
| var self = this; |
| var ms = this.timeout() || 1e9; |
| |
| if (!this._enableTimeouts) return; |
| this.clearTimeout(); |
| this.timer = setTimeout(function(){ |
| self.callback(new Error('timeout of ' + ms + 'ms exceeded')); |
| self.timedOut = true; |
| }, ms); |
| }; |
| |
| /** |
| * Run the test and invoke `fn(err)`. |
| * |
| * @param {Function} fn |
| * @api private |
| */ |
| |
| Runnable.prototype.run = function(fn){ |
| var self = this |
| , start = new Date |
| , ctx = this.ctx |
| , finished |
| , emitted; |
| |
| // Some times the ctx exists but it is not runnable |
| if (ctx && ctx.runnable) ctx.runnable(this); |
| |
| // called multiple times |
| function multiple(err) { |
| if (emitted) return; |
| emitted = true; |
| self.emit('error', err || new Error('done() called multiple times')); |
| } |
| |
| // finished |
| function done(err) { |
| var ms = self.timeout(); |
| if (self.timedOut) return; |
| if (finished) return multiple(err); |
| self.clearTimeout(); |
| self.duration = new Date - start; |
| finished = true; |
| if (!err && self.duration > ms && self._enableTimeouts) err = new Error('timeout of ' + ms + 'ms exceeded'); |
| fn(err); |
| } |
| |
| // for .resetTimeout() |
| this.callback = done; |
| |
| // explicit async with `done` argument |
| if (this.async) { |
| this.resetTimeout(); |
| |
| try { |
| this.fn.call(ctx, function(err){ |
| if (err instanceof Error || toString.call(err) === "[object Error]") return done(err); |
| if (null != err) { |
| if (Object.prototype.toString.call(err) === '[object Object]') { |
| return done(new Error('done() invoked with non-Error: ' + JSON.stringify(err))); |
| } else { |
| return done(new Error('done() invoked with non-Error: ' + err)); |
| } |
| } |
| done(); |
| }); |
| } catch (err) { |
| done(err); |
| } |
| return; |
| } |
| |
| if (this.asyncOnly) { |
| return done(new Error('--async-only option in use without declaring `done()`')); |
| } |
| |
| // sync or promise-returning |
| try { |
| if (this.pending) { |
| done(); |
| } else { |
| callFn(this.fn); |
| } |
| } catch (err) { |
| done(err); |
| } |
| |
| function callFn(fn) { |
| var result = fn.call(ctx); |
| if (result && typeof result.then === 'function') { |
| self.resetTimeout(); |
| result |
| .then(function() { |
| done() |
| }, |
| function(reason) { |
| done(reason || new Error('Promise rejected with no or falsy reason')) |
| }); |
| } else { |
| done(); |
| } |
| } |
| }; |
| |
| }); // module: runnable.js |
| |
| require.register("runner.js", function(module, exports, require){ |
| /** |
| * Module dependencies. |
| */ |
| |
| var EventEmitter = require('browser/events').EventEmitter |
| , debug = require('browser/debug')('mocha:runner') |
| , Test = require('./test') |
| , utils = require('./utils') |
| , filter = utils.filter |
| , keys = utils.keys; |
| |
| /** |
| * Expose `Runner`. |
| */ |
| |
| module.exports = Runner; |
| |
| /** |
| * Initialize a `Runner` for the given `suite`. |
| * |
| * Events: |
| * |
| * - `start` execution started |
| * - `end` execution complete |
| * - `suite` (suite) test suite execution started |
| * - `suite end` (suite) all tests (and sub-suites) have finished |
| * - `test` (test) test execution started |
| * - `test end` (test) test completed |
| * - `hook` (hook) hook execution started |
| * - `hook end` (hook) hook complete |
| * - `pass` (test) test passed |
| * - `fail` (test, err) test failed |
| * - `pending` (test) test pending |
| * |
| * @api public |
| */ |
| |
| function Runner(suite) { |
| var self = this; |
| this._abort = false; |
| this.suite = suite; |
| this.total = suite.total(); |
| this.failures = 0; |
| this.grep(/.*/); |
| } |
| |
| /** |
| * Wrapper for setImmediate, process.nextTick, or browser polyfill. |
| * |
| * @param {Function} fn |
| * @api private |
| */ |
| |
| Runner.immediately = process.nextTick; |
| |
| /** |
| * Inherit from `EventEmitter.prototype`. |
| */ |
| |
| function F(){}; |
| F.prototype = EventEmitter.prototype; |
| Runner.prototype = new F; |
| Runner.prototype.constructor = Runner; |
| |
| |
| /** |
| * Run tests with full titles matching `re`. Updates runner.total |
| * with number of tests matched. |
| * |
| * @param {RegExp} re |
| * @param {Boolean} invert |
| * @return {Runner} for chaining |
| * @api public |
| */ |
| |
| Runner.prototype.grep = function(re, invert){ |
| debug('grep %s', re); |
| this._grep = re; |
| this._invert = invert; |
| this.total = this.grepTotal(this.suite); |
| return this; |
| }; |
| |
| /** |
| * Returns the number of tests matching the grep search for the |
| * given suite. |
| * |
| * @param {Suite} suite |
| * @return {Number} |
| * @api public |
| */ |
| |
| Runner.prototype.grepTotal = function(suite) { |
| var self = this; |
| var total = 0; |
| |
| suite.eachTest(function(test){ |
| var match = self._grep.test(test.fullTitle()); |
| if (self._invert) match = !match; |
| if (match) total++; |
| }); |
| |
| return total; |
| }; |
| |
| /** |
| * Check for global variable leaks. |
| * |
| * @api private |
| */ |
| |
| /** |
| * Fail the given `test`. |
| * |
| * @param {Test} test |
| * @param {Error} err |
| * @api private |
| */ |
| |
| Runner.prototype.fail = function(test, err){ |
| ++this.failures; |
| test.state = 'failed'; |
| |
| if ('string' == typeof err) { |
| err = new Error('the string "' + err + '" was thrown, throw an Error :)'); |
| } |
| |
| this.emit('fail', test, err); |
| }; |
| |
| /** |
| * Fail the given `hook` with `err`. |
| * |
| * Hook failures work in the following pattern: |
| * - If bail, then exit |
| * - Failed `before` hook skips all tests in a suite and subsuites, |
| * but jumps to corresponding `after` hook |
| * - Failed `before each` hook skips remaining tests in a |
| * suite and jumps to corresponding `after each` hook, |
| * which is run only once |
| * - Failed `after` hook does not alter |
| * execution order |
| * - Failed `after each` hook skips remaining tests in a |
| * suite and subsuites, but executes other `after each` |
| * hooks |
| * |
| * @param {Hook} hook |
| * @param {Error} err |
| * @api private |
| */ |
| |
| Runner.prototype.failHook = function(hook, err){ |
| this.fail(hook, err); |
| if (this.suite.bail()) { |
| this.emit('end'); |
| } |
| }; |
| |
| /** |
| * Run hook `name` callbacks and then invoke `fn()`. |
| * |
| * @param {String} name |
| * @param {Function} function |
| * @api private |
| */ |
| |
| Runner.prototype.hook = function(name, fn){ |
| var suite = this.suite |
| , hooks = suite['_' + name] |
| , self = this |
| , timer; |
| |
| function next(i) { |
| var hook = hooks[i]; |
| if (!hook) return fn(); |
| if (self.failures && suite.bail()) return fn(); |
| self.currentRunnable = hook; |
| |
| hook.ctx.currentTest = self.test; |
| |
| self.emit('hook', hook); |
| |
| hook.on('error', function(err){ |
| self.failHook(hook, err); |
| }); |
| |
| hook.run(function(err){ |
| hook.removeAllListeners('error'); |
| var testError = hook.error(); |
| if (testError) self.fail(self.test, testError); |
| if (err) { |
| self.failHook(hook, err); |
| |
| // stop executing hooks, notify callee of hook err |
| return fn(err); |
| } |
| self.emit('hook end', hook); |
| delete hook.ctx.currentTest; |
| next(++i); |
| }); |
| } |
| |
| Runner.immediately(function(){ |
| next(0); |
| }); |
| }; |
| |
| /** |
| * Run hook `name` for the given array of `suites` |
| * in order, and callback `fn(err, errSuite)`. |
| * |
| * @param {String} name |
| * @param {Array} suites |
| * @param {Function} fn |
| * @api private |
| */ |
| |
| Runner.prototype.hooks = function(name, suites, fn){ |
| var self = this |
| , orig = this.suite; |
| |
| function next(suite) { |
| self.suite = suite; |
| |
| if (!suite) { |
| self.suite = orig; |
| return fn(); |
| } |
| |
| self.hook(name, function(err){ |
| if (err) { |
| var errSuite = self.suite; |
| self.suite = orig; |
| return fn(err, errSuite); |
| } |
| |
| next(suites.pop()); |
| }); |
| } |
| |
| next(suites.pop()); |
| }; |
| |
| /** |
| * Run hooks from the top level down. |
| * |
| * @param {String} name |
| * @param {Function} fn |
| * @api private |
| */ |
| |
| Runner.prototype.hookUp = function(name, fn){ |
| var suites = [this.suite].concat(this.parents()).reverse(); |
| this.hooks(name, suites, fn); |
| }; |
| |
| /** |
| * Run hooks from the bottom up. |
| * |
| * @param {String} name |
| * @param {Function} fn |
| * @api private |
| */ |
| |
| Runner.prototype.hookDown = function(name, fn){ |
| var suites = [this.suite].concat(this.parents()); |
| this.hooks(name, suites, fn); |
| }; |
| |
| /** |
| * Return an array of parent Suites from |
| * closest to furthest. |
| * |
| * @return {Array} |
| * @api private |
| */ |
| |
| Runner.prototype.parents = function(){ |
| var suite = this.suite |
| , suites = []; |
| while (suite = suite.parent) suites.push(suite); |
| return suites; |
| }; |
| |
| /** |
| * Run the current test and callback `fn(err)`. |
| * |
| * @param {Function} fn |
| * @api private |
| */ |
| |
| Runner.prototype.runTest = function(fn){ |
| var test = this.test |
| , self = this; |
| |
| if (this.asyncOnly) test.asyncOnly = true; |
| |
| try { |
| test.on('error', function(err){ |
| self.fail(test, err); |
| }); |
| test.run(fn); |
| } catch (err) { |
| fn(err); |
| } |
| }; |
| |
| /** |
| * Run tests in the given `suite` and invoke |
| * the callback `fn()` when complete. |
| * |
| * @param {Suite} suite |
| * @param {Function} fn |
| * @api private |
| */ |
| |
| Runner.prototype.runTests = function(suite, fn){ |
| var self = this |
| , tests = suite.tests.slice() |
| , test; |
| |
| |
| function hookErr(err, errSuite, after) { |
| // before/after Each hook for errSuite failed: |
| var orig = self.suite; |
| |
| // for failed 'after each' hook start from errSuite parent, |
| // otherwise start from errSuite itself |
| self.suite = after ? errSuite.parent : errSuite; |
| |
| if (self.suite) { |
| // call hookUp afterEach |
| self.hookUp('afterEach', function(err2, errSuite2) { |
| self.suite = orig; |
| // some hooks may fail even now |
| if (err2) return hookErr(err2, errSuite2, true); |
| // report error suite |
| fn(errSuite); |
| }); |
| } else { |
| // there is no need calling other 'after each' hooks |
| self.suite = orig; |
| fn(errSuite); |
| } |
| } |
| |
| function next(err, errSuite) { |
| // if we bail after first err |
| if (self.failures && suite._bail) return fn(); |
| |
| if (self._abort) return fn(); |
| |
| if (err) return hookErr(err, errSuite, true); |
| |
| // next test |
| test = tests.shift(); |
| |
| // all done |
| if (!test) return fn(); |
| |
| // grep |
| var match = self._grep.test(test.fullTitle()); |
| if (self._invert) match = !match; |
| if (!match) return next(); |
| |
| // pending |
| if (test.pending) { |
| self.emit('pending', test); |
| self.emit('test end', test); |
| return next(); |
| } |
| |
| // execute test and hook(s) |
| self.emit('test', self.test = test); |
| self.hookDown('beforeEach', function(err, errSuite){ |
| |
| if (err) return hookErr(err, errSuite, false); |
| |
| self.currentRunnable = self.test; |
| self.runTest(function(err){ |
| test = self.test; |
| |
| if (err) { |
| self.fail(test, err); |
| self.emit('test end', test); |
| return self.hookUp('afterEach', next); |
| } |
| |
| test.state = 'passed'; |
| self.emit('pass', test); |
| self.emit('test end', test); |
| self.hookUp('afterEach', next); |
| }); |
| }); |
| } |
| |
| this.next = next; |
| next(); |
| }; |
| |
| /** |
| * Run the given `suite` and invoke the |
| * callback `fn()` when complete. |
| * |
| * @param {Suite} suite |
| * @param {Function} fn |
| * @api private |
| */ |
| |
| Runner.prototype.runSuite = function(suite, fn){ |
| var total = this.grepTotal(suite) |
| , self = this |
| , i = 0; |
| |
| debug('run suite %s', suite.fullTitle()); |
| |
| if (!total) return fn(); |
| |
| this.emit('suite', this.suite = suite); |
| |
| function next(errSuite) { |
| if (errSuite) { |
| // current suite failed on a hook from errSuite |
| if (errSuite == suite) { |
| // if errSuite is current suite |
| // continue to the next sibling suite |
| return done(); |
| } else { |
| // errSuite is among the parents of current suite |
| // stop execution of errSuite and all sub-suites |
| return done(errSuite); |
| } |
| } |
| |
| if (self._abort) return done(); |
| |
| var curr = suite.suites[i++]; |
| if (!curr) return done(); |
| self.runSuite(curr, next); |
| } |
| |
| function done(errSuite) { |
| self.suite = suite; |
| self.hook('afterAll', function(){ |
| self.emit('suite end', suite); |
| fn(errSuite); |
| }); |
| } |
| |
| this.hook('beforeAll', function(err){ |
| if (err) return done(); |
| self.runTests(suite, next); |
| }); |
| }; |
| |
| /** |
| * Handle uncaught exceptions. |
| * |
| * @param {Error} err |
| * @api private |
| */ |
| |
| Runner.prototype.uncaught = function(err){ |
| if (err) { |
| debug('uncaught exception %s', err.message); |
| } else { |
| debug('uncaught undefined exception'); |
| err = new Error('Catched undefined error, did you throw without specifying what?'); |
| } |
| |
| var runnable = this.currentRunnable; |
| if (!runnable || 'failed' == runnable.state) return; |
| runnable.clearTimeout(); |
| err.uncaught = true; |
| this.fail(runnable, err); |
| |
| // recover from test |
| if ('test' == runnable.type) { |
| this.emit('test end', runnable); |
| this.hookUp('afterEach', this.next); |
| return; |
| } |
| |
| // bail on hooks |
| this.emit('end'); |
| }; |
| |
| /** |
| * Run the root suite and invoke `fn(failures)` |
| * on completion. |
| * |
| * @param {Function} fn |
| * @return {Runner} for chaining |
| * @api public |
| */ |
| |
| Runner.prototype.run = function(fn){ |
| var self = this |
| , fn = fn || function(){}; |
| |
| function uncaught(err){ |
| self.uncaught(err); |
| } |
| |
| debug('start'); |
| |
| // callback |
| this.on('end', function(){ |
| debug('end'); |
| process.removeListener('uncaughtException', uncaught); |
| fn(self.failures); |
| }); |
| |
| // run suites |
| this.emit('start'); |
| this.runSuite(this.suite, function(){ |
| debug('finished running'); |
| self.emit('end'); |
| }); |
| |
| // uncaught exception |
| process.on('uncaughtException', uncaught); |
| |
| return this; |
| }; |
| |
| /** |
| * Cleanly abort execution |
| * |
| * @return {Runner} for chaining |
| * @api public |
| */ |
| Runner.prototype.abort = function(){ |
| debug('aborting'); |
| this._abort = true; |
| } |
| |
| }); // module: runner.js |
| |
| require.register("suite.js", function(module, exports, require){ |
| |
| /** |
| * Module dependencies. |
| */ |
| |
| var EventEmitter = require('browser/events').EventEmitter |
| , debug = require('browser/debug')('mocha:suite') |
| , milliseconds = require('./ms') |
| , Hook = require('./hook'); |
| |
| /** |
| * Expose `Suite`. |
| */ |
| |
| exports = module.exports = Suite; |
| |
| /** |
| * Create a new `Suite` with the given `title` |
| * and parent `Suite`. When a suite with the |
| * same title is already present, that suite |
| * is returned to provide nicer reporter |
| * and more flexible meta-testing. |
| * |
| * @param {Suite} parent |
| * @param {String} title |
| * @return {Suite} |
| * @api public |
| */ |
| |
| exports.create = function(parent, title){ |
| var suite = new Suite(title, parent.ctx); |
| suite.parent = parent; |
| if (parent.pending) suite.pending = true; |
| title = suite.fullTitle(); |
| parent.addSuite(suite); |
| return suite; |
| }; |
| |
| /** |
| * Initialize a new `Suite` with the given |
| * `title` and `ctx`. |
| * |
| * @param {String} title |
| * @param {Context} ctx |
| * @api private |
| */ |
| |
| function Suite(title, parentContext) { |
| this.title = title; |
| var context = function() {}; |
| context.prototype = parentContext; |
| this.ctx = new context(); |
| this.suites = []; |
| this.tests = []; |
| this.pending = false; |
| this._beforeEach = []; |
| this._beforeAll = []; |
| this._afterEach = []; |
| this._afterAll = []; |
| this.root = !title; |
| this._timeout = 2000; |
| this._enableTimeouts = true; |
| this._slow = 75; |
| this._bail = false; |
| } |
| |
| /** |
| * Inherit from `EventEmitter.prototype`. |
| */ |
| |
| function F(){}; |
| F.prototype = EventEmitter.prototype; |
| Suite.prototype = new F; |
| Suite.prototype.constructor = Suite; |
| |
| |
| /** |
| * Return a clone of this `Suite`. |
| * |
| * @return {Suite} |
| * @api private |
| */ |
| |
| Suite.prototype.clone = function(){ |
| var suite = new Suite(this.title); |
| debug('clone'); |
| suite.ctx = this.ctx; |
| suite.timeout(this.timeout()); |
| suite.enableTimeouts(this.enableTimeouts()); |
| suite.slow(this.slow()); |
| suite.bail(this.bail()); |
| return suite; |
| }; |
| |
| /** |
| * Set timeout `ms` or short-hand such as "2s". |
| * |
| * @param {Number|String} ms |
| * @return {Suite|Number} for chaining |
| * @api private |
| */ |
| |
| Suite.prototype.timeout = function(ms){ |
| if (0 == arguments.length) return this._timeout; |
| if ('string' == typeof ms) ms = milliseconds(ms); |
| debug('timeout %d', ms); |
| this._timeout = parseInt(ms, 10); |
| return this; |
| }; |
| |
| /** |
| * Set timeout `enabled`. |
| * |
| * @param {Boolean} enabled |
| * @return {Suite|Boolean} self or enabled |
| * @api private |
| */ |
| |
| Suite.prototype.enableTimeouts = function(enabled){ |
| if (arguments.length === 0) return this._enableTimeouts; |
| debug('enableTimeouts %s', enabled); |
| this._enableTimeouts = enabled; |
| return this; |
| } |
| |
| /** |
| * Set slow `ms` or short-hand such as "2s". |
| * |
| * @param {Number|String} ms |
| * @return {Suite|Number} for chaining |
| * @api private |
| */ |
| |
| Suite.prototype.slow = function(ms){ |
| if (0 === arguments.length) return this._slow; |
| if ('string' == typeof ms) ms = milliseconds(ms); |
| debug('slow %d', ms); |
| this._slow = ms; |
| return this; |
| }; |
| |
| /** |
| * Sets whether to bail after first error. |
| * |
| * @parma {Boolean} bail |
| * @return {Suite|Number} for chaining |
| * @api private |
| */ |
| |
| Suite.prototype.bail = function(bail){ |
| if (0 == arguments.length) return this._bail; |
| debug('bail %s', bail); |
| this._bail = bail; |
| return this; |
| }; |
| |
| /** |
| * Run `fn(test[, done])` before running tests. |
| * |
| * @param {Function} fn |
| * @return {Suite} for chaining |
| * @api private |
| */ |
| |
| Suite.prototype.beforeAll = function(title, fn){ |
| if (this.pending) return this; |
| if ('function' === typeof title) { |
| fn = title; |
| title = fn.name; |
| } |
| title = '"before all" hook' + (title ? ': ' + title : ''); |
| |
| var hook = new Hook(title, fn); |
| hook.parent = this; |
| hook.timeout(this.timeout()); |
| hook.enableTimeouts(this.enableTimeouts()); |
| hook.slow(this.slow()); |
| hook.ctx = this.ctx; |
| this._beforeAll.push(hook); |
| this.emit('beforeAll', hook); |
| return this; |
| }; |
| |
| /** |
| * Run `fn(test[, done])` after running tests. |
| * |
| * @param {Function} fn |
| * @return {Suite} for chaining |
| * @api private |
| */ |
| |
| Suite.prototype.afterAll = function(title, fn){ |
| if (this.pending) return this; |
| if ('function' === typeof title) { |
| fn = title; |
| title = fn.name; |
| } |
| title = '"after all" hook' + (title ? ': ' + title : ''); |
| |
| var hook = new Hook(title, fn); |
| hook.parent = this; |
| hook.timeout(this.timeout()); |
| hook.enableTimeouts(this.enableTimeouts()); |
| hook.slow(this.slow()); |
| hook.ctx = this.ctx; |
| this._afterAll.push(hook); |
| this.emit('afterAll', hook); |
| return this; |
| }; |
| |
| /** |
| * Run `fn(test[, done])` before each test case. |
| * |
| * @param {Function} fn |
| * @return {Suite} for chaining |
| * @api private |
| */ |
| |
| Suite.prototype.beforeEach = function(title, fn){ |
| if (this.pending) return this; |
| if ('function' === typeof title) { |
| fn = title; |
| title = fn.name; |
| } |
| title = '"before each" hook' + (title ? ': ' + title : ''); |
| |
| var hook = new Hook(title, fn); |
| hook.parent = this; |
| hook.timeout(this.timeout()); |
| hook.enableTimeouts(this.enableTimeouts()); |
| hook.slow(this.slow()); |
| hook.ctx = this.ctx; |
| this._beforeEach.push(hook); |
| this.emit('beforeEach', hook); |
| return this; |
| }; |
| |
| /** |
| * Run `fn(test[, done])` after each test case. |
| * |
| * @param {Function} fn |
| * @return {Suite} for chaining |
| * @api private |
| */ |
| |
| Suite.prototype.afterEach = function(title, fn){ |
| if (this.pending) return this; |
| if ('function' === typeof title) { |
| fn = title; |
| title = fn.name; |
| } |
| title = '"after each" hook' + (title ? ': ' + title : ''); |
| |
| var hook = new Hook(title, fn); |
| hook.parent = this; |
| hook.timeout(this.timeout()); |
| hook.enableTimeouts(this.enableTimeouts()); |
| hook.slow(this.slow()); |
| hook.ctx = this.ctx; |
| this._afterEach.push(hook); |
| this.emit('afterEach', hook); |
| return this; |
| }; |
| |
| /** |
| * Add a test `suite`. |
| * |
| * @param {Suite} suite |
| * @return {Suite} for chaining |
| * @api private |
| */ |
| |
| Suite.prototype.addSuite = function(suite){ |
| suite.parent = this; |
| suite.timeout(this.timeout()); |
| suite.enableTimeouts(this.enableTimeouts()); |
| suite.slow(this.slow()); |
| suite.bail(this.bail()); |
| this.suites.push(suite); |
| this.emit('suite', suite); |
| return this; |
| }; |
| |
| /** |
| * Add a `test` to this suite. |
| * |
| * @param {Test} test |
| * @return {Suite} for chaining |
| * @api private |
| */ |
| |
| Suite.prototype.addTest = function(test){ |
| test.parent = this; |
| test.timeout(this.timeout()); |
| test.enableTimeouts(this.enableTimeouts()); |
| test.slow(this.slow()); |
| test.ctx = this.ctx; |
| this.tests.push(test); |
| this.emit('test', test); |
| return this; |
| }; |
| |
| /** |
| * Return the full title generated by recursively |
| * concatenating the parent's full title. |
| * |
| * @return {String} |
| * @api public |
| */ |
| |
| Suite.prototype.fullTitle = function(){ |
| if (this.parent) { |
| var full = this.parent.fullTitle(); |
| if (full) return full + ' ' + this.title; |
| } |
| return this.title; |
| }; |
| |
| /** |
| * Return the total number of tests. |
| * |
| * @return {Number} |
| * @api public |
| */ |
| |
| Suite.prototype.total = function(){ |
| return this.suites.reduce(function(sum, suite){ |
| return sum + suite.total(); |
| }, 0) + this.tests.length; |
| }; |
| |
| /** |
| * Iterates through each suite recursively to find |
| * all tests. Applies a function in the format |
| * `fn(test)`. |
| * |
| * @param {Function} fn |
| * @return {Suite} |
| * @api private |
| */ |
| |
| Suite.prototype.eachTest = function(fn){ |
| this.tests.forEach(fn); |
| this.suites.forEach(function(suite){ |
| suite.eachTest(fn); |
| }); |
| return this; |
| }; |
| |
| }); // module: suite.js |
| |
| require.register("test.js", function(module, exports, require){ |
| |
| /** |
| * Module dependencies. |
| */ |
| |
| var Runnable = require('./runnable'); |
| |
| /** |
| * Expose `Test`. |
| */ |
| |
| module.exports = Test; |
| |
| /** |
| * Initialize a new `Test` with the given `title` and callback `fn`. |
| * |
| * @param {String} title |
| * @param {Function} fn |
| * @api private |
| */ |
| |
| function Test(title, fn) { |
| Runnable.call(this, title, fn); |
| this.pending = !fn; |
| this.type = 'test'; |
| } |
| |
| /** |
| * Inherit from `Runnable.prototype`. |
| */ |
| |
| function F(){}; |
| F.prototype = Runnable.prototype; |
| Test.prototype = new F; |
| Test.prototype.constructor = Test; |
| |
| |
| }); // module: test.js |
| |
| require.register("utils.js", function(module, exports, require){ |
| /** |
| * Module dependencies. |
| */ |
| |
| /** |
| * Escape regular expression characters in `str`. |
| * |
| * @param {String} str |
| * @return {String} |
| * @api private |
| */ |
| |
| exports.escapeRegexp = function(str){ |
| return str.replace(/[-\\^$*+?.()|[\]{}]/g, "\\$&"); |
| }; |
| |
| |
| }); // module: utils.js |
| |
| /** |
| * Save timer references to avoid Sinon interfering (see GH-237). |
| */ |
| |
| /** |
| * Node shims. |
| * |
| * These are meant only to allow |
| * mocha.js to run untouched, not |
| * to allow running node code in |
| * the browser. |
| */ |
| |
| var process = {}; |
| process.exit = function(status){}; |
| process.stdout = {}; |
| |
| var uncaughtExceptionHandlers = []; |
| |
| var originalOnerrorHandler = window.onerror; |
| |
| /** |
| * Remove uncaughtException listener. |
| * Revert to original onerror handler if previously defined. |
| */ |
| |
| process.removeListener = function(e, fn){ |
| if ('uncaughtException' == e) { |
| if (originalOnerrorHandler) { |
| window.onerror = originalOnerrorHandler; |
| } else { |
| window.onerror = function() {}; |
| } |
| var i = uncaughtExceptionHandlers.indexOf(fn); |
| if (i != -1) { uncaughtExceptionHandlers.splice(i, 1); } |
| } |
| }; |
| |
| /** |
| * Implements uncaughtException listener. |
| */ |
| |
| process.on = function(e, fn){ |
| if ('uncaughtException' == e) { |
| window.onerror = function(err, url, line){ |
| fn(new Error(err + ' (' + url + ':' + line + ')')); |
| return true; |
| }; |
| uncaughtExceptionHandlers.push(fn); |
| } |
| }; |
| |
| /** |
| * Expose mocha. |
| */ |
| |
| var Mocha = window.Mocha = require('mocha'), |
| mocha = window.mocha = new Mocha(); |
| |
| // The BDD UI is registered by default, but no UI will be functional in the |
| // browser without an explicit call to the overridden `mocha.ui` (see below). |
| // Ensure that this default UI does not expose its methods to the global scope. |
| mocha.suite.removeAllListeners('pre-require'); |
| |
| var immediateQueue = [] |
| , immediateTimeout; |
| |
| function timeslice() { |
| var immediateStart = new Date().getTime(); |
| while (immediateQueue.length && (new Date().getTime() - immediateStart) < 100) { |
| immediateQueue.shift()(); |
| } |
| if (immediateQueue.length) { |
| immediateTimeout = setTimeout(timeslice, 0); |
| } else { |
| immediateTimeout = null; |
| } |
| } |
| |
| /** |
| * High-performance override of Runner.immediately. |
| */ |
| |
| Mocha.Runner.immediately = function(callback) { |
| immediateQueue.push(callback); |
| if (!immediateTimeout) { |
| immediateTimeout = setTimeout(timeslice, 0); |
| } |
| }; |
| |
| /** |
| * Function to allow assertion libraries to throw errors directly into mocha. |
| * This is useful when running tests in a browser because window.onerror will |
| * only receive the 'message' attribute of the Error. |
| */ |
| mocha.throwError = function(err) { |
| uncaughtExceptionHandlers.forEach(function (fn) { |
| fn(err); |
| }); |
| throw err; |
| }; |
| |
| /** |
| * Override ui to ensure that the ui functions are initialized. |
| * Normally this would happen in Mocha.prototype.loadFiles. |
| */ |
| |
| mocha.ui = function(ui){ |
| Mocha.prototype.ui.call(this, ui); |
| this.suite.emit('pre-require', window, null, this); |
| return this; |
| }; |
| |
| /** |
| * Setup mocha with the given setting options. |
| */ |
| |
| mocha.setup = function(opts){ |
| this.ui(); |
| }; |
| |
| /** |
| * Run mocha, returning the Runner. |
| */ |
| |
| mocha.run = function(fn){ |
| return Mocha.prototype.run.call(mocha, function(err){ |
| if (fn) fn(err); |
| }); |
| }; |
| |
| /** |
| * Expose the process shim. |
| */ |
| |
| Mocha.process = process; |
| })(); |
| |
| </script> |
| <script> |
| |
| mocha.setup(); |
| |
| window.addEventListener('load', function() { |
| requestAnimationFrame(function() { |
| mocha.run(); |
| }); |
| }) |
| |
| </script> |