| 'use strict'; |
| |
| /*! |
| * mocha |
| * Copyright(c) 2011 TJ Holowaychuk <tj@vision-media.ca> |
| * MIT Licensed |
| */ |
| |
| var escapeRe = require('escape-string-regexp'); |
| var path = require('path'); |
| var builtinReporters = require('./reporters'); |
| var growl = require('./growl'); |
| var utils = require('./utils'); |
| var mocharc = require('./mocharc.json'); |
| var errors = require('./errors'); |
| var Suite = require('./suite'); |
| var createStatsCollector = require('./stats-collector'); |
| var createInvalidReporterError = errors.createInvalidReporterError; |
| var createInvalidInterfaceError = errors.createInvalidInterfaceError; |
| var EVENT_FILE_PRE_REQUIRE = Suite.constants.EVENT_FILE_PRE_REQUIRE; |
| var EVENT_FILE_POST_REQUIRE = Suite.constants.EVENT_FILE_POST_REQUIRE; |
| var EVENT_FILE_REQUIRE = Suite.constants.EVENT_FILE_REQUIRE; |
| var sQuote = utils.sQuote; |
| |
| 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. |
| */ |
| |
| /** |
| * @public |
| * @class utils |
| * @memberof Mocha |
| */ |
| exports.utils = utils; |
| exports.interfaces = require('./interfaces'); |
| /** |
| * @public |
| * @memberof Mocha |
| */ |
| exports.reporters = builtinReporters; |
| exports.Runnable = require('./runnable'); |
| exports.Context = require('./context'); |
| /** |
| * |
| * @memberof Mocha |
| */ |
| exports.Runner = require('./runner'); |
| exports.Suite = Suite; |
| exports.Hook = require('./hook'); |
| exports.Test = require('./test'); |
| |
| /** |
| * Constructs a new Mocha instance with `options`. |
| * |
| * @public |
| * @class Mocha |
| * @param {Object} [options] - Settings object. |
| * @param {boolean} [options.allowUncaught] - Propagate uncaught errors? |
| * @param {boolean} [options.asyncOnly] - Force `done` callback or promise? |
| * @param {boolean} [options.bail] - Bail after first test failure? |
| * @param {boolean} [options.checkLeaks] - If true, check leaks. |
| * @param {boolean} [options.delay] - Delay root suite execution? |
| * @param {boolean} [options.enableTimeouts] - Enable timeouts? |
| * @param {string} [options.fgrep] - Test filter given string. |
| * @param {boolean} [options.forbidOnly] - Tests marked `only` fail the suite? |
| * @param {boolean} [options.forbidPending] - Pending tests fail the suite? |
| * @param {boolean} [options.fullStackTrace] - Full stacktrace upon failure? |
| * @param {string[]} [options.global] - Variables expected in global scope. |
| * @param {RegExp|string} [options.grep] - Test filter given regular expression. |
| * @param {boolean} [options.growl] - Enable desktop notifications? |
| * @param {boolean} [options.hideDiff] - Suppress diffs from failures? |
| * @param {boolean} [options.ignoreLeaks] - Ignore global leaks? |
| * @param {boolean} [options.invert] - Invert test filter matches? |
| * @param {boolean} [options.noHighlighting] - Disable syntax highlighting? |
| * @param {string} [options.reporter] - Reporter name. |
| * @param {Object} [options.reporterOption] - Reporter settings object. |
| * @param {number} [options.retries] - Number of times to retry failed tests. |
| * @param {number} [options.slow] - Slow threshold value. |
| * @param {number|string} [options.timeout] - Timeout threshold value. |
| * @param {string} [options.ui] - Interface name. |
| * @param {boolean} [options.color] - Color TTY output from reporter? |
| * @param {boolean} [options.useInlineDiffs] - Use inline diffs? |
| */ |
| function Mocha(options) { |
| options = utils.assign({}, mocharc, options || {}); |
| this.files = []; |
| this.options = options; |
| // root suite |
| this.suite = new exports.Suite('', new exports.Context(), true); |
| |
| if ('useColors' in options) { |
| utils.deprecate( |
| 'useColors is DEPRECATED and will be removed from a future version of Mocha. Instead, use the "color" option' |
| ); |
| options.color = 'color' in options ? options.color : options.useColors; |
| } |
| |
| // Globals are passed in as options.global, with options.globals for backward compatibility. |
| options.globals = options.global || options.globals || []; |
| delete options.global; |
| |
| this.grep(options.grep) |
| .fgrep(options.fgrep) |
| .ui(options.ui) |
| .bail(options.bail) |
| .reporter(options.reporter, options.reporterOptions) |
| .useColors(options.color) |
| .slow(options.slow) |
| .useInlineDiffs(options.inlineDiffs) |
| .globals(options.globals); |
| |
| if ('enableTimeouts' in options) { |
| utils.deprecate( |
| 'enableTimeouts is DEPRECATED and will be removed from a future version of Mocha. Instead, use "timeout: false" to disable timeouts.' |
| ); |
| if (options.enableTimeouts === false) { |
| this.timeout(0); |
| } |
| } |
| |
| // this guard exists because Suite#timeout does not consider `undefined` to be valid input |
| if (typeof options.timeout !== 'undefined') { |
| this.timeout(options.timeout === false ? 0 : options.timeout); |
| } |
| |
| if ('retries' in options) { |
| this.retries(options.retries); |
| } |
| |
| if ('diff' in options) { |
| this.hideDiff(!options.diff); |
| } |
| |
| [ |
| 'allowUncaught', |
| 'asyncOnly', |
| 'checkLeaks', |
| 'delay', |
| 'forbidOnly', |
| 'forbidPending', |
| 'fullTrace', |
| 'growl', |
| 'invert' |
| ].forEach(function(opt) { |
| if (options[opt]) { |
| this[opt](); |
| } |
| }, this); |
| } |
| |
| /** |
| * Enables or disables bailing on the first failure. |
| * |
| * @public |
| * @see {@link https://mochajs.org/#-b---bail|CLI option} |
| * @param {boolean} [bail=true] - Whether to bail on first error. |
| * @returns {Mocha} this |
| * @chainable |
| */ |
| Mocha.prototype.bail = function(bail) { |
| if (!arguments.length) { |
| bail = true; |
| } |
| this.suite.bail(bail); |
| return this; |
| }; |
| |
| /** |
| * @summary |
| * Adds `file` to be loaded for execution. |
| * |
| * @description |
| * Useful for generic setup code that must be included within test suite. |
| * |
| * @public |
| * @see {@link https://mochajs.org/#--file-file|CLI option} |
| * @param {string} file - Pathname of file to be loaded. |
| * @returns {Mocha} this |
| * @chainable |
| */ |
| Mocha.prototype.addFile = function(file) { |
| this.files.push(file); |
| return this; |
| }; |
| |
| /** |
| * Sets reporter to `reporter`, defaults to "spec". |
| * |
| * @public |
| * @see {@link https://mochajs.org/#-r---reporter-name|CLI option} |
| * @see {@link https://mochajs.org/#reporters|Reporters} |
| * @param {String|Function} reporter - Reporter name or constructor. |
| * @param {Object} [reporterOptions] - Options used to configure the reporter. |
| * @returns {Mocha} this |
| * @chainable |
| * @throws {Error} if requested reporter cannot be loaded |
| * @example |
| * |
| * // Use XUnit reporter and direct its output to file |
| * mocha.reporter('xunit', { output: '/path/to/testspec.xunit.xml' }); |
| */ |
| 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 (builtinReporters[reporter]) { |
| _reporter = builtinReporters[reporter]; |
| } |
| // Try to load reporters from process.cwd() and node_modules |
| if (!_reporter) { |
| try { |
| _reporter = require(reporter); |
| } catch (err) { |
| if ( |
| err.code !== 'MODULE_NOT_FOUND' || |
| err.message.indexOf('Cannot find module') !== -1 |
| ) { |
| // Try to load reporters from a path (absolute or relative) |
| try { |
| _reporter = require(path.resolve(process.cwd(), reporter)); |
| } catch (_err) { |
| _err.code !== 'MODULE_NOT_FOUND' || |
| _err.message.indexOf('Cannot find module') !== -1 |
| ? console.warn(sQuote(reporter) + ' reporter not found') |
| : console.warn( |
| sQuote(reporter) + |
| ' reporter blew up with error:\n' + |
| err.stack |
| ); |
| } |
| } else { |
| console.warn( |
| sQuote(reporter) + ' reporter blew up with error:\n' + err.stack |
| ); |
| } |
| } |
| } |
| if (!_reporter) { |
| throw createInvalidReporterError( |
| 'invalid reporter ' + sQuote(reporter), |
| reporter |
| ); |
| } |
| this._reporter = _reporter; |
| } |
| this.options.reporterOptions = reporterOptions; |
| return this; |
| }; |
| |
| /** |
| * Sets test UI `name`, defaults to "bdd". |
| * |
| * @public |
| * @see {@link https://mochajs.org/#-u---ui-name|CLI option} |
| * @see {@link https://mochajs.org/#interfaces|Interface DSLs} |
| * @param {string|Function} [ui=bdd] - Interface name or class. |
| * @returns {Mocha} this |
| * @chainable |
| * @throws {Error} if requested interface cannot be loaded |
| */ |
| Mocha.prototype.ui = function(ui) { |
| var bindInterface; |
| if (typeof ui === 'function') { |
| bindInterface = ui; |
| } else { |
| ui = ui || 'bdd'; |
| bindInterface = exports.interfaces[ui]; |
| if (!bindInterface) { |
| try { |
| bindInterface = require(ui); |
| } catch (err) { |
| throw createInvalidInterfaceError( |
| 'invalid interface ' + sQuote(ui), |
| ui |
| ); |
| } |
| } |
| } |
| bindInterface(this.suite); |
| |
| this.suite.on(EVENT_FILE_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.xit = context.xit || (context.test && context.test.skip); |
| 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; |
| }; |
| |
| /** |
| * Loads `files` prior to execution. |
| * |
| * @description |
| * The implementation relies on Node's `require` to execute |
| * the test interface functions and will be subject to its cache. |
| * |
| * @private |
| * @see {@link Mocha#addFile} |
| * @see {@link Mocha#run} |
| * @see {@link Mocha#unloadFiles} |
| * @param {Function} [fn] - Callback invoked upon completion. |
| */ |
| Mocha.prototype.loadFiles = function(fn) { |
| var self = this; |
| var suite = this.suite; |
| this.files.forEach(function(file) { |
| file = path.resolve(file); |
| suite.emit(EVENT_FILE_PRE_REQUIRE, global, file, self); |
| suite.emit(EVENT_FILE_REQUIRE, require(file), file, self); |
| suite.emit(EVENT_FILE_POST_REQUIRE, global, file, self); |
| }); |
| fn && fn(); |
| }; |
| |
| /** |
| * Removes a previously loaded file from Node's `require` cache. |
| * |
| * @private |
| * @static |
| * @see {@link Mocha#unloadFiles} |
| * @param {string} file - Pathname of file to be unloaded. |
| */ |
| Mocha.unloadFile = function(file) { |
| delete require.cache[require.resolve(file)]; |
| }; |
| |
| /** |
| * Unloads `files` from Node's `require` cache. |
| * |
| * @description |
| * This allows files to be "freshly" reloaded, providing the ability |
| * to reuse a Mocha instance programmatically. |
| * |
| * <strong>Intended for consumers — not used internally</strong> |
| * |
| * @public |
| * @see {@link Mocha.unloadFile} |
| * @see {@link Mocha#loadFiles} |
| * @see {@link Mocha#run} |
| * @returns {Mocha} this |
| * @chainable |
| */ |
| Mocha.prototype.unloadFiles = function() { |
| this.files.forEach(Mocha.unloadFile); |
| return this; |
| }; |
| |
| /** |
| * Sets `grep` filter after escaping RegExp special characters. |
| * |
| * @public |
| * @see {@link Mocha#grep} |
| * @param {string} str - Value to be converted to a regexp. |
| * @returns {Mocha} this |
| * @chainable |
| * @example |
| * |
| * // Select tests whose full title begins with `"foo"` followed by a period |
| * mocha.fgrep('foo.'); |
| */ |
| Mocha.prototype.fgrep = function(str) { |
| if (!str) { |
| return this; |
| } |
| return this.grep(new RegExp(escapeRe(str))); |
| }; |
| |
| /** |
| * @summary |
| * Sets `grep` filter used to select specific tests for execution. |
| * |
| * @description |
| * If `re` is a regexp-like string, it will be converted to regexp. |
| * The regexp is tested against the full title of each test (i.e., the |
| * name of the test preceded by titles of each its ancestral suites). |
| * As such, using an <em>exact-match</em> fixed pattern against the |
| * test name itself will not yield any matches. |
| * <br> |
| * <strong>Previous filter value will be overwritten on each call!</strong> |
| * |
| * @public |
| * @see {@link https://mochajs.org/#-g---grep-pattern|CLI option} |
| * @see {@link Mocha#fgrep} |
| * @see {@link Mocha#invert} |
| * @param {RegExp|String} re - Regular expression used to select tests. |
| * @return {Mocha} this |
| * @chainable |
| * @example |
| * |
| * // Select tests whose full title contains `"match"`, ignoring case |
| * mocha.grep(/match/i); |
| * @example |
| * |
| * // Same as above but with regexp-like string argument |
| * mocha.grep('/match/i'); |
| * @example |
| * |
| * // ## Anti-example |
| * // Given embedded test `it('only-this-test')`... |
| * mocha.grep('/^only-this-test$/'); // NO! Use `.only()` to do this! |
| */ |
| 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; |
| }; |
| |
| /** |
| * Inverts `grep` matches. |
| * |
| * @public |
| * @see {@link Mocha#grep} |
| * @return {Mocha} this |
| * @chainable |
| * @example |
| * |
| * // Select tests whose full title does *not* contain `"match"`, ignoring case |
| * mocha.grep(/match/i).invert(); |
| */ |
| Mocha.prototype.invert = function() { |
| this.options.invert = true; |
| return this; |
| }; |
| |
| /** |
| * Enables or disables ignoring global leaks. |
| * |
| * @public |
| * @see {@link Mocha#checkLeaks} |
| * @param {boolean} ignoreLeaks - Whether to ignore global leaks. |
| * @return {Mocha} this |
| * @chainable |
| * @example |
| * |
| * // Ignore global leaks |
| * mocha.ignoreLeaks(true); |
| */ |
| Mocha.prototype.ignoreLeaks = function(ignoreLeaks) { |
| this.options.ignoreLeaks = Boolean(ignoreLeaks); |
| return this; |
| }; |
| |
| /** |
| * Enables checking for global variables leaked while running tests. |
| * |
| * @public |
| * @see {@link https://mochajs.org/#--check-leaks|CLI option} |
| * @see {@link Mocha#ignoreLeaks} |
| * @return {Mocha} this |
| * @chainable |
| */ |
| Mocha.prototype.checkLeaks = function() { |
| this.options.ignoreLeaks = false; |
| return this; |
| }; |
| |
| /** |
| * Displays full stack trace upon test failure. |
| * |
| * @public |
| * @return {Mocha} this |
| * @chainable |
| */ |
| Mocha.prototype.fullTrace = function() { |
| this.options.fullStackTrace = true; |
| return this; |
| }; |
| |
| /** |
| * Enables desktop notification support if prerequisite software installed. |
| * |
| * @public |
| * @see {@link Mocha#isGrowlCapable} |
| * @see {@link Mocha#_growl} |
| * @return {Mocha} this |
| * @chainable |
| */ |
| Mocha.prototype.growl = function() { |
| this.options.growl = this.isGrowlCapable(); |
| if (!this.options.growl) { |
| var detail = process.browser |
| ? 'notification support not available in this browser...' |
| : 'notification support prerequisites not installed...'; |
| console.error(detail + ' cannot enable!'); |
| } |
| return this; |
| }; |
| |
| /** |
| * @summary |
| * Determines if Growl support seems likely. |
| * |
| * @description |
| * <strong>Not available when run in browser.</strong> |
| * |
| * @private |
| * @see {@link Growl#isCapable} |
| * @see {@link Mocha#growl} |
| * @return {boolean} whether Growl support can be expected |
| */ |
| Mocha.prototype.isGrowlCapable = growl.isCapable; |
| |
| /** |
| * Implements desktop notifications using a pseudo-reporter. |
| * |
| * @private |
| * @see {@link Mocha#growl} |
| * @see {@link Growl#notify} |
| * @param {Runner} runner - Runner instance. |
| */ |
| Mocha.prototype._growl = growl.notify; |
| |
| /** |
| * Specifies whitelist of variable names to be expected in global scope. |
| * |
| * @public |
| * @see {@link https://mochajs.org/#-global-variable-name|CLI option} |
| * @see {@link Mocha#checkLeaks} |
| * @param {String[]|String} globals - Accepted global variable name(s). |
| * @return {Mocha} this |
| * @chainable |
| * @example |
| * |
| * // Specify variables to be expected in global scope |
| * mocha.globals(['jQuery', 'MyLib']); |
| */ |
| Mocha.prototype.globals = function(globals) { |
| this.options.globals = this.options.globals |
| .concat(globals) |
| .filter(Boolean) |
| .filter(function(elt, idx, arr) { |
| return arr.indexOf(elt) === idx; |
| }); |
| return this; |
| }; |
| |
| /** |
| * Enables or disables TTY color output by screen-oriented reporters. |
| * |
| * @public |
| * @param {boolean} colors - Whether to enable color output. |
| * @return {Mocha} this |
| * @chainable |
| */ |
| Mocha.prototype.useColors = function(colors) { |
| if (colors !== undefined) { |
| this.options.useColors = colors; |
| } |
| return this; |
| }; |
| |
| /** |
| * Determines if reporter should use inline diffs (rather than +/-) |
| * in test failure output. |
| * |
| * @public |
| * @param {boolean} inlineDiffs - Whether to use inline diffs. |
| * @return {Mocha} this |
| * @chainable |
| */ |
| Mocha.prototype.useInlineDiffs = function(inlineDiffs) { |
| this.options.useInlineDiffs = inlineDiffs !== undefined && inlineDiffs; |
| return this; |
| }; |
| |
| /** |
| * Determines if reporter should include diffs in test failure output. |
| * |
| * @public |
| * @param {boolean} hideDiff - Whether to hide diffs. |
| * @return {Mocha} this |
| * @chainable |
| */ |
| Mocha.prototype.hideDiff = function(hideDiff) { |
| this.options.hideDiff = hideDiff !== undefined && hideDiff; |
| return this; |
| }; |
| |
| /** |
| * @summary |
| * Sets timeout threshold value. |
| * |
| * @description |
| * A string argument can use shorthand (such as "2s") and will be converted. |
| * If the value is `0`, timeouts will be disabled. |
| * |
| * @public |
| * @see {@link https://mochajs.org/#-t---timeout-ms|CLI option} |
| * @see {@link https://mochajs.org/#--no-timeouts|CLI option} |
| * @see {@link https://mochajs.org/#timeouts|Timeouts} |
| * @see {@link Mocha#enableTimeouts} |
| * @param {number|string} msecs - Timeout threshold value. |
| * @return {Mocha} this |
| * @chainable |
| * @example |
| * |
| * // Sets timeout to one second |
| * mocha.timeout(1000); |
| * @example |
| * |
| * // Same as above but using string argument |
| * mocha.timeout('1s'); |
| */ |
| Mocha.prototype.timeout = function(msecs) { |
| this.suite.timeout(msecs); |
| return this; |
| }; |
| |
| /** |
| * Sets the number of times to retry failed tests. |
| * |
| * @public |
| * @see {@link https://mochajs.org/#retry-tests|Retry Tests} |
| * @param {number} retry - Number of times to retry failed tests. |
| * @return {Mocha} this |
| * @chainable |
| * @example |
| * |
| * // Allow any failed test to retry one more time |
| * mocha.retries(1); |
| */ |
| Mocha.prototype.retries = function(n) { |
| this.suite.retries(n); |
| return this; |
| }; |
| |
| /** |
| * Sets slowness threshold value. |
| * |
| * @public |
| * @see {@link https://mochajs.org/#-s---slow-ms|CLI option} |
| * @param {number} msecs - Slowness threshold value. |
| * @return {Mocha} this |
| * @chainable |
| * @example |
| * |
| * // Sets "slow" threshold to half a second |
| * mocha.slow(500); |
| * @example |
| * |
| * // Same as above but using string argument |
| * mocha.slow('0.5s'); |
| */ |
| Mocha.prototype.slow = function(msecs) { |
| this.suite.slow(msecs); |
| return this; |
| }; |
| |
| /** |
| * Enables or disables timeouts. |
| * |
| * @public |
| * @see {@link https://mochajs.org/#-t---timeout-ms|CLI option} |
| * @see {@link https://mochajs.org/#--no-timeouts|CLI option} |
| * @param {boolean} enableTimeouts - Whether to enable timeouts. |
| * @return {Mocha} this |
| * @chainable |
| */ |
| Mocha.prototype.enableTimeouts = function(enableTimeouts) { |
| this.suite.enableTimeouts( |
| arguments.length && enableTimeouts !== undefined ? enableTimeouts : true |
| ); |
| return this; |
| }; |
| |
| /** |
| * Forces all tests to either accept a `done` callback or return a promise. |
| * |
| * @public |
| * @return {Mocha} this |
| * @chainable |
| */ |
| Mocha.prototype.asyncOnly = function() { |
| this.options.asyncOnly = true; |
| return this; |
| }; |
| |
| /** |
| * Disables syntax highlighting (in browser). |
| * |
| * @public |
| * @return {Mocha} this |
| * @chainable |
| */ |
| Mocha.prototype.noHighlighting = function() { |
| this.options.noHighlighting = true; |
| return this; |
| }; |
| |
| /** |
| * Enables uncaught errors to propagate (in browser). |
| * |
| * @public |
| * @return {Mocha} this |
| * @chainable |
| */ |
| Mocha.prototype.allowUncaught = function() { |
| this.options.allowUncaught = true; |
| return this; |
| }; |
| |
| /** |
| * @summary |
| * Delays root suite execution. |
| * |
| * @description |
| * Used to perform asynch operations before any suites are run. |
| * |
| * @public |
| * @see {@link https://mochajs.org/#delayed-root-suite|delayed root suite} |
| * @returns {Mocha} this |
| * @chainable |
| */ |
| Mocha.prototype.delay = function delay() { |
| this.options.delay = true; |
| return this; |
| }; |
| |
| /** |
| * Causes tests marked `only` to fail the suite. |
| * |
| * @public |
| * @returns {Mocha} this |
| * @chainable |
| */ |
| Mocha.prototype.forbidOnly = function() { |
| this.options.forbidOnly = true; |
| return this; |
| }; |
| |
| /** |
| * Causes pending tests and tests marked `skip` to fail the suite. |
| * |
| * @public |
| * @returns {Mocha} this |
| * @chainable |
| */ |
| Mocha.prototype.forbidPending = function() { |
| this.options.forbidPending = true; |
| return this; |
| }; |
| |
| /** |
| * Mocha version as specified by "package.json". |
| * |
| * @name Mocha#version |
| * @type string |
| * @readonly |
| */ |
| Object.defineProperty(Mocha.prototype, 'version', { |
| value: require('../package.json').version, |
| configurable: false, |
| enumerable: true, |
| writable: false |
| }); |
| |
| /** |
| * Callback to be invoked when test execution is complete. |
| * |
| * @callback DoneCB |
| * @param {number} failures - Number of failures that occurred. |
| */ |
| |
| /** |
| * Runs root suite and invokes `fn()` when complete. |
| * |
| * @description |
| * To run tests multiple times (or to run tests in files that are |
| * already in the `require` cache), make sure to clear them from |
| * the cache first! |
| * |
| * @public |
| * @see {@link Mocha#loadFiles} |
| * @see {@link Mocha#unloadFiles} |
| * @see {@link Runner#run} |
| * @param {DoneCB} [fn] - Callback invoked when test execution completed. |
| * @return {Runner} runner instance |
| */ |
| 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); |
| createStatsCollector(runner); |
| var reporter = new this._reporter(runner, options); |
| runner.ignoreLeaks = options.ignoreLeaks !== false; |
| runner.fullStackTrace = options.fullStackTrace; |
| runner.asyncOnly = options.asyncOnly; |
| runner.allowUncaught = options.allowUncaught; |
| runner.forbidOnly = options.forbidOnly; |
| runner.forbidPending = options.forbidPending; |
| if (options.grep) { |
| runner.grep(options.grep, options.invert); |
| } |
| if (options.globals) { |
| runner.globals(options.globals); |
| } |
| if (options.growl) { |
| this._growl(runner); |
| } |
| if (options.useColors !== undefined) { |
| exports.reporters.Base.useColors = options.useColors; |
| } |
| exports.reporters.Base.inlineDiffs = options.useInlineDiffs; |
| exports.reporters.Base.hideDiff = options.hideDiff; |
| |
| function done(failures) { |
| fn = fn || utils.noop; |
| if (reporter.done) { |
| reporter.done(failures, fn); |
| } else { |
| fn(failures); |
| } |
| } |
| |
| return runner.run(done); |
| }; |