UNPKG

direct-dev

Version:
2,304 lines (2,008 loc) 423 kB
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ (function (process,global){ 'use strict'; /* eslint no-unused-vars: off */ /* eslint-env commonjs */ /** * Shim process.stdout. */ process.stdout = require('browser-stdout')(); var Mocha = require('./lib/mocha'); /** * Create a Mocha instance. * * @return {undefined} */ var mocha = new Mocha({ reporter: 'html' }); /** * Save timer references to avoid Sinon interfering (see GH-237). */ var Date = global.Date; var setTimeout = global.setTimeout; var setInterval = global.setInterval; var clearTimeout = global.clearTimeout; var clearInterval = global.clearInterval; var uncaughtExceptionHandlers = []; var originalOnerrorHandler = global.onerror; /** * Remove uncaughtException listener. * Revert to original onerror handler if previously defined. */ process.removeListener = function (e, fn) { if (e === 'uncaughtException') { if (originalOnerrorHandler) { global.onerror = originalOnerrorHandler; } else { global.onerror = function () {}; } var i = Mocha.utils.indexOf(uncaughtExceptionHandlers, fn); if (i !== -1) { uncaughtExceptionHandlers.splice(i, 1); } } }; /** * Implements uncaughtException listener. */ process.on = function (e, fn) { if (e === 'uncaughtException') { global.onerror = function (err, url, line) { fn(new Error(err + ' (' + url + ':' + line + ')')); return !mocha.allowUncaught; }; uncaughtExceptionHandlers.push(fn); } }; // 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 = []; var 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) { Mocha.utils.forEach(uncaughtExceptionHandlers, 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', global, null, this); return this; }; /** * Setup mocha with the given setting options. */ mocha.setup = function (opts) { if (typeof opts === 'string') { opts = { ui: opts }; } for (var opt in opts) { if (opts.hasOwnProperty(opt)) { this[opt](opts[opt]); } } return this; }; /** * Run mocha, returning the Runner. */ mocha.run = function (fn) { var options = mocha.options; mocha.globals('location'); var query = Mocha.utils.parseQuery(global.location.search || ''); if (query.grep) { mocha.grep(query.grep); } if (query.fgrep) { mocha.fgrep(query.fgrep); } if (query.invert) { mocha.invert(); } return Mocha.prototype.run.call(mocha, function (err) { // The DOM Document is not available in Web Workers. var document = global.document; if (document && document.getElementById('mocha') && options.noHighlighting !== true) { Mocha.utils.highlightTags('code'); } if (fn) { fn(err); } }); }; /** * Expose the process shim. * https://github.com/mochajs/mocha/pull/916 */ Mocha.process = process; /** * Expose mocha. */ global.Mocha = Mocha; global.mocha = mocha; // this allows test/acceptance/required-tokens.js to pass; thus, // you can now do `const describe = require('mocha').describe` in a // browser context (assuming browserification). should fix #880 module.exports = global; }).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{"./lib/mocha":14,"_process":67,"browser-stdout":41}],2:[function(require,module,exports){ 'use strict'; function noop () {} module.exports = function () { return noop; }; },{}],3:[function(require,module,exports){ 'use strict'; /** * Module exports. */ exports.EventEmitter = EventEmitter; /** * Object#toString reference. */ var objToString = Object.prototype.toString; /** * Check if a value is an array. * * @api private * @param {*} val The value to test. * @return {boolean} true if the value is an array, otherwise false. */ function isArray (val) { return objToString.call(val) === '[object Array]'; } /** * Event emitter constructor. * * @api public */ function EventEmitter () {} /** * Add a listener. * * @api public * @param {string} name Event name. * @param {Function} fn Event handler. * @return {EventEmitter} Emitter instance. */ 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 * @param {string} name Event name. * @param {Function} fn Event handler. * @return {EventEmitter} Emitter instance. */ 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; }; /** * Remove a listener. * * @api public * @param {string} name Event name. * @param {Function} fn Event handler. * @return {EventEmitter} Emitter instance. */ 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; }; /** * Remove all listeners for an event. * * @api public * @param {string} name Event name. * @return {EventEmitter} Emitter instance. */ EventEmitter.prototype.removeAllListeners = function (name) { if (name === undefined) { this.$events = {}; return this; } if (this.$events && this.$events[name]) { this.$events[name] = null; } return this; }; /** * Get all listeners for a given event. * * @api public * @param {string} name Event name. * @return {EventEmitter} Emitter instance. */ 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]; }; /** * Emit an event. * * @api public * @param {string} name Event name. * @return {boolean} true if at least one handler was invoked, else false. */ EventEmitter.prototype.emit = function (name) { if (!this.$events) { return false; } var handler = this.$events[name]; if (!handler) { return false; } var args = Array.prototype.slice.call(arguments, 1); if (typeof handler === 'function') { 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; }; },{}],4:[function(require,module,exports){ 'use strict'; /** * Expose `Progress`. */ module.exports = Progress; /** * Initialize a new `Progress` indicator. */ function Progress () { this.percent = 0; this.size(0); this.fontSize(11); this.font('helvetica, arial, sans-serif'); } /** * Set progress size to `size`. * * @api public * @param {number} size * @return {Progress} Progress instance. */ Progress.prototype.size = function (size) { this._size = size; return this; }; /** * Set text to `text`. * * @api public * @param {string} text * @return {Progress} Progress instance. */ Progress.prototype.text = function (text) { this._text = text; return this; }; /** * Set font size to `size`. * * @api public * @param {number} size * @return {Progress} Progress instance. */ Progress.prototype.fontSize = function (size) { this._fontSize = size; return this; }; /** * Set font to `family`. * * @param {string} family * @return {Progress} Progress instance. */ Progress.prototype.font = function (family) { this._font = family; return this; }; /** * Update percentage to `n`. * * @param {number} n * @return {Progress} Progress instance. */ Progress.prototype.update = function (n) { this.percent = n; return this; }; /** * Draw on `ctx`. * * @param {CanvasRenderingContext2d} ctx * @return {Progress} Progress instance. */ Progress.prototype.draw = function (ctx) { try { var percent = Math.min(this.percent, 100); var size = this._size; var half = size / 2; var x = half; var y = half; var rad = half - 1; var fontSize = this._fontSize; ctx.font = fontSize + 'px ' + this._font; var angle = Math.PI * 2 * (percent / 100); ctx.clearRect(0, 0, size, size); // outer circle ctx.strokeStyle = '#9f9f9f'; ctx.beginPath(); ctx.arc(x, y, rad, 0, angle, false); ctx.stroke(); // inner circle ctx.strokeStyle = '#eee'; ctx.beginPath(); ctx.arc(x, y, rad - 1, 0, angle, true); ctx.stroke(); // text var text = this._text || (percent | 0) + '%'; var w = ctx.measureText(text).width; ctx.fillText(text, x - w / 2 + 1, y + fontSize / 2 - 1); } catch (err) { // don't fail if we can't render progress } return this; }; },{}],5:[function(require,module,exports){ (function (global){ 'use strict'; exports.isatty = function isatty () { return true; }; exports.getWindowSize = function getWindowSize () { if ('innerHeight' in global) { return [global.innerHeight, global.innerWidth]; } // In a Web Worker, the DOM Window is not available. return [640, 480]; }; }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{}],6:[function(require,module,exports){ 'use strict'; /** * Module dependencies. */ var JSON = require('json3'); /** * Expose `Context`. */ module.exports = Context; /** * Initialize a new `Context`. * * @api private */ function Context () {} /** * Set or get the context `Runnable` to `runnable`. * * @api private * @param {Runnable} runnable * @return {Context} */ Context.prototype.runnable = function (runnable) { if (!arguments.length) { return this._runnable; } this.test = this._runnable = runnable; return this; }; /** * Set test timeout `ms`. * * @api private * @param {number} ms * @return {Context} self */ Context.prototype.timeout = function (ms) { if (!arguments.length) { return this.runnable().timeout(); } this.runnable().timeout(ms); return this; }; /** * Set test timeout `enabled`. * * @api private * @param {boolean} enabled * @return {Context} self */ Context.prototype.enableTimeouts = function (enabled) { this.runnable().enableTimeouts(enabled); return this; }; /** * Set test slowness threshold `ms`. * * @api private * @param {number} ms * @return {Context} self */ Context.prototype.slow = function (ms) { this.runnable().slow(ms); return this; }; /** * Mark a test as skipped. * * @api private * @return {Context} self */ Context.prototype.skip = function () { this.runnable().skip(); return this; }; /** * Allow a number of retries on failed tests * * @api private * @param {number} n * @return {Context} self */ Context.prototype.retries = function (n) { if (!arguments.length) { return this.runnable().retries(); } this.runnable().retries(n); return this; }; /** * Inspect the context void of `._runnable`. * * @api private * @return {string} */ Context.prototype.inspect = function () { return JSON.stringify(this, function (key, val) { return key === 'runnable' || key === 'test' ? undefined : val; }, 2); }; },{"json3":54}],7:[function(require,module,exports){ 'use strict'; /** * Module dependencies. */ var Runnable = require('./runnable'); var inherits = require('./utils').inherits; /** * 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`. */ inherits(Hook, Runnable); /** * Get or set the test `err`. * * @param {Error} err * @return {Error} * @api public */ Hook.prototype.error = function (err) { if (!arguments.length) { err = this._error; this._error = null; return err; } this._error = err; }; },{"./runnable":33,"./utils":38}],8:[function(require,module,exports){ 'use strict'; /** * Module dependencies. */ var Test = require('../test'); /** * 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() { * // ... * }); * }); * }); * * @param {Suite} suite Root suite. */ module.exports = function (suite) { var suites = [suite]; suite.on('pre-require', function (context, file, mocha) { var common = require('./common')(suites, context, mocha); context.before = common.before; context.after = common.after; context.beforeEach = common.beforeEach; context.afterEach = common.afterEach; context.run = mocha.options.delay && common.runWithSuite(suite); /** * Describe a "suite" with the given `title` * and callback `fn` containing nested suites * and/or tests. */ context.describe = context.context = function (title, fn) { return common.suite.create({ title: title, file: file, fn: fn }); }; /** * Pending describe. */ context.xdescribe = context.xcontext = context.describe.skip = function (title, fn) { return common.suite.skip({ title: title, file: file, fn: fn }); }; /** * Exclusive suite. */ context.describe.only = function (title, fn) { return common.suite.only({ title: title, file: file, fn: fn }); }; /** * Describe a specification or test-case * with the given `title` and callback `fn` * acting as a thunk. */ context.it = context.specify = function (title, fn) { var suite = suites[0]; if (suite.isPending()) { fn = null; } var test = new Test(title, fn); test.file = file; suite.addTest(test); return test; }; /** * Exclusive test-case. */ context.it.only = function (title, fn) { return common.test.only(mocha, context.it(title, fn)); }; /** * Pending test case. */ context.xit = context.xspecify = context.it.skip = function (title) { context.it(title); }; /** * Number of attempts to retry. */ context.it.retries = function (n) { context.retries(n); }; }); }; },{"../test":36,"./common":9}],9:[function(require,module,exports){ 'use strict'; var Suite = require('../suite'); /** * Functions common to more than one interface. * * @param {Suite[]} suites * @param {Context} context * @param {Mocha} mocha * @return {Object} An object containing common functions. */ module.exports = function (suites, context, mocha) { return { /** * This is only present if flag --delay is passed into Mocha. It triggers * root suite execution. * * @param {Suite} suite The root suite. * @return {Function} A function which runs the root suite */ runWithSuite: function runWithSuite (suite) { return function run () { suite.run(); }; }, /** * Execute before running tests. * * @param {string} name * @param {Function} fn */ before: function (name, fn) { suites[0].beforeAll(name, fn); }, /** * Execute after running tests. * * @param {string} name * @param {Function} fn */ after: function (name, fn) { suites[0].afterAll(name, fn); }, /** * Execute before each test case. * * @param {string} name * @param {Function} fn */ beforeEach: function (name, fn) { suites[0].beforeEach(name, fn); }, /** * Execute after each test case. * * @param {string} name * @param {Function} fn */ afterEach: function (name, fn) { suites[0].afterEach(name, fn); }, suite: { /** * Create an exclusive Suite; convenience function * See docstring for create() below. * * @param {Object} opts * @returns {Suite} */ only: function only (opts) { mocha.options.hasOnly = true; opts.isOnly = true; return this.create(opts); }, /** * Create a Suite, but skip it; convenience function * See docstring for create() below. * * @param {Object} opts * @returns {Suite} */ skip: function skip (opts) { opts.pending = true; return this.create(opts); }, /** * Creates a suite. * @param {Object} opts Options * @param {string} opts.title Title of Suite * @param {Function} [opts.fn] Suite Function (not always applicable) * @param {boolean} [opts.pending] Is Suite pending? * @param {string} [opts.file] Filepath where this Suite resides * @param {boolean} [opts.isOnly] Is Suite exclusive? * @returns {Suite} */ create: function create (opts) { var suite = Suite.create(suites[0], opts.title); suite.pending = Boolean(opts.pending); suite.file = opts.file; suites.unshift(suite); if (opts.isOnly) { suite.parent._onlySuites = suite.parent._onlySuites.concat(suite); mocha.options.hasOnly = true; } if (typeof opts.fn === 'function') { opts.fn.call(suite); suites.shift(); } else if (typeof opts.fn === 'undefined' && !suite.pending) { throw new Error('Suite "' + suite.fullTitle() + '" was defined but no callback was supplied. Supply a callback or explicitly skip the suite.'); } return suite; } }, test: { /** * Exclusive test-case. * * @param {Object} mocha * @param {Function} test * @returns {*} */ only: function (mocha, test) { test.parent._onlyTests = test.parent._onlyTests.concat(test); mocha.options.hasOnly = true; return test; }, /** * Pending test case. * * @param {string} title */ skip: function (title) { context.test(title); }, /** * Number of retry attempts * * @param {number} n */ retries: function (n) { context.retries(n); } } }; }; },{"../suite":35}],10:[function(require,module,exports){ 'use strict'; /** * Module dependencies. */ var Suite = require('../suite'); var Test = require('../test'); /** * Exports-style (as Node.js module) 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() { * * } * } * }; * * @param {Suite} suite Root suite. */ module.exports = function (suite) { var suites = [suite]; suite.on('require', visit); function visit (obj, file) { var suite; for (var key in obj) { if (typeof obj[key] === 'function') { 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 { suite = Suite.create(suites[0], key); suites.unshift(suite); visit(obj[key], file); suites.shift(); } } } }; },{"../suite":35,"../test":36}],11:[function(require,module,exports){ 'use strict'; exports.bdd = require('./bdd'); exports.tdd = require('./tdd'); exports.qunit = require('./qunit'); exports.exports = require('./exports'); },{"./bdd":8,"./exports":10,"./qunit":12,"./tdd":13}],12:[function(require,module,exports){ 'use strict'; /** * Module dependencies. */ var Test = require('../test'); /** * QUnit-style interface: * * suite('Array'); * * test('#length', function() { * var arr = [1,2,3]; * ok(arr.length == 3); * }); * * test('#indexOf()', function() { * var arr = [1,2,3]; * ok(arr.indexOf(1) == 0); * ok(arr.indexOf(2) == 1); * ok(arr.indexOf(3) == 2); * }); * * suite('String'); * * test('#length', function() { * ok('foo'.length == 3); * }); * * @param {Suite} suite Root suite. */ module.exports = function (suite) { var suites = [suite]; suite.on('pre-require', function (context, file, mocha) { var common = require('./common')(suites, context, mocha); context.before = common.before; context.after = common.after; context.beforeEach = common.beforeEach; context.afterEach = common.afterEach; context.run = mocha.options.delay && common.runWithSuite(suite); /** * Describe a "suite" with the given `title`. */ context.suite = function (title) { if (suites.length > 1) { suites.shift(); } return common.suite.create({ title: title, file: file, fn: false }); }; /** * Exclusive Suite. */ context.suite.only = function (title) { if (suites.length > 1) { suites.shift(); } return common.suite.only({ title: title, file: file, fn: false }); }; /** * Describe a specification or test-case * with the given `title` and callback `fn` * acting as a thunk. */ context.test = function (title, fn) { var test = new Test(title, fn); test.file = file; suites[0].addTest(test); return test; }; /** * Exclusive test-case. */ context.test.only = function (title, fn) { return common.test.only(mocha, context.test(title, fn)); }; context.test.skip = common.test.skip; context.test.retries = common.test.retries; }); }; },{"../test":36,"./common":9}],13:[function(require,module,exports){ 'use strict'; /** * Module dependencies. */ var Test = require('../test'); /** * TDD-style interface: * * suite('Array', function() { * suite('#indexOf()', function() { * suiteSetup(function() { * * }); * * test('should return -1 when not present', function() { * * }); * * test('should return the index when present', function() { * * }); * * suiteTeardown(function() { * * }); * }); * }); * * @param {Suite} suite Root suite. */ module.exports = function (suite) { var suites = [suite]; suite.on('pre-require', function (context, file, mocha) { var common = require('./common')(suites, context, mocha); context.setup = common.beforeEach; context.teardown = common.afterEach; context.suiteSetup = common.before; context.suiteTeardown = common.after; context.run = mocha.options.delay && common.runWithSuite(suite); /** * Describe a "suite" with the given `title` and callback `fn` containing * nested suites and/or tests. */ context.suite = function (title, fn) { return common.suite.create({ title: title, file: file, fn: fn }); }; /** * Pending suite. */ context.suite.skip = function (title, fn) { return common.suite.skip({ title: title, file: file, fn: fn }); }; /** * Exclusive test-case. */ context.suite.only = function (title, fn) { return common.suite.only({ title: title, file: file, fn: fn }); }; /** * Describe a specification or test-case with the given `title` and * callback `fn` acting as a thunk. */ context.test = function (title, fn) { var suite = suites[0]; if (suite.isPending()) { fn = null; } var test = new Test(title, fn); test.file = file; suite.addTest(test); return test; }; /** * Exclusive test-case. */ context.test.only = function (title, fn) { return common.test.only(mocha, context.test(title, fn)); }; context.test.skip = common.test.skip; context.test.retries = common.test.retries; }); }; },{"../test":36,"./common":9}],14:[function(require,module,exports){ (function (process,global,__dirname){ 'use strict'; /*! * mocha * Copyright(c) 2011 TJ Holowaychuk <tj@vision-media.ca> * MIT Licensed */ /** * Module dependencies. */ var escapeRe = require('escape-string-regexp'); var path = require('path'); var reporters = require('./reporters'); var utils = require('./utils'); /** * Expose `Mocha`. */ exports = module.exports = Mocha; /** * To require local UIs and reporters when running in node. */ if (!process.browser) { var cwd = process.cwd(); module.paths.push(cwd, path.join(cwd, 'node_modules')); } /** * Expose internals. */ exports.utils = utils; exports.interfaces = require('./interfaces'); exports.reporters = 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'); /** * Return image `name` path. * * @api private * @param {string} name * @return {string} */ function image (name) { return path.join(__dirname, '../images', name + '.png'); } /** * Set up mocha with `options`. * * Options: * * - `ui` name "bdd", "tdd", "exports" etc * - `reporter` reporter instance, defaults to `mocha.reporters.spec` * - `globals` array of accepted globals * - `timeout` timeout in milliseconds * - `retries` number of times to retry failed tests * - `bail` bail on the first test failure * - `slow` milliseconds to wait before considering a test slow * - `ignoreLeaks` ignore global leaks * - `fullTrace` display the full stack-trace on failing * - `grep` string or regexp to filter tests with * * @param {Object} options * @api public */ function Mocha (options) { options = options || {}; this.files = []; this.options = options; if (options.grep) { this.grep(new RegExp(options.grep)); } if (options.fgrep) { this.fgrep(options.fgrep); } this.suite = new exports.Suite('', new exports.Context()); this.ui(options.ui); this.bail(options.bail); this.reporter(options.reporter, options.reporterOptions); if (typeof options.timeout !== 'undefined' && options.timeout !== null) { this.timeout(options.timeout); } if (typeof options.retries !== 'undefined' && options.retries !== null) { this.retries(options.retries); } this.useColors(options.useColors); if (options.enableTimeouts !== null) { this.enableTimeouts(options.enableTimeouts); } if (options.slow) { this.slow(options.slow); } } /** * Enable or disable bailing on the first failure. * * @api public * @param {boolean} [bail] */ Mocha.prototype.bail = function (bail) { if (!arguments.length) { bail = true; } this.suite.bail(bail); return this; }; /** * Add test `file`. * * @api public * @param {string} file */ Mocha.prototype.addFile = function (file) { this.files.push(file); return this; }; /** * Set reporter to `reporter`, defaults to "spec". * * @param {String|Function} reporter name or constructor * @param {Object} reporterOptions optional options * @api public * @param {string|Function} reporter name or constructor * @param {Object} reporterOptions optional options */ Mocha.prototype.reporter = function (reporter, reporterOptions) { if (typeof reporter === 'function') { this._reporter = reporter; } else { reporter = reporter || 'spec'; var _reporter; // Try to load a built-in reporter. if (reporters[reporter]) { _reporter = reporters[reporter]; } // Try to load reporters from process.cwd() and node_modules if (!_reporter) { try { _reporter = require(reporter); } catch (err) { err.message.indexOf('Cannot find module') !== -1 ? console.warn('"' + reporter + '" reporter not found') : console.warn('"' + reporter + '" reporter blew up with error:\n' + err.stack); } } if (!_reporter && reporter === 'teamcity') { console.warn('The Teamcity reporter was moved to a package named ' + 'mocha-teamcity-reporter ' + '(https://npmjs.org/package/mocha-teamcity-reporter).'); } if (!_reporter) { throw new Error('invalid reporter "' + reporter + '"'); } this._reporter = _reporter; } this.options.reporterOptions = reporterOptions; return this; }; /** * Set test UI `name`, defaults to "bdd". * * @api public * @param {string} bdd */ Mocha.prototype.ui = function (name) { name = name || 'bdd'; this._ui = exports.interfaces[name]; if (!this._ui) { try { this._ui = require(name); } catch (err) { throw new Error('invalid interface "' + name + '"'); } } this._ui = this._ui(this.suite); this.suite.on('pre-require', function (context) { exports.afterEach = context.afterEach || context.teardown; exports.after = context.after || context.suiteTeardown; exports.beforeEach = context.beforeEach || context.setup; exports.before = context.before || context.suiteSetup; exports.describe = context.describe || context.suite; exports.it = context.it || context.test; exports.setup = context.setup || context.beforeEach; exports.suiteSetup = context.suiteSetup || context.before; exports.suiteTeardown = context.suiteTeardown || context.after; exports.suite = context.suite || context.describe; exports.teardown = context.teardown || context.afterEach; exports.test = context.test || context.it; exports.run = context.run; }); return this; }; /** * Load registered files. * * @api private */ Mocha.prototype.loadFiles = function (fn) { var self = this; var suite = this.suite; this.files.forEach(function (file) { file = path.resolve(file); suite.emit('pre-require', global, file, self); suite.emit('require', require(file), file, self); suite.emit('post-require', global, file, self); }); fn && fn(); }; /** * Enable growl support. * * @api private */ Mocha.prototype._growl = function (runner, reporter) { var notify = require('growl'); runner.on('end', function () { var stats = reporter.stats; if (stats.failures) { var msg = stats.failures + ' of ' + runner.total + ' tests failed'; notify(msg, { name: 'mocha', title: 'Failed', image: image('error') }); } else { notify(stats.passes + ' tests passed in ' + stats.duration + 'ms', { name: 'mocha', title: 'Passed', image: image('ok') }); } }); }; /** * Escape string and add it to grep as a regexp. * * @api public * @param str * @returns {Mocha} */ Mocha.prototype.fgrep = function (str) { return this.grep(new RegExp(escapeRe(str))); }; /** * Add regexp to grep, if `re` is a string it is escaped. * * @param {RegExp|String} re * @return {Mocha} * @api public * @param {RegExp|string} re * @return {Mocha} */ Mocha.prototype.grep = function (re) { if (utils.isString(re)) { // extract args if it's regex-like, i.e: [string, pattern, flag] var arg = re.match(/^\/(.*)\/(g|i|)$|.*/); this.options.grep = new RegExp(arg[1] || arg[0], arg[2]); } else { this.options.grep = re; } return this; }; /** * Invert `.grep()` matches. * * @return {Mocha} * @api public */ Mocha.prototype.invert = function () { this.options.invert = true; return this; }; /** * Ignore global leaks. * * @param {Boolean} ignore * @return {Mocha} * @api public * @param {boolean} ignore * @return {Mocha} */ Mocha.prototype.ignoreLeaks = function (ignore) { this.options.ignoreLeaks = Boolean(ignore); return this; }; /** * Enable global leak checking. * * @return {Mocha} * @api public */ Mocha.prototype.checkLeaks = function () { this.options.ignoreLeaks = false; return this; }; /** * Display long stack-trace on failing * * @return {Mocha} * @api public */ Mocha.prototype.fullTrace = function () { this.options.fullStackTrace = true; return this; }; /** * Enable growl support. * * @return {Mocha} * @api public */ Mocha.prototype.growl = function () { this.options.growl = true; return this; }; /** * Ignore `globals` array or string. * * @param {Array|String} globals * @return {Mocha} * @api public * @param {Array|string} globals * @return {Mocha} */ Mocha.prototype.globals = function (globals) { this.options.globals = (this.options.globals || []).concat(globals); return this; }; /** * Emit color output. * * @param {Boolean} colors * @return {Mocha} * @api public * @param {boolean} colors * @return {Mocha} */ Mocha.prototype.useColors = function (colors) { if (colors !== undefined) { this.options.useColors = colors; } return this; }; /** * Use inline diffs rather than +/-. * * @param {Boolean} inlineDiffs * @return {Mocha} * @api public * @param {boolean} inlineDiffs * @return {Mocha} */ Mocha.prototype.useInlineDiffs = function (inlineDiffs) { this.options.useInlineDiffs = inlineDiffs !== undefined && inlineDiffs; return this; }; /** * Set the timeout in milliseconds. * * @param {Number} timeout * @return {Mocha} * @api public * @param {number} timeout * @return {Mocha} */ Mocha.prototype.timeout = function (timeout) { this.suite.timeout(timeout); return this; }; /** * Set the number of times to retry failed tests. * * @param {Number} retry times * @return {Mocha} * @api public */ Mocha.prototype.retries = function (n) { this.suite.retries(n); return this; }; /** * Set slowness threshold in milliseconds. * * @param {Number} slow * @return {Mocha} * @api public * @param {number} slow * @return {Mocha} */ Mocha.prototype.slow = function (slow) { this.suite.slow(slow); return this; }; /** * Enable timeouts. * * @param {Boolean} enabled * @return {Mocha} * @api public * @param {boolean} enabled * @return {Mocha} */ 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; }; /** * Disable syntax highlighting (in browser). * * @api public */ Mocha.prototype.noHighlighting = function () { this.options.noHighlighting = true; return this; }; /** * Enable uncaught errors to propagate (in browser). * * @return {Mocha} * @api public */ Mocha.prototype.allowUncaught = function () { this.options.allowUncaught = true; return this; }; /** * Delay root suite execution. * @returns {Mocha} */ Mocha.prototype.delay = function delay () { this.options.delay = true; return this; }; /** * Run tests and invoke `fn()` when complete. * * @api public * @param {Function} fn * @return {Runner} */ Mocha.prototype.run = function (fn) { if (this.files.length) { this.loadFiles(); } var suite = this.suite; var options = this.options; options.files = this.files; var runner = new exports.Runner(suite, options.delay); var reporter = new this._reporter(runner, options); runner.ignoreLeaks = options.ignoreLeaks !== false; runner.fullStackTrace = options.fullStackTrace; runner.hasOnly = options.hasOnly; runner.asyncOnly = options.asyncOnly; runner.allowUncaught = options.allowUncaught; if (options.grep) { runner.grep(options.grep, options.invert); } if (options.globals) { runner.globals(options.globals); } if (options.growl) { this._growl(runner, reporter); } if (options.useColors !== undefined) { exports.reporters.Base.useColors = options.useColors; } exports.reporters.Base.inlineDiffs = options.useInlineDiffs; function done (failures) { if (reporter.done) { reporter.done(failures, fn); } else { fn && fn(failures); } } return runner.run(done); }; }).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},"/lib") },{"./context":6,"./hook":7,"./interfaces":11,"./reporters":21,"./runnable":33,"./runner":34,"./suite":35,"./test":36,"./utils":38,"_process":67,"escape-string-regexp":47,"growl":49,"path":42}],15:[function(require,module,exports){ 'use strict'; /** * 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] * * @api public * @param {string|number} val * @param {Object} options * @return {string|number} */ module.exports = function (val, options) { options = options || {}; if (typeof val === 'string') { return parse(val); } // https://github.com/mochajs/mocha/pull/1035 return options['long'] ? longFormat(val) : shortFormat(val); }; /** * Parse the given `str` and return milliseconds. * * @api private * @param {string} str * @return {number} */ 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; default: // No default case } } /** * Short format for `ms`. * * @api private * @param {number} ms * @return {string} */ 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`. * * @api private * @param {number} ms * @return {string} */ function longFormat (ms) { return plural(ms, d, 'day') || plural(ms, h, 'hour') || plural(ms, m, 'minute') || plural(ms, s, 'second') || ms + ' ms'; } /** * Pluralization helper. * * @api private * @param {number} ms * @param {number} n * @param {string} name */ 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'; } },{}],16:[function(require,module,exports){ 'use strict'; /** * Expose `Pending`. */ module.exports = Pending; /** * Initialize a new `Pending` error with the given message. * * @param {string} message */ function Pending (message) { this.message = message; } },{}],17:[function(require,module,exports){ (function (process,global){ 'use strict'; /** * Module dependencies. */ var tty = require('tty'); var diff = require('diff'); var ms = require('../ms'); var utils = require('../utils'); var supportsColor = process.browser ? null : require('supports-color'); /** * Expose `Base`. */ exports = module.exports = Base; /** * Save timer references to avoid Sinon interfering. * See: https://github.com/mochajs/mocha/issues/237 */ /* eslint-disable no-unused-vars, no-native-reassign */ var Date = global.Date; var setTimeout = global.setTimeout; var setInterval = global.setInterval; var clearTimeout = global.clearTimeout; var clearInterval = global.clearInterval; /* eslint-enable no-unused-vars, no-native-reassign */ /** * Check if both stdio streams are associated with a tty. */ var isatty = tty.isatty(1) && tty.isatty(2); /** * Enable coloring by default, except in the browser interface. */ exports.useColors = !process.browser && (supportsColor || (process.env.MOCHA_COLORS !== undefined)); /** * Inline diffs instead of +/- */ exports.inlineDiffs = false; /** * Default color map. */ exports.colors = { pass: 90, fail: 31, 'bright pass': 92, 'bright fail': 91, 'bright yellow': 93, pending: 36, suite: 0, 'error title': 0, 'error message': 31, 'error stack': 90, checkmark: 32, fast: 90, medium: 33, slow: 31, green: 32, light: 90, 'diff gutter': 90, 'diff added': 32, 'diff removed': 31 }; /** * Default symbol map. */ exports.symbols = { ok: '✓', err: '✖', dot: '․', comma: ',', bang: '!' }; // With node.js on Windows: use symbols available in terminal default fonts if (process.platform === 'win32') { exports.symbols.ok = '\u221A'; exports.symbols.err = '\u00D7'; exports.symbols.dot = '.'; } /** * Color `str` with the given `type`, * allowing colors to be disabled, * as well as user-defined color * schemes. * * @param {string} type * @param {string} str * @return {string} * @api private */ var color = exports.color = function (type, str) { if (!exports.useColors) { return String(str); } return '\u001b[' + exports.colors[type] + 'm' + str + '\u001b[0m'; }; /** * Expose term window size, with some defaults for when stderr is not a tty. */ exports.window = { width: 75 }; if (isatty) { exports.window.width = process.stdout.getWindowSize ? process.stdout.getWindowSize(1)[0] : tty.getWindowSize()[1]; } /** * Expose some basic cursor interactions that are common among reporters. */ exports.cursor = { hide: function () { isatty && process.stdout.write('\u001b[?25l'); }, show: function () { isatty && process.stdout.write('\u001b[?25h'); }, deleteLine: function () { isatty && process.stdout.write('\u001b[2K'); }, beginningOfLine: function () { isatty && process.stdout.write('\u001b[0G'); }, CR: function () { if (isatty) { exports.cursor.deleteLine(); exports.cursor.beginningOfLine(); } else { process.stdout.write('\r'); } } }; /** * Outut the given `failures` as a list. * * @param {Array} failures * @api public */ exports.list = function (failures) { console.log(); failures.forEach(function (test, i) { // format var fmt = color('error title', ' %s) %s:\n') + color('error message', ' %s') + color('error stack', '\n%s\n'); // msg var msg; var err = test.err; var message; if (err.message && typeof err.message.toString === 'function') { message = err.message + ''; } else if (typeof err.inspect === 'function') { message = err.inspect() + ''; } else { message = ''; } var stack = err.stack || message; var index = message ? stack.indexOf(message) : -1; var actual = err.actual; var expected = err.expected; var escape = true; if (index === -1) { msg = message; } else { index += message.length; msg = stack.slice(0, index); // remove msg from stack stack = stack.slice(index + 1); } // uncaught if (err.uncaught) { msg = 'Uncaught ' + msg; } // explicitly show diff if (err.showDiff !== false && sameType(actual, expected) && expected !== undefined) { escape = false; if (!(utils.isString(actual) && utils.isString(expected))) { err.actual = actual = utils.stringify(actual); err.expected = expected = utils.stringify(expected); } fmt = color('error title', ' %s) %s:\n%s') + color('error stack', '\n%s\n'); var match = message.match(/^([^:]+): expected/); msg = '\n ' + color('error message', match ? match[1] : msg); if (exports.inlineDiffs) { msg += inlineDiff(err, escape); } else { msg += unifiedDiff(err, escape); } } // indent stack trace stack = stack.replace(/^/gm, ' '); console.log(fmt, (i + 1), test.fullTitle(), msg, stack); }); }; /** * 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) { var stats = this.stats = { suites: 0, tests: 0, passes: 0, pending: 0, failures: 0 }; var failures = this.failures = []; if (!runner) { return; } this.runner = runner; runner.stats = stats; runner.on('start', function () { stats.start = new Date(); }); runner.on('suite', function (suite) { stats.suites = stats.suites || 0; suite.root || stats.suites++; }); runner.on('test end', function () { stats.tests = stats.tests || 0; stats.tests++; }); runner.on('pass', function (test) { stats.passes = stats.passes || 0; if (test.duration > test.slow()) { test.speed = 'slow'; } else if (test.duration > test.slow() / 2) { test.speed = 'medium'; } else { test.speed = 'fast'; } stats.passes++; }); runner.on('fail', function (test, err) { stats.failures = stats.failures || 0; stats.failures++; test.err = err; failures.push(test); }); runner.on('end', function () { stats.end = new Date(); stats.duration = new Date() - stats.start; }); runner.on('pending', function () { stats.pending++; }); } /** * Output common epilogue used by many of * the bundled reporters. * * @api public */ Base.prototype.epilogue = function () { var stats = this.stats; var fmt; console.log(); // passes fmt = color('bright pass', ' ') + color('green', ' %d passing') + color('light', ' (%s)'); console.log(fmt, stats.passes || 0, ms(stats.duration)); // pending if (stats.pending) { fmt = color('pending', ' ') + color('pending', ' %d pending'); console.log(fmt, stats.pending); } // failures if (stats.failures) { fmt = color('fail', ' %d failing'); console.log(fmt, stats.failures); Base.list(this.failures); console.log(); } console.log(); }; /** * Pad the given `str` to `len`. * * @api private * @param {string} str * @param {string} len * @return {string} */ function pad (str, len) { str = String(str); return Array(len - str.length + 1).join(' ') + str; } /** * Returns an inline diff between 2 strings with coloured ANSI output * * @api private * @param {Error} err with actual/expected * @param {boolean} escape * @return {string} Diff */ function inlineDiff (err, escape) { var msg = errorDiff(err, 'WordsWithSpace', escape); // linenos var lines = msg.split('\n'); if (lines.length > 4) { var width = String(lines.length).length; msg = lines.map(function (str, i) { return pad(+