Files

Return to Package Diff Home.
Brought to you by Intrinsic.

Package Diff: mocha @ 5.0.0 .. 5.2.0

bin/.eslintrc.yml

@@ -1,3 +0,0 @@
-env:
- es6: true
- browser: false

bin/_mocha

@@ -10,6 +10,7 @@
const program = require('commander');
const path = require('path');
const fs = require('fs');
+const minimatch = require('minimatch');
const resolve = path.resolve;
const exists = fs.existsSync;
const Mocha = require('../');
@@ -57,7 +58,7 @@
// https://github.com/joyent/node/issues/6247 is just one bug example
// https://github.com/visionmedia/mocha/issues/333 has a good discussion
const done = () => {
- if (!(draining--)) {
+ if (!draining--) {
process.exit(clampedCode);
}
};
@@ -142,16 +143,23 @@
*/
const images = {
- fail: path.join(__dirname, '..', 'images', 'error.png'),
- pass: path.join(__dirname, '..', 'images', 'ok.png')
+ fail: path.join(__dirname, '..', 'assets', 'growl', 'error.png'),
+ pass: path.join(__dirname, '..', 'assets', 'growl', 'ok.png')
};
// options
program
- .version(JSON.parse(fs.readFileSync(path.join(__dirname, '..', 'package.json'), 'utf8')).version)
+ .version(
+ JSON.parse(
+ fs.readFileSync(path.join(__dirname, '..', 'package.json'), 'utf8')
+ ).version
+ )
.usage('[debug] [options] [files]')
- .option('-A, --async-only', 'force all tests to take a callback (async) or return a promise')
+ .option(
+ '-A, --async-only',
+ 'force all tests to take a callback (async) or return a promise'
+ )
.option('-c, --colors', 'force enabling of colors')
.option('-C, --no-colors', 'force disabling of colors')
.option('-G, --growl', 'enable growl notification support')
@@ -167,24 +175,53 @@
.option('-r, --require <name>', 'require the given module')
.option('-s, --slow <ms>', '"slow" test threshold in milliseconds [75]')
.option('-t, --timeout <ms>', 'set test-case timeout in milliseconds [2000]')
- .option('-u, --ui <name>', `specify user-interface (${interfaceNames.join('|')})`, 'bdd')
+ .option(
+ '-u, --ui <name>',
+ `specify user-interface (${interfaceNames.join('|')})`,
+ 'bdd'
+ )
.option('-w, --watch', 'watch files for changes')
.option('--check-leaks', 'check for global variable leaks')
.option('--full-trace', 'display the full stack trace')
- .option('--compilers <ext>:<module>,...', 'use the given module(s) to compile files', list, [])
+ .option(
+ '--compilers <ext>:<module>,...',
+ 'use the given module(s) to compile files',
+ list,
+ []
+ )
.option('--debug-brk', "enable node's debugger breaking on the first line")
- .option('--globals <names>', 'allow the given comma-delimited global [names]', list, [])
+ .option(
+ '--globals <names>',
+ 'allow the given comma-delimited global [names]',
+ list,
+ []
+ )
.option('--es_staging', 'enable all staged features')
- .option('--harmony<_classes,_generators,...>', 'all node --harmony* flags are available')
- .option('--preserve-symlinks', 'Instructs the module loader to preserve symbolic links when resolving and caching modules')
+ .option(
+ '--harmony<_classes,_generators,...>',
+ 'all node --harmony* flags are available'
+ )
+ .option(
+ '--preserve-symlinks',
+ 'Instructs the module loader to preserve symbolic links when resolving and caching modules'
+ )
.option('--icu-data-dir', 'include ICU data')
- .option('--inline-diffs', 'display actual/expected differences inline within each string')
+ .option(
+ '--inline-diffs',
+ 'display actual/expected differences inline within each string'
+ )
.option('--no-diff', 'do not show a diff on failure')
.option('--inspect', 'activate devtools in chrome')
- .option('--inspect-brk', 'activate devtools in chrome and break on the first line')
+ .option(
+ '--inspect-brk',
+ 'activate devtools in chrome and break on the first line'
+ )
.option('--interfaces', 'display available interfaces')
.option('--no-deprecation', 'silence deprecation warnings')
- .option('--exit', 'force shutdown of the event loop after test run: mocha will call process.exit')
+ .option(
+ '--exit',
+ 'force shutdown of the event loop after test run: mocha will call process.exit'
+ )
.option('--no-timeouts', 'disables timeouts, given implicitly with --debug')
.option('--no-warnings', 'silence all node process warnings')
.option('--opts <path>', 'specify opts path', 'test/mocha.opts')
@@ -194,18 +231,38 @@
.option('--log-timer-events', 'Time events including external callbacks')
.option('--recursive', 'include sub directories')
.option('--reporters', 'display available reporters')
- .option('--retries <times>', 'set numbers of time to retry a failed test case')
- .option('--throw-deprecation', 'throw an exception anytime a deprecated function is used')
+ .option(
+ '--retries <times>',
+ 'set numbers of time to retry a failed test case'
+ )
+ .option(
+ '--throw-deprecation',
+ 'throw an exception anytime a deprecated function is used'
+ )
.option('--trace', 'trace function calls')
.option('--trace-deprecation', 'show stack traces on deprecations')
.option('--trace-warnings', 'show stack traces on node process warnings')
.option('--use_strict', 'enforce strict mode')
- .option('--watch-extensions <ext>,...', 'additional extensions to monitor with --watch', list, [])
+ .option(
+ '--watch-extensions <ext>,...',
+ 'additional extensions to monitor with --watch',
+ list,
+ ['js']
+ )
.option('--delay', 'wait for async suite definition')
.option('--allow-uncaught', 'enable uncaught errors to propagate')
.option('--forbid-only', 'causes test marked with only to fail the suite')
- .option('--forbid-pending', 'causes pending tests and test marked with skip to fail the suite')
- .option('--file <file>', 'include a file to be ran during the suite', collect, []);
+ .option(
+ '--forbid-pending',
+ 'causes pending tests and test marked with skip to fail the suite'
+ )
+ .option(
+ '--file <file>',
+ 'include a file to be ran during the suite',
+ collect,
+ []
+ )
+ .option('--exclude <file>', 'a file or glob pattern to ignore', collect, []);
program._name = 'mocha';
@@ -310,19 +367,6 @@
mocha.reporter(program.reporter, reporterOptions);
-// load reporter
-
-let Reporter = null;
-try {
- Reporter = require(`../lib/reporters/${program.reporter}`);
-} catch (err) {
- try {
- Reporter = require(program.reporter);
- } catch (err2) {
- throw new Error(`reporter "${program.reporter}" does not exist`);
- }
-}
-
// --no-colors
if (!program.colors) {
@@ -487,13 +531,24 @@
newFiles = utils.lookupFiles(arg, extensions, program.recursive);
} catch (err) {
if (err.message.indexOf('cannot resolve path') === 0) {
- console.error(`Warning: Could not find any test files matching pattern: ${arg}`);
+ console.error(
+ `Warning: Could not find any test files matching pattern: ${arg}`
+ );
return;
}
throw err;
}
+ if (typeof newFiles !== 'undefined') {
+ if (typeof newFiles === 'string') {
+ newFiles = [newFiles];
+ }
+ newFiles = newFiles.filter(fileName =>
+ program.exclude.every(pattern => !minimatch(fileName, pattern))
+ );
+ }
+
files = files.concat(newFiles);
});
@@ -529,7 +584,7 @@
process.exit(130);
});
- const watchFiles = utils.files(cwd, [ 'js' ].concat(program.watchExtensions));
+ const watchFiles = utils.files(cwd, ['js'].concat(program.watchExtensions));
let runAgain = false;
loadAndRun = () => {
@@ -576,7 +631,7 @@
}
});
} else {
-// load
+ // load
mocha.files = files;
runner = mocha.run(program.exit ? exit : exitLater);

bin/options.js

@@ -16,17 +16,23 @@
* Get options.
*/
-function getOptions () {
- if (process.argv.length === 3 && (process.argv[2] === '-h' || process.argv[2] === '--help')) {
+function getOptions() {
+ if (
+ process.argv.length === 3 &&
+ (process.argv[2] === '-h' || process.argv[2] === '--help')
+ ) {
return;
}
- const optsPath = process.argv.indexOf('--opts') === -1
+ const optsPath =
+ process.argv.indexOf('--opts') === -1
? 'test/mocha.opts'
: process.argv[process.argv.indexOf('--opts') + 1];
try {
- const opts = fs.readFileSync(optsPath, 'utf8')
+ const opts = fs
+ .readFileSync(optsPath, 'utf8')
+ .replace(/^#.*$/gm, '')
.replace(/\\\s/g, '%20')
.split(/\s/)
.filter(Boolean)
@@ -35,8 +41,8 @@
process.argv = process.argv
.slice(0, 2)
.concat(opts.concat(process.argv.slice(2)));
- } catch (err) {
- // ignore
+ } catch (ignore) {
+ // NOTE: should console.error() and throw the error
}
process.env.LOADED_MOCHA_OPTS = true;

browser-entry.js

@@ -17,7 +17,7 @@
* @return {undefined}
*/
-var mocha = new Mocha({ reporter: 'html' });
+var mocha = new Mocha({reporter: 'html'});
/**
* Save timer references to avoid Sinon interfering (see GH-237).
@@ -38,12 +38,12 @@
* Revert to original onerror handler if previously defined.
*/
-process.removeListener = function (e, fn) {
+process.removeListener = function(e, fn) {
if (e === 'uncaughtException') {
if (originalOnerrorHandler) {
global.onerror = originalOnerrorHandler;
} else {
- global.onerror = function () {};
+ global.onerror = function() {};
}
var i = uncaughtExceptionHandlers.indexOf(fn);
if (i !== -1) {
@@ -56,9 +56,9 @@
* Implements uncaughtException listener.
*/
-process.on = function (e, fn) {
+process.on = function(e, fn) {
if (e === 'uncaughtException') {
- global.onerror = function (err, url, line) {
+ global.onerror = function(err, url, line) {
fn(new Error(err + ' (' + url + ':' + line + ')'));
return !mocha.allowUncaught;
};
@@ -74,9 +74,9 @@
var immediateQueue = [];
var immediateTimeout;
-function timeslice () {
+function timeslice() {
var immediateStart = new Date().getTime();
- while (immediateQueue.length && (new Date().getTime() - immediateStart) < 100) {
+ while (immediateQueue.length && new Date().getTime() - immediateStart < 100) {
immediateQueue.shift()();
}
if (immediateQueue.length) {
@@ -90,7 +90,7 @@
* High-performance override of Runner.immediately.
*/
-Mocha.Runner.immediately = function (callback) {
+Mocha.Runner.immediately = function(callback) {
immediateQueue.push(callback);
if (!immediateTimeout) {
immediateTimeout = setTimeout(timeslice, 0);
@@ -102,8 +102,8 @@
* 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) {
+mocha.throwError = function(err) {
+ uncaughtExceptionHandlers.forEach(function(fn) {
fn(err);
});
throw err;
@@ -114,7 +114,7 @@
* Normally this would happen in Mocha.prototype.loadFiles.
*/
-mocha.ui = function (ui) {
+mocha.ui = function(ui) {
Mocha.prototype.ui.call(this, ui);
this.suite.emit('pre-require', global, null, this);
return this;
@@ -124,9 +124,9 @@
* Setup mocha with the given setting options.
*/
-mocha.setup = function (opts) {
+mocha.setup = function(opts) {
if (typeof opts === 'string') {
- opts = { ui: opts };
+ opts = {ui: opts};
}
for (var opt in opts) {
if (opts.hasOwnProperty(opt)) {
@@ -140,7 +140,7 @@
* Run mocha, returning the Runner.
*/
-mocha.run = function (fn) {
+mocha.run = function(fn) {
var options = mocha.options;
mocha.globals('location');
@@ -155,10 +155,14 @@
mocha.invert();
}
- return Mocha.prototype.run.call(mocha, function (err) {
+ 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) {
+ if (
+ document &&
+ document.getElementById('mocha') &&
+ options.noHighlighting !== true
+ ) {
Mocha.utils.highlightTags('code');
}
if (fn) {

CHANGELOG.md

@@ -1,3 +1,211 @@
+# 5.2.0 / 2018-05-18
+
+## :tada: Enhancements
+
+- [#3375]: Add support for comments in `mocha.opts` ([@plroebuck])
+
+## :bug: Fixes
+
+- [#3346]: Exit correctly from `before` hooks when using `--bail` ([@outsideris])
+
+## :book: Documentation
+
+- [#3328]: Mocha-flavored [API docs](https://mochajs.org/api/)! ([@Munter])
+
+## :nut_and_bolt: Other
+
+- [#3330]: Use `Buffer.from()` ([@harrysarson])
+- [#3295]: Remove redundant folder ([@DavNej])
+- [#3356]: Refactoring ([@plroebuck])
+
+[#3375]: https://github.com/mochajs/mocha/pull/3375
+[#3346]: https://github.com/mochajs/mocha/pull/3346
+[#3328]: https://github.com/mochajs/mocha/pull/3328
+[#3330]: https://github.com/mochajs/mocha/pull/3330
+[#3295]: https://github.com/mochajs/mocha/pull/3295
+[#3356]: https://github.com/mochajs/mocha/pull/3356
+
+[@plroebuck]: https://github.com/plroebuck
+[@harrysarson]: https://github.com/harrysarson
+[@outsideris]: https://github.com/outsideris
+[@Munter]: https://github.com/Munter
+
+# 5.1.1 / 2018-04-18
+
+## :bug: Fixes
+
+- [#3325]: Revert change which broke `--watch` ([@boneskull])
+
+[#3325]: https://github.com/mochajs/mocha/issues/3325
+
+# 5.1.0 / 2018-04-12
+
+## :tada: Enhancements
+
+- [#3210]: Add `--exclude` option ([@metalex9])
+
+## :bug: Fixes
+
+- [#3318]: Fix failures in circular objects in JSON reporter ([@jeversmann], [@boneskull])
+
+## :book: Documentation
+
+- [#3323]: Publish actual [API documentation](https://mochajs.org/api/)! ([@dfberry], [@Munter])
+- [#3299]: Improve docs around exclusive tests ([@nicgirault])
+
+## :nut_and_bolt: Other
+
+- [#3302], [#3308], [#3310], [#3315], [#3316]: Build matrix improvements ([more info](https://boneskull.com/mocha-and-travis-ci-build-stages/)) ([@outsideris], [@boneskull])
+- [#3272]: Refactor reporter tests ([@jMuzsik])
+
+[#3210]: https://github.com/mochajs/mocha/pull/3210
+[#3318]: https://github.com/mochajs/mocha/pull/3318
+[#3323]: https://github.com/mochajs/mocha/pull/3323
+[#3299]: https://github.com/mochajs/mocha/pull/3299
+[#3302]: https://github.com/mochajs/mocha/pull/3302
+[#3308]: https://github.com/mochajs/mocha/pull/3308
+[#3310]: https://github.com/mochajs/mocha/pull/3310
+[#3315]: https://github.com/mochajs/mocha/pull/3315
+[#3316]: https://github.com/mochajs/mocha/pull/3316
+[#3272]: https://github.com/mochajs/mocha/pull/3272
+[@metalex9]: https://github.com/metalex9
+[@jeversmann]: https://github.com/jeversmann
+[@dfberry]: https://github.com/dfberry
+[@nicgirault]: https://github.com/nicgirault
+[@jMuzsik]: https://github.com/jMuzsik
+
+# 5.0.5 / 2018-03-22
+
+Welcome [@outsideris] to the team!
+
+## :bug: Fixes
+
+- [#3096]: Fix `--bail` failing to bail within hooks ([@outsideris])
+- [#3184]: Don't skip too many suites (using `describe.skip()`) ([@outsideris])
+
+## :book: Documentation
+
+- [#3133]: Improve docs regarding "pending" behavior ([@ematicipo])
+- [#3276], [#3274]: Fix broken stuff in `CHANGELOG.md` ([@tagoro9], [@honzajavorek])
+
+## :nut_and_bolt: Other
+
+- [#3208]: Improve test coverage for AMD users ([@outsideris])
+- [#3267]: Remove vestiges of PhantomJS from CI ([@anishkny])
+- [#2952]: Fix a debug message ([@boneskull])
+
+[#3096]: https://github.com/mochajs/mocha/issues/3096
+[#3184]: https://github.com/mochajs/mocha/issues/3184
+[#3133]: https://github.com/mochajs/mocha/issues/3133
+[#3276]: https://github.com/mochajs/mocha/pull/3276
+[#3274]: https://github.com/mochajs/mocha/pull/3274
+[#3208]: https://github.com/mochajs/mocha/issues/3208
+[#2952]: https://github.com/mochajs/mocha/issues/2952
+[#3267]: https://github.com/mochajs/mocha/pull/3267
+
+[@ematicipo]: https://github.com/ematicipo
+[@tagoro9]: https://github.com/tagoro9
+[@honzajavorek]: https://github.com/honajavorek
+[@anishkny]: https://github.com/anishkny
+
+# 5.0.4 / 2018-03-07
+
+## :bug: Fixes
+
+- [#3265]: Fixes regression in "watch" functionality introduced in v5.0.2 ([@outsideris])
+
+[#3265]: https://github.com/mochajs/mocha/issues/3265
+
+# 5.0.3 / 2018-03-06
+
+This patch features a fix to address a potential "low severity" [ReDoS vulnerability](https://snyk.io/vuln/npm:diff:20180305) in the [diff](https://npm.im/diff) package (a dependency of Mocha).
+
+## :lock: Security Fixes
+
+- [#3266]: Bump `diff` to v3.5.0 ([@anishkny])
+
+## :nut_and_bolt: Other
+
+- [#3011]: Expose `generateDiff()` in `Base` reporter ([@harrysarson])
+
+[#3266]: https://github.com/mochajs/mocha/pull/3266
+[#3011]: https://github.com/mochajs/mocha/issues/3011
+
+[@anishkny]: https://github.com/anishkny
+[@harrysarson]: https://github.com/harrysarson
+
+# 5.0.2 / 2018-03-05
+
+This release fixes a class of tests which report as *false positives*. **Certain tests will now break**, though they would have previously been reported as passing. Details below. Sorry for the inconvenience!
+
+## :bug: Fixes
+
+- [#3226]: Do not swallow errors that are thrown asynchronously from passing tests ([@boneskull]). Example:
+
+ ```js
+ it('should actually fail, sorry!', function (done) {
+ // passing assertion
+ assert(true === true);
+
+ // test complete & is marked as passing
+ done();
+
+ // ...but something evil lurks within
+ setTimeout(() => {
+ throw new Error('chaos!');
+ }, 100);
+ });
+ ```
+
+ Previously to this version, Mocha would have *silently swallowed* the `chaos!` exception, and you wouldn't know. Well, *now you know*. Mocha cannot recover from this gracefully, so it will exit with a nonzero code.
+
+ **Maintainers of external reporters**: *If* a test of this class is encountered, the `Runner` instance will emit the `end` event *twice*; you *may* need to change your reporter to use `runner.once('end')` intead of `runner.on('end')`.
+- [#3093]: Fix stack trace reformatting problem ([@outsideris])
+
+## :nut_and_bolt: Other
+
+- [#3248]: Update `browser-stdout` to v1.3.1 ([@honzajavorek])
+
+[#3248]: https://github.com/mochajs/mocha/issues/3248
+[#3226]: https://github.com/mochajs/mocha/issues/3226
+[#3093]: https://github.com/mochajs/mocha/issues/3093
+[@honzajavorek]: https://github.com/honzajavorek
+
+# 5.0.1 / 2018-02-07
+
+...your garden-variety patch release.
+
+Special thanks to [Wallaby.js](https://wallabyjs.com) for their continued support! :heart:
+
+## :bug: Fixes
+
+- [#1838]: `--delay` now works with `.only()` ([@silviom])
+- [#3119]: Plug memory leak present in v8 ([@boneskull])
+
+## :book: Documentation
+
+- [#3132], [#3098]: Update `--glob` docs ([@outsideris])
+- [#3212]: Update [Wallaby.js](https://wallabyjs.com)-related docs ([@ArtemGovorov])
+- [#3205]: Remove outdated cruft ([@boneskull])
+
+## :nut_and_bolt: Other
+
+- [#3224]: Add proper Wallaby.js config ([@ArtemGovorov])
+- [#3230]: Update copyright year ([@josephlin55555])
+
+[#1838]: https://github.com/mochajs/mocha/issues/1838
+[#3119]: https://github.com/mochajs/mocha/issues/3119
+[#3132]: https://github.com/mochajs/mocha/issues/3132
+[#3098]: https://github.com/mochajs/mocha/issues/3098
+[#3212]: https://github.com/mochajs/mocha/pull/3212
+[#3205]: https://github.com/mochajs/mocha/pull/3205
+[#3224]: https://github.com/mochajs/mocha/pull/3224
+[#3230]: https://github.com/mochajs/mocha/pull/3230
+[@silviom]: https://github.com/silviom
+[@outsideris]: https://github.com/outsideris
+[@ArtemGovorov]: https://github.com/ArtemGovorov
+[@josephlin55555]: https://github.com/josephlin55555
+
# 5.0.0 / 2018-01-17
Mocha starts off 2018 right by again dropping support for *unmaintained rubbish*.
@@ -41,7 +249,7 @@
[#3148]: https://github.com/mochajs/mocha/issues/3148
[#3181]: https://github.com/mochajs/mocha/issues/3181
[#3187]: https://github.com/mochajs/mocha/issues/3187
-[#3202]: https://github.com/mochajs/mocha/pull/3148
+[#3202]: https://github.com/mochajs/mocha/pull/3202
[#2352]: https://github.com/mochajs/mocha/issues/2352
[#3137]: https://github.com/mochajs/mocha/issues/3137
[#3134]: https://github.com/mochajs/mocha/issues/3134
@@ -252,9 +460,9 @@
- Various CI-and-test-related fixes and improvements ([@boneskull], [@dasilvacontin], [@PopradiArpad], [@Munter], [@ScottFreeCode])
- "Officially" support Node.js 8 ([@elergy])
-[#2860]: https://github.com/mochajs/mocha/pulls/2860
-[#2696]: https://github.com/mochajs/mocha/pulls/2696
-[#2813]: https://github.com/mochajs/mocha/pulls/2813
+[#2860]: https://github.com/mochajs/mocha/pull/2860
+[#2696]: https://github.com/mochajs/mocha/pull/2696
+[#2813]: https://github.com/mochajs/mocha/pull/2813
[@charlierudolph]: https://github.com/charlierudolph
[@PopradiArpad]: https://github.com/PopradiArpad
[@kungapal]: https://github.com/kungapal
@@ -276,7 +484,7 @@
[@makepanic]: https://github.com/makepanic
[@Munter]: https://github.com/Munter
-[#2778]: https://github.com/mochajs/mocha/pulls/2778
+[#2778]: https://github.com/mochajs/mocha/pull/2778
[#2802]: https://github.com/mochajs/mocha/issues/2802
[#2820]: https://github.com/mochajs/mocha/pull/2820

CHANGELOG.md.orig

@@ -1,1736 +0,0 @@
-<<<<<<< HEAD
-# 4.1.0 / 2017-12-28
-
-This is mainly a "housekeeping" release.
-
-Welcome [@Bamieh] and [@xxczaki] to the team!
-
-## :bug:: Fixes
-
-- [#2661]: `progress` reporter now accepts reporter options ([@canoztokmak])
-- [#3142]: `xit` in `bdd` interface now properly returns its `Test` object ([@Bamieh])
-- [#3075]: Diffs now computed eagerly to avoid misinformation when reported ([@abrady0])
-- [#2745]: `--help` will now help you even if you have a `mocha.opts` ([@Zarel])
-
-## :tada: Enhancements
-
-- [#2514]: The `--no-diff` flag will completely disable diff output ([@CapacitorSet])
-- [#3058]: All "setters" in Mocha's API are now also "getters" if called without arguments ([@makepanic])
-
-## :book: Documentation
-
-- [#3170]: Optimization and site speed improvements ([@Munter])
-- [#2987]: Moved the old [site repo](https://github.com/mochajs/mochajs.github.io) into the main repo under `docs/` ([@boneskull])
-- [#2896]: Add [maintainer guide](https://github.com/mochajs/mocha/blob/master/MAINTAINERS.md) ([@boneskull])
-- Various fixes and updates ([@xxczaki], [@maty21], [@leedm777])
-
-## :nut_and_bolt: Other
-
-- Test improvements and fixes ([@eugenet8k], [@ngeor], [@38elements], [@Gerhut], [@ScottFreeCode], [@boneskull])
-- Refactoring and cruft excision ([@38elements], [@Bamieh], [@finnigantime], [@boneskull])
-
-[#2661]: https://github.com/mochajs/mocha/issues/2661
-[#3142]: https://github.com/mochajs/mocha/issues/3142
-[#3075]: https://github.com/mochajs/mocha/pull/3075
-[#2745]: https://github.com/mochajs/mocha/issues/2745
-[#2514]: https://github.com/mochajs/mocha/issues/2514
-[#3058]: https://github.com/mochajs/mocha/issues/3058
-[#3170]: https://github.com/mochajs/mocha/pull/3170
-[#2987]: https://github.com/mochajs/mocha/issues/2987
-[#2896]: https://github.com/mochajs/mocha/issues/2896
-[@canoztokmak]: https://github.com/canoztokmak
-[@Bamieh]: https://github.com/Bamieh
-[@abrady0]: https://github.com/abrady0
-[@Zarel]: https://github.com/Zarel
-[@CapacitorSet]: https://github.com/CapacitorSet
-[@xxczaki]: https://github.com/xxczaki
-[@maty21]: https://github.com/maty21
-[@leedm777]: https://github.com/leedm777
-[@eugenet8k]: https://github.com/eugenet8k
-[@38elements]: https://github.com/38elements
-[@Gerhut]: https://github.com/Gerhut
-[@finnigantime]: https://github.com/finnigantime
-
-# 4.0.1 / 2017-10-05
-=======
-# Mocha Changelog
->>>>>>> lint all markdown files [ci skip]
-
-## 4.0.1 / 2017-10-05
-
-### :bug: Fixes
-
-- [#3051]: Upgrade Growl to v1.10.3 to fix its [peer dep problems](https://github.com/tj/node-growl/pull/68) ([@dpogue])
-
-[#3051]: https://github.com/mochajs/mocha/pull/3051
-[@dpogue]: https://github.com/dpogue
-
-## 4.0.0 / 2017-10-02
-
-You might want to read this before filing a new bug! :stuck_out_tongue_closed_eyes:
-
-### :boom: Breaking Changes
-
-For more info, please [read this article](https://boneskull.com/mocha-v4-nears-release/).
-
-#### Compatibility
-
-- [#3016]: Drop support for unmaintained versions of Node.js ([@boneskull]):
- - 0.10.x
- - 0.11.x
- - 0.12.x
- - iojs (any)
- - 5.x.x
-- [#2979]: Drop support for non-ES5-compliant browsers ([@boneskull]):
- - IE7
- - IE8
- - PhantomJS 1.x
-- [#2615]: Drop Bower support; old versions (3.x, etc.) will remain available ([@ScottFreeCode], [@boneskull])
-
-#### Default Behavior
-
-- [#2879]: By default, Mocha will no longer force the process to exit once all tests complete. This means any test code (or code under test) which would normally prevent `node` from exiting will do so when run in Mocha. Supply the `--exit` flag to revert to pre-v4.0.0 behavior ([@ScottFreeCode], [@boneskull])
-
-#### Reporter Output
-
-- [#2095]: Remove `stdout:` prefix from browser reporter logs ([@skeggse])
-- [#2295]: Add separator in "unified diff" output ([@olsonpm])
-- [#2686]: Print failure message when `--forbid-pending` or `--forbid-only` is specified ([@ScottFreeCode])
-- [#2814]: Indent contexts for better readability when reporting failures ([@charlierudolph])
-
-### :-1: Deprecations
-
-- [#2493]: The `--compilers` command-line option is now soft-deprecated and will emit a warning on `STDERR`. Read [this](https://github.com/mochajs/mocha/wiki/compilers-deprecation) for more info and workarounds ([@ScottFreeCode], [@boneskull])
-
-### :tada: Enhancements
-
-- [#2628]: Allow override of default test suite name in XUnit reporter ([@ngeor])
-
-### :book: Documentation
-
-- [#3020]: Link to CLA in `README.md` and `CONTRIBUTING.md` ([@skeggse])
-
-### :nut_and_bolt: Other
-
-- [#2890]: Speed up build by (re-)consolidating SauceLabs tests ([@boneskull])
-
-[#3016]: https://github.com/mochajs/mocha/issues/3016
-[#2979]: https://github.com/mochajs/mocha/issues/2979
-[#2615]: https://github.com/mochajs/mocha/issues/2615
-[#2879]: https://github.com/mochajs/mocha/issues/2879
-[#2095]: https://github.com/mochajs/mocha/issues/2095
-[#2295]: https://github.com/mochajs/mocha/issues/2295
-[#2686]: https://github.com/mochajs/mocha/issues/2686
-[#2814]: https://github.com/mochajs/mocha/pull/2814
-[#2493]: https://github.com/mochajs/mocha/issues/2493
-[#2628]: https://github.com/mochajs/mocha/issues/2628
-[#3020]: https://github.com/mochajs/mocha/pull/3020
-[#2890]: https://github.com/mochajs/mocha/issues/2890
-[@skeggse]: https://github.com/skeggse
-[@olsonpm]: https://github.com/olsonpm
-[@ngeor]: https://github.com/ngeor
-
-## 3.5.3 / 2017-09-11
-
-### :bug: Fixes
-
-- [#3003]: Fix invalid entities in xUnit reporter first appearing in v3.5.1 ([@jkrems])
-
-[#3003]: https://github.com/mochajs/mocha/pull/3003
-
-## 3.5.2 / 2017-09-10
-
-### :bug: Fixes
-
-- [#3001]: Fix AMD-related failures first appearing in v3.5.1 ([@boneskull])
-
-[#3001]: https://github.com/mochajs/mocha/pull/3001
-
-## 3.5.1 / 2017-09-09
-
-### :newspaper: News
-
-- :mega: Mocha is now sponsoring [PDXNode](http://pdxnode.org)! If you're in the [Portland](https://wikipedia.org/wiki/Portland,_Oregon) area, come check out the monthly talks and hack nights!
-
-### :bug: Fixes
-
-- [#2997]: Fix missing `xit` export for "require" interface ([@solodynamo])
-- [#2957]: Fix unicode character handling in XUnit reporter failures ([@jkrems])
-
-### :nut_and_bolt: Other
-
-- [#2986]: Add issue and PR templates ([@kungapal])
-- [#2918]: Drop bash dependency for glob-related tests ([@ScottFreeCode])
-- [#2922]: Improve `--compilers` coverage ([@ScottFreeCode])
-- [#2981]: Fix tpyos and spelling errors ([@jsoref])
-
-[#2997]: https://github.com/mochajs/mocha/pull/2997
-[#2957]: https://github.com/mochajs/mocha/pull/2957
-[#2918]: https://github.com/mochajs/mocha/pull/2918
-[#2986]: https://github.com/mochajs/mocha/pull/2986
-[#2922]: https://github.com/mochajs/mocha/pull/2922
-[#2981]: https://github.com/mochajs/mocha/pull/2981
-[@solodynamo]: https://github.com/solodynamo
-[@jkrems]: https://github.com/jkrems
-[@jsoref]: https://github.com/jsoref
-
-## 3.5.0 / 2017-07-31
-
-### :newspaper: News
-
-- Mocha now has a [code of conduct](https://github.com/mochajs/mocha/blob/master/.github/CODE_OF_CONDUCT.md) (thanks [@kungapal]!).
-- Old issues and PRs are now being marked "stale" by [Probot's "Stale" plugin](https://github.com/probot/stale). If an issue is marked as such, and you would like to see it remain open, simply add a new comment to the ticket or PR.
-- **WARNING**: Support for non-ES5-compliant environments will be dropped starting with version 4.0.0 of Mocha!
-
-### :lock: Security Fixes
-
-- [#2860]: Address [CVE-2015-8315](https://nodesecurity.io/advisories/46) via upgrade of [debug](https://npm.im/debug) ([@boneskull])
-
-### :tada: Enhancements
-
-- [#2696]: Add `--forbid-only` and `--forbid-pending` flags. Use these in CI or hooks to ensure tests aren't accidentally being skipped! ([@charlierudolph])
-- [#2813]: Support Node.js 8's `--napi-modules` flag ([@jupp0r])
-
-### :nut_and_bolt: Other
-
-- Various CI-and-test-related fixes and improvements ([@boneskull], [@dasilvacontin], [@PopradiArpad], [@Munter], [@ScottFreeCode])
-- "Officially" support Node.js 8 ([@elergy])
-
-[#2860]: https://github.com/mochajs/mocha/pulls/2860
-[#2696]: https://github.com/mochajs/mocha/pulls/2696
-[#2813]: https://github.com/mochajs/mocha/pulls/2813
-[@charlierudolph]: https://github.com/charlierudolph
-[@PopradiArpad]: https://github.com/PopradiArpad
-[@kungapal]: https://github.com/kungapal
-[@elergy]: https://github.com/elergy
-[@jupp0r]: https://github.com/jupp0r
-
-## 3.4.2 / 2017-05-24
-
-### :bug: Fixes
-
-- [#2802]: Remove call to deprecated `os.tmpDir` ([@makepanic])
-- [#2820]: Eagerly set `process.exitCode` ([@chrisleck])
-
-### :nut_and_bolt: Other
-
-- [#2778]: Move linting into an npm script ([@Munter])
-
-[@chrisleck]: https://github.com/chrisleck
-[@makepanic]: https://github.com/makepanic
-[@Munter]: https://github.com/Munter
-
-[#2778]: https://github.com/mochajs/mocha/pulls/2778
-[#2802]: https://github.com/mochajs/mocha/issues/2802
-[#2820]: https://github.com/mochajs/mocha/pull/2820
-
-## 3.4.1 / 2017-05-14
-
-Fixed a publishing mishap with git's autocrlf settings.
-
-## 3.4.0 / 2017-05-14
-
-Mocha is now moving to a quicker release schedule: when non-breaking changes are merged, a release should happen that week.
-
-This week's highlights:
-
-- `allowUncaught` added to commandline as `--allow-uncaught` (and bugfixed)
-- warning-related Node flags
-
-### :tada: Enhancements
-
-- [#2793], [#2697]: add --allowUncaught to Node.js ([@lrowe])
-- [#2733]: Add `--no-warnings` and `--trace-warnings` flags ([@sonicdoe])
-
-### :bug: Fixes
-
-- [#2793], [#2697]: fix broken allowUncaught ([@lrowe])
-
-### :nut_and_bolt: Other
-
-- [#2778]: Add license report and scan status ([@xizhao])
-- [#2794]: no special case for macOS running Karma locally ([@boneskull])
-- [#2795]: reverts use of semistandard directly ([#2648]) ([@boneskull])
-
-[@lrowe]: https://github.com/lrowe
-[@sonicdoe]: https://github.com/sonicdoe
-[@xizhao]: https://github.com/xizhao
-[@boneskull]: https://github.com/boneskull
-
-[#2795]: https://github.com/mochajs/mocha/pull/2795
-[#2733]: https://github.com/mochajs/mocha/pull/2733
-[#2793]: https://github.com/mochajs/mocha/pull/2793
-[#2697]: https://github.com/mochajs/mocha/pull/2697
-[#2778]: https://github.com/mochajs/mocha/pull/2778
-[#2794]: https://github.com/mochajs/mocha/pull/2794
-
-## 3.3.0 / 2017-04-24
-
-Thanks to all our contributors, maintainers, sponsors, and users! ❤️
-
-As highlights:
-
-- We've got coverage now!
-- Testing is looking less flaky \o/.
-- No more nitpicking about "mocha.js" build on PRs.
-
-### :tada: Enhancements
-
-- [#2659]: Adds support for loading reporter from an absolute or relative path ([@sul4bh])
-- [#2769]: Support `--inspect-brk` on command-line ([@igwejk])
-
-### :bug: Fixes
-
-- [#2662]: Replace unicode chars w/ hex codes in HTML reporter ([@rotemdan])
-
-### :mag: Coverage
-
-- [#2672]: Add coverage for node tests ([@c089], [@Munter])
-- [#2680]: Increase tests coverage for base reporter ([@epallerols])
-- [#2690]: Increase tests coverage for doc reporter ([@craigtaub])
-- [#2701]: Increase tests coverage for landing, min, tap and list reporters ([@craigtaub])
-- [#2691]: Increase tests coverage for spec + dot reporters ([@craigtaub])
-- [#2698]: Increase tests coverage for xunit reporter ([@craigtaub])
-- [#2699]: Increase tests coverage for json-stream, markdown and progress reporters ([@craigtaub])
-- [#2703]: Cover .some() function in utils.js with tests ([@seppevs])
-- [#2773]: Add tests for loading reporters w/ relative/absolute paths ([@sul4bh])
-
-### :nut_and_bolt: Other
-
-- Remove bin/.eslintrc; ensure execs are linted ([@boneskull])
-- [#2542]: Expand CONTRIBUTING.md ([@boneskull])
-- [#2660]: Double timeouts on integration tests ([@Munter])
-- [#2653]: Update copyright year ([@Scottkao85], [@Munter])
-- [#2621]: Update dependencies to enable Greenkeeper ([@boneskull], [@greenkeeper])
-- [#2625]: Use trusty container in travis-ci; use "artifacts" addon ([@boneskull])
-- [#2670]: doc(CONTRIBUTING): fix link to org members ([@coderbyheart])
-- Add Mocha propaganda to README.md ([@boneskull])
-- [#2470]: Avoid test flake in "delay" test ([@boneskull])
-- [#2675]: Limit browser concurrency on sauce ([@boneskull])
-- [#2669]: Use temporary test-only build of mocha.js for browsers tests ([@Munter])
-- Fix "projects" link in README.md ([@boneskull])
-- [#2678]: Chore(Saucelabs): test on IE9, IE10 and IE11 ([@coderbyheart])
-- [#2648]: Use `semistandard` directly ([@kt3k])
-- [#2727]: Make the build reproducible ([@lamby])
-
-[@boneskull]: https://github.com/boneskull
-[@c089]: https://github.com/c089
-[@coderbyheart]: https://github.com/coderbyheart
-[@craigtaub]: https://github.com/craigtaub
-[@epallerols]: https://github.com/epallerols
-[@greenkeeper]: https://github.com/greenkeeper
-[@igwejk]: https://github.com/igwejk
-[@kt3k]: https://github.com/kt3k
-[@lamby]: https://github.com/lamby
-[@Munter]: https://github.com/Munter
-[@rotemdan]: https://github.com/rotemdan
-[@seppevs]: https://github.com/seppevs
-[@sul4bh]: https://github.com/sul4bh
-
-[#2470]: https://github.com/mochajs/mocha/pull/2470
-[#2542]: https://github.com/mochajs/mocha/issues/2542
-[#2621]: https://github.com/mochajs/mocha/pull/2621
-[#2625]: https://github.com/mochajs/mocha/pull/2625
-[#2648]: https://github.com/mochajs/mocha/pull/2648
-[#2653]: https://github.com/mochajs/mocha/pull/2653
-[#2659]: https://github.com/mochajs/mocha/pull/2659
-[#2660]: https://github.com/mochajs/mocha/pull/2660
-[#2662]: https://github.com/mochajs/mocha/pull/2662
-[#2669]: https://github.com/mochajs/mocha/pull/2669
-[#2670]: https://github.com/mochajs/mocha/pull/2670
-[#2672]: https://github.com/mochajs/mocha/pull/2672
-[#2675]: https://github.com/mochajs/mocha/pull/2675
-[#2678]: https://github.com/mochajs/mocha/pull/2678
-[#2680]: https://github.com/mochajs/mocha/pull/2680
-[#2690]: https://github.com/mochajs/mocha/pull/2690
-[#2691]: https://github.com/mochajs/mocha/pull/2691
-[#2698]: https://github.com/mochajs/mocha/pull/2698
-[#2699]: https://github.com/mochajs/mocha/pull/2699
-[#2701]: https://github.com/mochajs/mocha/pull/2701
-[#2703]: https://github.com/mochajs/mocha/pull/2703
-[#2727]: https://github.com/mochajs/mocha/pull/2727
-[#2769]: https://github.com/mochajs/mocha/pull/2769
-[#2773]: https://github.com/mochajs/mocha/pull/2773
-
-## 3.2.0 / 2016-11-24
-
-### :newspaper: News
-
-#### Mocha is now a JS Foundation Project!
-
-Mocha is proud to have joined the [JS Foundation](https://js.foundation). For more information, [read the announcement](https://js.foundation/announcements/2016/10/17/Linux-Foundation-Unites-JavaScript-Community-Open-Web-Development/).
-
-#### Contributor License Agreement
-
-Under the foundation, all contributors to Mocha must sign the [JS Foundation CLA](https://js.foundation/CLA/) before their code can be merged. When sending a PR--if you have not already signed the CLA--a friendly bot will ask you to do so.
-
-Mocha remains licensed under the [MIT license](https://github.com/mochajs/mocha/blob/master/LICENSE).
-
-### :bug: Bug Fix
-
-- [#2535]: Fix crash when `--watch` encounters broken symlinks ([@villesau])
-- [#2593]: Fix (old) regression; incorrect symbol shown in `list` reporter ([@Aldaviva])
-- [#2584]: Fix potential error when running XUnit reporter ([@vobujs])
-
-### :tada: Enhancement
-
-- [#2294]: Improve timeout error messaging ([@jeversmann], [@boneskull])
-- [#2520]: Add info about `--inspect` flag to CLI help ([@ughitsaaron])
-
-### :nut_and_bolt: Other
-
-- [#2570]: Use [karma-mocha](https://npmjs.com/package/karma-mocha) proper ([@boneskull])
-- Licenses updated to reflect new copyright, add link to license and browser matrix to `README.md` ([@boneskull], [@ScottFreeCode], [@dasilvacontin])
-
-[#2294]: https://github.com/mochajs/mocha/issues/2294
-[#2535]: https://github.com/mochajs/mocha/issues/2535
-[#2520]: https://github.com/mochajs/mocha/pull/2520
-[#2593]: https://github.com/mochajs/mocha/pull/2593
-[#2584]: https://github.com/mochajs/mocha/issues/2584
-[#2570]: https://github.com/mochajs/mocha/issues/2570
-[@Aldaviva]: https://github.com/Aldaviva
-[@jeversmann]: https://github.com/jeversmann
-[@ughitsaaron]: https://github.com/ughitsaaron
-[@villesau]: https://github.com/villesau
-[@vobujs]: https://github.com/vobujs
-
-Thanks to all our contributors, sponsors and backers! Keep on the lookout for a public roadmap and new contribution guide coming soon.
-
-## 3.1.2 / 2016-10-10
-
-### :bug: Bug Fix
-
-- [#2528]: Recovery gracefully if an `Error`'s `stack` property isn't writable ([@boneskull])
-
-[#2528]: https://github.com/mochajs/mocha/issues/2528
-
-## 3.1.1 / 2016-10-09
-
-### :bug: Bug Fix
-
-- [#1417]: Don't report `done()` was called multiple times when it wasn't ([@frankleonrose])
-
-### :nut_and_bolt: Other
-
-- [#2490]: Lint with [semistandard](https://npmjs.com/package/semistandard) config ([@makepanic])
-- [#2525]: Lint all `.js` files ([@boneskull])
-- [#2524]: Provide workaround for developers unable to run browser tests on macOS Sierra ([@boneskull])
-
-[#1417]: https://github.com/mochajs/mocha/issues/1417
-[#2490]: https://github.com/mochajs/mocha/issues/2490
-[#2525]: https://github.com/mochajs/mocha/issues/2525
-[#2524]: https://github.com/mochajs/mocha/issues/2524
-[@makepanic]: https://github.com/makepanic
-[@frankleonrose]: https://github.com/frankleonrose
-
-## 3.1.0 / 2016-09-27
-
-### :tada: Enhancement
-
-- [#2357]: Support `--inspect` on command-line ([@simov])
-- [#2194]: Human-friendly error if no files are matched on command-line ([@Munter])
-- [#1744]: Human-friendly error if a Suite has no callback (BDD/TDD only) ([@anton])
-
-### :bug: Bug Fix
-
-- [#2488]: Fix case in which *variables beginning with lowercase "D"* may not have been reported properly as global leaks ([@JustATrick]) :laughing:
-- [#2465]: Always halt execution in async function when `this.skip()` is called ([@boneskull])
-- [#2445]: Exits with expected code 130 when `SIGINT` encountered; exit code can no longer rollover at 256 ([@Munter])
-- [#2315]: Fix uncaught TypeError thrown from callback stack ([@1999])
-- Fix broken `only()`/`skip()` in IE7/IE8 ([@boneskull])
-- [#2502]: Fix broken stack trace filter on Node.js under Windows ([@boneskull])
-- [#2496]: Fix diff output for objects instantiated with `String` constructor ([more](https://youtrack.jetbrains.com/issue/WEB-23383)) ([@boneskull])
-
-[#2496]: https://github.com/mochajs/mocha/issues/2496
-[#2502]: https://github.com/mochajs/mocha/issues/2502
-[#2315]: https://github.com/mochajs/mocha/issues/2315
-[#2445]: https://github.com/mochajs/mocha/pull/2445
-[#2465]: https://github.com/mochajs/mocha/issues/2465
-[#2488]: https://github.com/mochajs/mocha/issues/2488
-[#1744]: https://github.com/mochajs/mocha/issues/1744
-[#2194]: https://github.com/mochajs/mocha/issues/2194
-[#2357]: https://github.com/mochajs/mocha/issues/2357
-[@1999]: https://github.com/1999
-[@JustATrick]: https://github.com/JustATrick
-[@anton]: https://github.com/anton
-[@simov]: https://github.com/simov
-
-## 3.0.2 / 2016-08-08
-
-### :bug: Bug Fix
-
-- [#2424]: Fix error loading Mocha via Require.js ([@boneskull])
-- [#2417]: Fix execution of *deeply* nested `describe.only()` suites ([@not-an-aardvark])
-- Remove references to `json-cov` and `html-cov` reporters in CLI ([@boneskull])
-
-[#2417]: https://github.com/mochajs/mocha/issues/2417
-[#2424]: https://github.com/mochajs/mocha/issues/2424
-
-## 3.0.1 / 2016-08-03
-
-### :bug: Bug Fix
-
-- [#2406]: Restore execution of nested `describe.only()` suites ([@not-an-aardvark])
-
-[#2406]: https://github.com/mochajs/mocha/issues/2406
-[@not-an-aardvark]: https://github.com/not-an-aardvark
-
-## 3.0.0 / 2016-07-31
-
-### :boom: Breaking Changes
-
-- :warning: Due to the increasing difficulty of applying security patches made within its dependency tree, as well as looming incompatibilities with Node.js v7.0, **Mocha no longer supports Node.js v0.8**.
-- :warning: **Mocha may no longer be installed by versions of `npm` less than `1.4.0`.** Previously, this requirement only affected Mocha's development dependencies. In short, this allows Mocha to depend on packages which have dependencies fixed to major versions (`^`).
-- `.only()` is no longer "fuzzy", can be used multiple times, and generally just works like you think it should. :joy:
-- To avoid common bugs, when a test injects a callback function (suggesting asynchronous execution), calls it, *and* returns a `Promise`, Mocha will now throw an exception:
-
- ```js
- const assert = require('assert');
-
- it('should complete this test', function (done) {
- return new Promise(function (resolve) {
- assert.ok(true);
- resolve();
- })
- .then(done);
- });
- ```
-
- The above test will fail with `Error: Resolution method is overspecified. Specify a callback *or* return a Promise; not both.`.
-- When a test timeout value *greater than* `2147483648` is specified in any context (`--timeout`, `mocha.setup()`, per-suite, per-test, etc.), the timeout will be *disabled* and the test(s) will be allowed to run indefinitely. This is equivalent to specifying a timeout value of `0`. See [MDN](https://developer.mozilla.org/docs/Web/API/WindowTimers/setTimeout#Maximum_delay_value) for reasoning.
-- The `dot` reporter now uses more visually distinctive characters when indicating "pending" and "failed" tests.
-- Mocha no longer supports [component](https://www.npmjs.com/package/component).
-- The long-forsaken `HTMLCov` and `JSONCov` reporters--and any relationship to the "node-jscoverage" project--have been removed.
-- `spec` reporter now omits leading carriage returns (`\r`) in non-TTY environment.
-
-### :tada: Enhancements
-
-- [#808]: Allow regular-expression-like strings in `--grep` and browser's `grep` querystring; enables flags such as `i` for case-insensitive matches and `u` for unicode. ([@a8m])
-- [#2000]: Use distinctive characters in `dot` reporter; `,` will denote a "pending" test and `!` will denote a "failing" test. ([@elliottcable])
-- [#1632]: Throw a useful exception when a suite or test lacks a title. ([@a8m])
-- [#1481]: Better `.only()` behavior. ([@a8m])
-- [#2334]: Allow `this.skip()` in async tests and hooks. ([@boneskull])
-- [#1320]: Throw a useful exception when test resolution method is overspecified. ([@jugglinmike])
-- [#2364]: Support `--preserve-symlinks`. ([@rosswarren])
-
-### :bug: Bug Fixes
-
-- [#2259]: Restore ES3 compatibility. Specifically, support an environment lacking `Date.prototype.toISOString()`, `JSON`, or has a non-standard implementation of `JSON`. ([@ndhoule], [@boneskull])
-- [#2286]: Fix `after()` failing to execute if test skipped using `this.skip()` in `beforeEach()`; no longer marks the entire suite as "pending". ([@dasilvacontin], [@boneskull])
-- [#2208]: Fix function name display in `markdown` and `html` (browser) reporters. ([@ScottFreeCode])
-- [#2299]: Fix progress bar in `html` (browser) reporter. ([@AviVahl])
-- [#2307]: Fix `doc` reporter crashing when test fails. ([@jleyba])
-- [#2323]: Ensure browser entry point (`browser-entry.js`) is published to npm (for use with bundlers). ([@boneskull])
-- [#2310]: Ensure custom reporter with an absolute path works in Windows. ([@silentcloud])
-- [#2311]: Fix problem wherein calling `this.slow()` without a value would blast any previously set value. ([@boneskull])
-- [#1813]: Ensure Mocha's own test suite will run in Windows. ([@tswaters], [@TimothyGu], [@boneskull])
-- [#2317]: Ensure all interfaces are displayed in `--help` on CLI. ([@ScottFreeCode])
-- [#1644]: Don't exhibit undefined behavior when calling `this.timeout()` with very large values ([@callumacrae], [@boneskull])
-- [#2361]: Don't truncate name of thrown anonymous exception. ([@boneskull])
-- [#2367]: Fix invalid CSS. ([@bensontrent])
-- [#2401]: Remove carriage return before each test line in spec reporter. ([@Munter])
-
-### :nut_and_bolt: Other
-
-- Upgrade production dependencies to address security advisories (and because now we can): `glob`, `commander`, `escape-string-regexp`, and `supports-color`. ([@boneskull], [@RobLoach])
-- Add Windows to CI. ([@boneskull], [@TimothyGu])
-- Ensure appropriate `engines` field in `package.json`. ([@shinnn], [@boneskull])
-- [#2348]: Upgrade ESLint to v2 ([@anthony-redfox])
-
-We :heart: our [backers and sponsors](https://opencollective.com/mochajs)!
-
-:shipit:
-
-[#2401]: https://github.com/mochajs/mocha/pull/2401
-[#2348]: https://github.com/mochajs/mocha/issues/2348
-[#808]: https://github.com/mochajs/mocha/issues/808
-[#2361]: https://github.com/mochajs/mocha/pull/2361
-[#2367]: https://github.com/mochajs/mocha/pull/2367
-[#2364]: https://github.com/mochajs/mocha/pull/2364
-[#1320]: https://github.com/mochajs/mocha/pull/1320
-[#2307]: https://github.com/mochajs/mocha/pull/2307
-[#2259]: https://github.com/mochajs/mocha/pull/2259
-[#2208]: https://github.com/mochajs/mocha/pull/2208
-[#2299]: https://github.com/mochajs/mocha/pull/2299
-[#2286]: https://github.com/mochajs/mocha/issues/2286
-[#1644]: https://github.com/mochajs/mocha/issues/1644
-[#2310]: https://github.com/mochajs/mocha/issues/2310
-[#2311]: https://github.com/mochajs/mocha/issues/2311
-[#2323]: https://github.com/mochajs/mocha/issues/2323
-[#2000]: https://github.com/mochajs/mocha/pull/2000
-[#1632]: https://github.com/mochajs/mocha/issues/1632
-[#1813]: https://github.com/mochajs/mocha/issues/1813
-[#2334]: https://github.com/mochajs/mocha/issues/2334
-[#2317]: https://github.com/mochajs/mocha/issues/2317
-[#1481]: https://github.com/mochajs/mocha/issues/1481
-[@elliottcable]: https://github.com/elliottcable
-[@RobLoach]: https://github.com/robloach
-[@AviVahl]: https://github.com/avivahl
-[@silentcloud]: https://github.com/silentcloud
-[@tswaters]: https://github.com/tswaters
-[@jleyba]: https://github.com/jleyba
-[@TimothyGu]: https://github.com/timothygu
-[@callumacrae]: https://github.com/callumacrae
-[@shinnn]: https://github.com/shinnn
-[@bensontrent]: https://github.com/bensontrent
-[@jugglinmike]: https://github.com/jugglinmike
-[@rosswarren]: https://github.com/rosswarren
-[@anthony-redfox]: https://github.com/anthony-redfox
-[@Munter]: https://github.com/munter
-
-## 2.5.3 / 2016-05-25
-
-- [#2112] - Fix HTML reporter regression causing duplicate error output ([@danielstjules] via 6d24063)
-- [#2119] - Make HTML reporter failure/passed links preventDefault to avoid SPA's hash navigation ([@jimenglish81] via 9e93efc)
-
-[@danielstjules]: https://github.com/danielstjules
-[@jimenglish81]: https://github.com/jimenglish81
-[#2112]: https://github.com/mochajs/mocha/pull/2112
-[#2119]: https://github.com/mochajs/mocha/pull/2119
-
-## 2.5.2 / 2016-05-24
-
-- [#2178] - Avoid double and triple xUnit XML escaping ([@graingert] via 49b5ff1)
-
-[@graingert]: https://github.com/graingert
-[#2178]: https://github.com/mochajs/mocha/pull/2178
-
-## 2.5.1 / 2016-05-23
-
-- Fix [to-iso-string](https://npmjs.com/package/to-iso-string) dependency ([@boneskull] via bd9450b)
-
-Thanks @entertainyou, @SimenB, @just-paja for the heads-up.
-
-## 2.5.0 / 2016-05-23
-
-This has been awhile coming! We needed to feel confident that the next release wouldn't break browser compatibility (e.g. the last few patch releases).
-
-### Browser Tests in CI
-
-We now run unit tests against PhantomJS v1.x and an assortment of browsers on [SauceLabs](https://saucelabs.com), including:
-
-- Internet Explorer v8.0
-- Chrome (latest)
-- Firefox (latest)
-- Safari (latest)
-- Microsoft Edge (latest)
-
-To accomplish this, we now run Mocha's unit tests (and a handful of integration tests) via [Karma](https://npmjs.com/package/karma) and a modified [karma-mocha](https://npmjs.com/package/karma-mocha). Along the way, we had to solve issue [#880] (apologies to @mderijcke and @sukima who had PRs addressing this), as well as replace most usages of [should](https://npmjs.com/package/should) with [expect.js](https://npmjs.com/package/expect.js) for IE8.
-
-Going forward, when sending PRs, your code will *only* run against PhantomJS v1.x (and not hit SauceLabs) [because security](https://docs.travis-ci.com/user/pull-requests/#Security-Restrictions-when-testing-Pull-Requests).
-
-### Node.js 6.x
-
- Node.js 6.x "just worked" before, but now it's in the CI matrix, so it's "officially" supported. Mocha *still retains support* for Node.js 0.8.x.
-
-### "Minor" Release
-
-You'll see mostly bug fixes below, but also a couple features--as such, it's a "minor" release.
-
-### TYVM
-
-Thanks to everyone who contributed, and our fabulous [sponsors and backers](https://opencollective.com/mochajs)!
-
-- [#2079] - Add browser checks to CI; update [browserify](https://npmjs.com/package/browserify) to v13.0.0 ([@dasilvacontin], [@ScottFreeCode], [@boneskull] via c04c1d7, 0b1e9b3, 0dde0fa, f8a3d86, 9e8cbaa)
-- [#880] - Make Mocha browserifyable ([@boneskull] via 524862b)
-- [#2121] - Update [glob](https://npmjs.com/package/glob) to v3.2.11 ([@astorije] via 7920fc4)
-- [#2126] - Fix dupe error messages in stack trace filter ([@Turbo87] via 4301caa)
-- [#2109] - Fix certain diffs when objects cannot be coerced into primitives ([@joshlory] via 61fbb7f)
-- [#1827] - Fix TWBS/`mocha.css` collisions ([@irnc] via 0543798)
-- [#1760], [#1936] - Fix `this.skip()` in HTML reporter ([@mislav] via cb4248b)
-- [#2115] - Fix exceptions thrown from hooks in HTML reporter ([@danielstjules] via e290bc0)
-- [#2089] - Handle Symbol values in `util.stringify()` ([@ryym] via ea61d05)
-- [#2097] - Fix diff for objects overriding `Object.prototype.hasOwnProperty` ([@mantoni] via b20fdfe)
-- [#2101] - Properly handle non-string "messages" thrown from assertion libraries ([@jkimbo] via 9c41051)
-- [#2124] - Update [growl](https://npmjs.com/package/growl) ([@benjamine] via 9ae6a85)
-- [#2162], [#2205] - JSDoc fixes ([@OlegTsyba] via 8031f20, [@ScottFreeCode] via f83b1d9)
-- [#2132] - Remove Growl-related cruft ([@julienw] via 00d6469)
-- [#2172] - Add [OpenCollective](https://opencollective.com) badge, sponsors & backers ([@xdamman], [@boneskull] via caee94f)
-- [#1841] - Add new logo, banner assets ([@dasilvacontin] via 00fd0e1)
-- [#2214] - Update `README.md` header ([@dasilvacontin] via c0f9be2)
-- [#2236] - Better checks for Node.js v0.8 compatibility in CI ([@dasilvacontin] via ba5637d)
-- [#2239] - Add Node.js v6.x to CI matrix ([@boneskull] via 3904da4)
-
-[#880]: https://github.com/mochajs/mocha/issues/880
-[#1841]: https://github.com/mochajs/mocha/pull/1841
-[#2239]: https://github.com/mochajs/mocha/issues/2239
-[#2153]: https://github.com/mochajs/mocha/pull/2153
-[#2214]: https://github.com/mochajs/mocha/pull/2214
-[#2236]: https://github.com/mochajs/mocha/pull/2236
-[#2079]: https://github.com/mochajs/mocha/issues/2079
-[#2231]: https://github.com/mochajs/mocha/pull/2231
-[#2089]: https://github.com/mochajs/mocha/issues/2089
-[#2097]: https://github.com/mochajs/mocha/pull/2097
-[#1760]: https://github.com/mochajs/mocha/issues/1760
-[#1936]: https://github.com/mochajs/mocha/issues/1936
-[#2115]: https://github.com/mochajs/mocha/pull/2115
-[#1827]: https://github.com/mochajs/mocha/pull/1827
-[#2101]: https://github.com/mochajs/mocha/pull/2101
-[#2124]: https://github.com/mochajs/mocha/pull/2124
-[#2109]: https://github.com/mochajs/mocha/issues/2109
-[#2162]: https://github.com/mochajs/mocha/pull/2162
-[#2132]: https://github.com/mochajs/mocha/issues/2132
-[#2126]: https://github.com/mochajs/mocha/issues/2126
-[#2121]: https://github.com/mochajs/mocha/issues/2121
-[#2205]: https://github.com/mochajs/mocha/pull/2205
-[#2172]: https://github.com/mochajs/mocha/pull/2172
-[@xdamman]: https://github.com/xdamman
-[@Turbo87]: https://github.com/Turbo87
-[@OlegTsyba]: https://github.com/OlegTsyba
-[@ryym]: https://github.com/ryym
-[@mantoni]: https://github.com/mantoni
-[@mislav]: https://github.com/mislav
-[@irnc]: https://github.com/irnc
-[@jkimbo]: https://github.com/jkimbo
-[@benjamine]: https://github.com/benjamine
-[@joshlory]: https://github.com/joshlory
-[@julienw]: https://github.com/julienw
-[@ScottFreeCode]: https://github.com/ScottFreeCode
-[@astorije]: https://github.com/astorije
-[@dasilvacontin]: https://github.com/dasilvacontin
-
-## 2.4.5 / 2016-01-28
-
-- [#2080], [#2078], [#2072], [#2073], [#1200] - Revert changes to console colors in changeset [1192914](https://github.com/mochajs/mocha/commit/119291449cd03a11cdeda9e37cf718a69a012896) and subsequent related changes thereafter. Restores compatibility with IE8 & PhantomJS. See also [mantoni/mochify.js#129](https://github.com/mantoni/mochify.js/issues/129) and [openlayers/ol3#4746](https://github.com/openlayers/ol3/pull/4746) ([@boneskull])
-- [#2082] - Fix several test assertions ([@mislav])
-
-[#1200]: https://github.com/mochajs/mocha/issues/1200
-[#2082]: https://github.com/mochajs/mocha/pull/2082
-
-## 2.4.4 / 2016-01-27
-
-- [#2080] - Fix broken RequireJS compatibility ([@boneskull])
-
-[#2080]: https://github.com/mochajs/mocha/issues/2080
-
-## 2.4.3 / 2016-01-27
-
-- [#2078] - Fix broken IE8 ([@boneskull])
-
-[#2078]: https://github.com/mochajs/mocha/issues/2078
-
-## 2.4.2 / 2016-01-26
-
-- [#2053] - Fix web worker compatibility ([@mislav])
-- [#2072] - Fix Windows color output ([@thedark1337])
-- [#2073] - Fix colors in `progress` and `landing` reporters ([@gyandeeps])
-
-[#2053]: https://github.com/mochajs/mocha/pull/2053
-[#2072]: https://github.com/mochajs/mocha/pull/2072
-[#2073]: https://github.com/mochajs/mocha/pull/2073
-[@gyandeeps]: https://github.com/gyandeeps
-[@thedark1337]: https://github.com/thedark1337
-
-## 2.4.1 / 2016-01-26
-
-- [#2067] - Fix HTML/doc reporter regressions ([@danielstjules])
-
-[#2067]: https://github.com/mochajs/mocha/pull/2067
-
-## 2.4.0 / 2016-01-25
-
-- [#1945] - Correctly skip tests when skipping in suite's before() ([@ryanshawty])
-- [#2056] - chore(license): update license year to 2016 ([@pra85])
-- [#2048] - Fix `this.skip` from spec with HTML reporter ([@mislav])
-- [#2033] - Update tests for newer versions of should.js ([@tomhughes])
-- [#2037] - Fix for memory leak caused by referenced to deferred test ([@bd82])
-- [#2038] - Also run Travis-CI on node.js 4 & 5 ([@bd82])
-- [#2028] - Remove reference to test before afterAll hook runs ([@stonelgh])
-- Bump mkdirp to 0.5.1 to support strict mode ([@danielstjules])
-- [#1977] - safely stringify PhantomJS undefined value ([@ahamid])
-- Add the ability to retry tests ([@@longlho])
-- [#1982] - Enable --log-timer-events option [@Alaneor]
-- Fix #1980: Load mocha.opts from bin/mocha and bin/_mocha ([@danielstjules])
-- [#1976] - Simplify function call ([@iclanzan])
-- [#1963] - Add support --perf-basic-prof ([@robraux])
-- [#1981] - Fix HTML reporter handling of done and exceptions ([@Standard8])
-- [#1993] - propagate "file" property for "exports" interface ([@segrey])
-- [#1999] - Add support for strict mode ([@tmont])
-- [#2005] - XUnit Reporter Writes to stdout, falls back to console.log ([@jonnyreeves])
-- [#2021] - Fix non ES5 compliant regexp ([@zetaben])
-- [#1965] - Don't double install BDD UI ([@cowboyd])
-- [#1995] - Make sure the xunit output dir exists before writing to it ([@ianwremmel])
-- Use chalk for the base reporter colors; closes #1200 ([@boneskull])
-- Fix requiring custom interfaces ([@jgkim])
-- [#1967] Silence Bluebird js warnings ([@krisr])
-
-[#1945]: https://github.com/mochajs/mocha/pull/1945
-[#2056]: https://github.com/mochajs/mocha/pull/2056
-[#2048]: https://github.com/mochajs/mocha/pull/2048
-[#2033]: https://github.com/mochajs/mocha/pull/2033
-[#2037]: https://github.com/mochajs/mocha/pull/2037
-[#2038]: https://github.com/mochajs/mocha/pull/2038
-[#2028]: https://github.com/mochajs/mocha/pull/2028
-[#1977]: https://github.com/mochajs/mocha/pull/1977
-[#1982]: https://github.com/mochajs/mocha/pull/1982
-[#1976]: https://github.com/mochajs/mocha/pull/1976
-[#1963]: https://github.com/mochajs/mocha/pull/1963
-[#1981]: https://github.com/mochajs/mocha/pull/1981
-[#1993]: https://github.com/mochajs/mocha/pull/1993
-[#1999]: https://github.com/mochajs/mocha/pull/1999
-[#2005]: https://github.com/mochajs/mocha/pull/2005
-[#2021]: https://github.com/mochajs/mocha/pull/2021
-[1965#]: https://github.com/mochajs/mocha/pull/1965
-[#1995]: https://github.com/mochajs/mocha/pull/1995
-[#1967]: https://github.com/mochajs/mocha/pull/1967
-[@ryanshawty]: https://github.com/ryanshawty
-[@pra85]: https://github.com/pra85
-[@mislav]: https://github.com/mislav
-[@tomhughes]: https://github.com/tomhughes
-[@bd82]: https://github.com/bd82
-[@stonelgh]: https://github.com/stonelgh
-[@danielstjules]: https://github.com/danielstjules
-[@ahamid]: https://github.com/ahamid
-[@longlho]: https://github.com/longlho
-[@Alaneor]: https://github.com/Alaneor
-[@iclanzan]: https://github.com/iclanzan
-[@robraux]: https://github.com/robraux
-[@Standard8]: https://github.com/Standard8
-[@segrey]: https://github.com/segrey
-[@tmont]: https://github.com/tmont
-[@jonnyreeves]: https://github.com/jonnyreeves
-[@zetaben]: https://github.com/zetaben
-[@cowboyd]: https://github.com/cowboyd
-[@ianwremmel]: https://github.com/ianwremmel
-[@boneskull]: https://github.com/boneskull
-[@jgkim]: https://github.com/jgkim
-[@krisr]: https://github.com/krisr
-
-## 2.3.4 / 2015-11-15
-
-- Update debug dependency to 2.2.0
-- remove duplication of mocha.opts on process.argv
-- Fix typo in test/reporters/nyan.js
-
-## 2.3.3 / 2015-09-19
-
-- [#1875] - Fix Markdown reporter exceeds maximum call stack size ([@danielstjules])
-- [#1864] - Fix xunit missing output with --reporter-options output ([@danielstjules])
-- [#1846] - Support all harmony flags ([@danielstjules])
-- Fix fragile xunit reporter spec ([@danielstjules])
-- [#1669] - Fix catch uncaught errors outside test suite execution ([@danielstjules])
-- [#1868] - Revert jade to support npm < v1.3.7 ([@danielstjules])
-- [#1766] - Don't remove modules/components from stack trace in the browser ([@danielstjules])
-- [#1798] - Fix correctly attribute mutiple done err with hooks ([@danielstjules])
-- Fix use utils.reduce for IE8 compatibility ([@wsw0108])
-- Some linting errors fixed by [@danielstjules]
-- Call the inspect() function if message is not set ([@kevinburke])
-
-[#1875]: https://github.com/mochajs/mocha/issues/1875
-[#1864]: https://github.com/mochajs/mocha/issues/1864
-[#1846]: https://github.com/mochajs/mocha/issues/1846
-[#1669]: https://github.com/mochajs/mocha/issues/1669
-[#1868]: https://github.com/mochajs/mocha/issues/1868
-[#1766]: https://github.com/mochajs/mocha/issues/1766
-[#1798]: https://github.com/mochajs/mocha/issues/1798
-[@danielstjules]: https://github.com/danielstjules
-[@wsw0108]: https://github.com/wsw0108
-[@kevinburke]: https://github.com/kevinburke
-
-## 2.3.2 / 2015-09-07
-
-- [#1868] - Fix compatibility with older versions of NPM ([@boneskull])
-
-[#1868]: https://github.com/mochajs/mocha/issues/1868
-
-## 2.3.1 / 2015-09-06
-
-- [#1812] - Fix: Bail flag causes before() hooks to be run even after a failure ([@aaroncrows])
-
-[#1812]: https://github.com/mochajs/mocha/issues/1812
-[aaroncrows]: https://github.com/aaroncrows
-
-## 2.3.0 / 2015-08-30
-
-- [#553] - added --allowUncaught option ([@amsul])
-- [#1490] - Allow --async-only to be satisfied by returning a promise ([@jlai])
-- [#1829] - support --max-old-space-size ([@gigadude])
-- [#1811] - upgrade Jade dependency ([@outsideris])
-- [#1769] - Fix async hook error handling ([@ajaykodali])
-- [#1230] - More descriptive beforeEach/afterEach messages ([@duncanbeevers])
-- [#1787] - Scope loading behaviour instead of using early return ([@aryeguy])
-- [#1789] - Fix: html-runner crashing ([@sunesimonsen])
-- [#1749] - Fix maximum call stack error on large amount of tests ([@tinganho])
-- [#1230] - Decorate failed hook titles with test title ([@duncanbeevers])
-- [#1260] - Build using Browserify ([@ndhoule])
-- [#1728] - Don't use `__proto__` ([@ndhoule])
-- [#1781] - Fix hook error tests ([@glenjamin])
-- [#1754] - Allow boolean --reporter-options ([@papandreou])
-- [#1766] - Fix overly aggressive stack suppression ([@moll])
-- [#1752] - Avoid potential infinite loop ([@gsilk])
-- [#1761] - Fix problems running under PhantomJS ([@chromakode])
-- [#1700] - Fix more problems running under PhantomJS ([@jbnicolai])
-- [#1774] - Support escaped spaces in CLI options ([@adamgruber])
-- [#1687] - Fix HTML reporter links with special chars ([@benvinegar])
-- [#1359] - Adopt code style and enforce it using ESLint ([@ndhoule] w/ assist from [@jbnicolai] & [@boneskull])
-- various refactors ([@jbnicolai])
-- [#1758] - Add cross-frame compatible Error checking ([@outdooricon])
-- [#1741] - Remove moot `version` property from bower.json ([@kkirsche])
-- [#1739] - Improve `HISTORY.md` ([@rstacruz])
-- [#1730] - Support more io.js flags ([@ryedog])
-- [#1349] - Allow HTML in HTML reporter errors ([@papandreou] / [@sunesimonsen])
-- [#1572] - Prevent default browser behavior for failure/pass links ([@jschilli])
-- [#1630] - Support underscored harmony flags ([@dominicbarnes])
-- [#1718] - Support more harmony flags ([@slyg])
-- [#1689] - Add stack to JSON-stream reporter ([@jonathandelgado])
-- [#1654] - Fix `ReferenceError` "location is not defined" ([@jakemmarsh])
-
-[#553]: https://github.com/mochajs/mocha/issues/553
-[#1490]: https://github.com/mochajs/mocha/issues/1490
-[#1829]: https://github.com/mochajs/mocha/issues/1829
-[#1811]: https://github.com/mochajs/mocha/issues/1811
-[#1769]: https://github.com/mochajs/mocha/issues/1769
-[#1230]: https://github.com/mochajs/mocha/issues/1230
-[#1787]: https://github.com/mochajs/mocha/issues/1787
-[#1789]: https://github.com/mochajs/mocha/issues/1789
-[#1749]: https://github.com/mochajs/mocha/issues/1749
-[#1230]: https://github.com/mochajs/mocha/issues/1230
-[#1260]: https://github.com/mochajs/mocha/issues/1260
-[#1728]: https://github.com/mochajs/mocha/issues/1728
-[#1781]: https://github.com/mochajs/mocha/issues/1781
-[#1754]: https://github.com/mochajs/mocha/issues/1754
-[#1766]: https://github.com/mochajs/mocha/issues/1766
-[#1752]: https://github.com/mochajs/mocha/issues/1752
-[#1761]: https://github.com/mochajs/mocha/issues/1761
-[#1700]: https://github.com/mochajs/mocha/issues/1700
-[#1774]: https://github.com/mochajs/mocha/issues/1774
-[#1687]: https://github.com/mochajs/mocha/issues/1687
-[#1359]: https://github.com/mochajs/mocha/issues/1359
-[#1758]: https://github.com/mochajs/mocha/issues/1758
-[#1741]: https://github.com/mochajs/mocha/issues/1741
-[#1739]: https://github.com/mochajs/mocha/issues/1739
-[#1730]: https://github.com/mochajs/mocha/issues/1730
-[#1349]: https://github.com/mochajs/mocha/issues/1349
-[#1572]: https://github.com/mochajs/mocha/issues/1572
-[#1630]: https://github.com/mochajs/mocha/issues/1630
-[#1718]: https://github.com/mochajs/mocha/issues/1718
-[#1689]: https://github.com/mochajs/mocha/issues/1689
-[#1654]: https://github.com/mochajs/mocha/issues/1654
-[@adamgruber]: https://github.com/adamgruber
-[@ajaykodali]: https://github.com/ajaykodali
-[@amsul]: https://github.com/amsul
-[@aryeguy]: https://github.com/aryeguy
-[@benvinegar]: https://github.com/benvinegar
-[@boneskull]: https://github.com/boneskull
-[@chromakode]: https://github.com/chromakode
-[@dominicbarnes]: https://github.com/dominicbarnes
-[@duncanbeevers]: https://github.com/duncanbeevers
-[@gigadude]: https://github.com/gigadude
-[@glenjamin]: https://github.com/glenjamin
-[@gsilk]: https://github.com/gsilk
-[@jakemmarsh]: https://github.com/jakemmarsh
-[@jbnicolai]: https://github.com/jbnicolai
-[@jlai]: https://github.com/jlai
-[@jonathandelgado]: https://github.com/jonathandelgado
-[@jschilli]: https://github.com/jschilli
-[@kkirsche]: https://github.com/kkirsche
-[@moll]: https://github.com/moll
-[@ndhoule]: https://github.com/ndhoule
-[@outdooricon]: https://github.com/outdooricon
-[@outsideris]: https://github.com/outsideris
-[@papandreou]: https://github.com/papandreou
-[@rstacruz]: https://github.com/rstacruz
-[@ryedog]: https://github.com/ryedog
-[@slyg]: https://github.com/slyg
-[@sunesimonsen]: https://github.com/sunesimonsen
-[@tinganho]: https://github.com/tinganho
-
-## 2.2.5 / 2015-05-14
-
-- [#1699] - Upgrade jsdiff to v1.4.0 ([@nylen])
-- [#1648] - fix diff background colors in the console ([@nylen])
-- [#1327] - fix tests running twice, a regression issue. ([#1686], [@danielstjules])
-- [#1675] - add integration tests ([@danielstjules])
-- [#1682] - use a valid SPDX license identifier in package.json ([@kemitchell])
-- [#1660] - fix assertion of invalid dates ([#1661], [@a8m])
-- [#1241] - fix issue with multiline diffs appearing as single line ([#1655], [@a8m])
-
-[#1699]: https://github.com/mochajs/mocha/issues/1699
-[#1648]: https://github.com/mochajs/mocha/issues/1648
-[#1327]: https://github.com/mochajs/mocha/issues/1327
-[#1686]: https://github.com/mochajs/mocha/issues/1686
-[#1675]: https://github.com/mochajs/mocha/issues/1675
-[#1682]: https://github.com/mochajs/mocha/issues/1682
-[#1660]: https://github.com/mochajs/mocha/issues/1660
-[#1661]: https://github.com/mochajs/mocha/issues/1661
-[#1241]: https://github.com/mochajs/mocha/issues/1241
-[#1655]: https://github.com/mochajs/mocha/issues/1655
-[@nylen]: https://github.com/nylen
-[@danielstjules]: https://github.com/danielstjules
-[@kemitchell]: https://github.com/kemitchell
-[@a8m]: https://github.com/a8m
-
-## 2.2.4 / 2015-04-08
-
-- Load mocha.opts in _mocha for now (close #1645)
-
-## 2.2.3 / 2015-04-07
-
-- fix(reporter/base): string diff - issue #1241
-- fix(reporter/base): string diff - issue #1241
-- fix(reporter/base): don't show diffs for errors without expectation
-- fix(reporter/base): don't assume error message is first line of stack
-- improve: dry up reporter/base test
-- fix(reporter/base): explicitly ignore showDiff #1614
-- Add iojs to travis build
-- Pass `--allow-natives-syntax` flag to node.
-- Support --harmony_classes flag for io.js
-- Fix 1556: Update utils.clean to handle newlines in func declarations
-- Fix 1606: fix err handling in IE <= 8 and non-ES5 browsers
-- Fix 1585: make _mocha executable again
-- chore(package.json): add a8m as a contributor
-- Fixed broken link on html-cov reporter
-- support --es_staging flag
-- fix issue where menu overlaps content.
-- update contributors in package.json
-- Remove trailing whitespace from reporter output
-- Remove contributors list from readme
-- log third-party reporter errors
-- [Fix] Exclude not own properties when looping on options
-- fix: support node args in mocha.opts (close #1573)
-- fix(reporter/base): string diff - issue #1241
-
-## 2.2.1 / 2015-03-09
-
-- Fix passing of args intended for node/iojs.
-
-## 2.2.0 / 2015-03-06
-
-- Update mocha.js
-- Add --fgrep. Use grep for RegExp, fgrep for str
-- Ignore async global errors after spec resolution
-- Fixing errors that prevent mocha.js from loading in the browser - fixes #1558
-- fix(utils): issue #1558 + make
-- add ability to delay root suite; closes #362, closes #1124
-- fix insanity in http tests
-- update travis: add node 0.12, add gitter, remove slack
-- building
-- resolve #1548: ensure the environment's "node" executable is used
-- reporters/base: use supports-color to detect colorable term
-- travis: use docker containers
-- small fix: commander option for --expose-gc
-- Ignore asynchronous errors after global failure
-- Improve error output when a test fails with a non-error
-- updated travis badge, uses svg instead of img
-- Allow skip from test context for #332
-- [JSHINT] Unnecessary semicolon fixed in bin/_mocha
-- Added a reminder about the done() callback to test timeout error messages
-- fixes #1496, in Mocha.run(fn), check if fn exists before executing it, added tests too
-- Add Harmony Proxy flag for iojs
-- test(utils|ms|*): test existing units
-- add support for some iojs flags
-- fix(utils.stringify): issue #1229, diff viewer
-- Remove slack link
-- Prevent multiple 'grep=' querystring params in html reporter
-- Use grep as regexp (close #1381)
-- utils.stringify should handle objects without an Object prototype
-- in runnable test, comparing to undefined error's message rather than a literal
-- Fix test running output truncation on async STDIO
-- amended for deprecated customFds option in child_process
-
-## 2.1.0 / 2014-12-23
-
-- showDiff: don’t stringify strings
-- Clean up unused module dependencies.
-- Filter zero-length strings from mocha.opts
-- only write to stdout in reporters
-- Revert "only write to stdout in reporters"
-- Print colored output only to a tty
-- update summary in README.md
-- rename Readme.md/History.md to README.md/HISTORY.md because neurotic
-- add .mailmap to fix "git shortlog" or "git summary" output
-- fixes #1461: nyan-reporter now respects Base.useColors, fixed bug where Base.color would not return a string when str wasn't a string.
-- Use existing test URL builder in failed replay links
-- modify .travis.yml: use travis_retry; closes #1449
-- fix -t 0 behavior; closes #1446
-- fix tests (whoops)
-- improve diff behavior
-- Preserve pathname when linking to individual tests
-- Fix test
-- Tiny typo in comments fixed
-- after hooks now being called on failed tests when using bail, fixes #1093
-- fix throwing undefined/null now makes tests fail, fixes #1395
-- compiler extensions are added as watched extensions, removed non-standard extensions from watch regex, resolves #1221
-- prefix/namespace for suite titles in markdown reporter, fixes #554
-- fix more bad markdown in CONTRIBUTING.md
-- fix bad markdown in CONTRIBUTING.md
-- add setImmediate/clearImmediate to globals; closes #1435
-- Fix buffer diffs (closes #1132, closes #1433)
-- add a CONTRIBUTING.md. closes #882
-- fix intermittent build failures (maybe). closes #1407
-- add Slack notification to .travis.yml
-- Fix slack link
-- Add slack room to readme
-- Update maintainers
-- update maintainers and contributors
-- resolves #1393: kill children with more effort on SIGINT
-- xunit reporter support for optionally writing to a file
-- if a reporter has a .done method, call it before exiting
-- add support for reporter options
-- only write to stdout in reporters
-
-## 2.0.0 / 2014-10-21
-
-- remove: support for node 0.6.x, 0.4.x
-- fix: landing reporter with non ansi characters (#211)
-- fix: html reporter - preserve query params when navigating to suites/tests (#1358)
-- fix: json stream reporter add error message to failed test
-- fix: fixes for visionmedia -> mochajs
-- fix: use stdio, fixes node deprecation warnings (#1391)
-
-## 1.21.5 / 2014-10-11
-
-- fix: build for NodeJS v0.6.x
-- fix: do not attempt to highlight syntax when non-HTML reporter is used
-- update: escape-string-regexp to 1.0.2.
-- fix: botched indentation in canonicalize()
-- fix: .gitignore: ignore .patch and .diff files
-- fix: changed 'Catched' to 'Caught' in uncaught exception error handler messages
-- add: `pending` field for json reporter
-- fix: Runner.prototype.uncaught: don't double-end runnables that already have a state.
-- fix: --recursive, broken by f0facd2e
-- update: replaces escapeRegexp with the escape-string-regexp package.
-- update: commander to 2.3.0.
-- update: diff to 1.0.8.
-- fix: ability to disable syntax highlighting (#1329)
-- fix: added empty object to errorJSON() call to catch when no error is present
-- fix: never time out after calling enableTimeouts(false)
-- fix: timeout(0) will work at suite level (#1300)
-- Fix for --watch+only() issue (#888 )
-- fix: respect err.showDiff, add Base reporter test (#810)
-
-## 1.22.1-3 / 2014-07-27
-
-- fix: disabling timeouts with this.timeout(0) (#1301)
-
-## 1.22.1-3 / 2014-07-27
-
-- fix: local uis and reporters (#1288)
-- fix: building 1.21.0's changes in the browser (#1284)
-
-## 1.21.0 / 2014-07-23
-
-- add: --no-timeouts option (#1262, #1268)
-- add: --*- deprecation node flags (#1217)
-- add: --watch-extensions argument (#1247)
-- change: spec reporter is default (#1228)
-- fix: diff output showing incorrect +/- (#1182)
-- fix: diffs of circular structures (#1179)
-- fix: re-render the progress bar when progress has changed only (#1151)
-- fix support for environments with global and window (#1159)
-- fix: reverting to previously defined onerror handler (#1178)
-- fix: stringify non error objects passed to done() (#1270)
-- fix: using local ui, reporters (#1267)
-- fix: cleaning es6 arrows (#1176)
-- fix: don't include attrs in failure tag for xunit (#1244)
-- fix: fail tests that return a promise if promise is rejected w/o a reason (#1224)
-- fix: showing failed tests in doc reporter (#1117)
-- fix: dot reporter dots being off (#1204)
-- fix: catch empty throws (#1219)
-- fix: honoring timeout for sync operations (#1242)
-- update: growl to 1.8.0
-
-## 1.20.1 / 2014-06-03
-
-- update: should dev dependency to ~4.0.0 (#1231)
-
-## 1.20.0 / 2014-05-28
-
-- add: filenames to suite objects (#1222)
-
-## 1.19.0 / 2014-05-17
-
-- add: browser script option to package.json
-- add: export file in Mocha.Test objects (#1174)
-- add: add docs for wrapped node flags
-- fix: mocha.run() to return error status in browser (#1216)
-- fix: clean() to show failure details (#1205)
-- fix: regex that generates html for new keyword (#1201)
-- fix: sibling suites have inherited but separate contexts (#1164)
-
-## 1.18.2 / 2014-03-18
-
-- fix: html runner was prevented from using #mocha as the default root el (#1162)
-
-## 1.18.1 / 2014-03-18
-
-- fix: named before/after hooks in bdd, tdd, qunit interfaces (#1161)
-
-## 1.18.0 / 2014-03-13
-
-- add: promise support (#329)
-- add: named before/after hooks (#966)
-
-## 1.17.1 / 2014-01-22
-
-- fix: expected messages in should.js (should.js#168)
-- fix: expect errno global in node versions < v0.9.11 (#1111)
-- fix: unreliable checkGlobals optimization (#1110)
-
-## 1.17.0 / 2014-01-09
-
-- add: able to require globals (describe, it, etc.) through mocha (#1077)
-- fix: abort previous run on --watch change (#1100)
-- fix: reset context for each --watch triggered run (#1099)
-- fix: error when cli can't resolve path or pattern (#799)
-- fix: canonicalize objects before stringifying and diffing them (#1079)
-- fix: make CR call behave like carriage return for non tty (#1087)
-
-## 1.16.2 / 2013-12-23
-
-- fix: couple issues with ie 8 (#1082, #1081)
-- fix: issue running the xunit reporter in browsers (#1068)
-- fix: issue with firefox < 3.5 (#725)
-
-## 1.16.1 / 2013-12-19
-
-- fix: recompiled for missed changes from the last release
-
-## 1.16.0 / 2013-12-19
-
-- add: Runnable.globals(arr) for per test global whitelist (#1046)
-- add: mocha.throwError(err) for assertion libs to call (#985)
-- remove: --watch's spinner (#806)
-- fix: duplicate test output for multi-line specs in spec reporter (#1006)
-- fix: gracefully exit on SIGINT (#1063)
-- fix expose the specified ui only in the browser (#984)
-- fix: ensure process exit code is preserved when using --no-exit (#1059)
-- fix: return true from window.onerror handler (#868)
-- fix: xunit reporter to use process.stdout.write (#1068)
-- fix: utils.clean(str) indentation (#761)
-- fix: xunit reporter returning test duration a NaN (#1039)
-
-## 1.15.1 / 2013-12-03
-
-- fix: recompiled for missed changes from the last release
-
-## 1.15.0 / 2013-12-02
-
-- add: `--no-exit` to prevent `process.exit()` (#1018)
-- fix: using inline diffs (#1044)
-- fix: show pending test details in xunit reporter (#1051)
-- fix: faster global leak detection (#1024)
-- fix: yui compression (#1035)
-- fix: wrapping long lines in test results (#1030, #1031)
-- fix: handle errors in hooks (#1043)
-
-## 1.14.0 / 2013-11-02
-
-- add: unified diff (#862)
-- add: set MOCHA_COLORS env var to use colors (#965)
-- add: able to override tests links in html reporters (#776)
-- remove: teamcity reporter (#954)
-- update: commander dependency to 2.0.0 (#1010)
-- fix: mocha --ui will try to require the ui if not built in, as --reporter does (#1022)
-- fix: send cursor commands only if isatty (#184, #1003)
-- fix: include assertion message in base reporter (#993, #991)
-- fix: consistent return of it, it.only, and describe, describe.only (#840)
-
-## 1.13.0 / 2013-09-15
-
-- add: sort test files with --sort (#813)
-- update: diff dependency to 1.0.7
-- update: glob dependency to 3.2.3 (#927)
-- fix: diffs show whitespace differences (#976)
-- fix: improve global leaks (#783)
-- fix: firefox window.getInterface leak
-- fix: accessing iframe via window[iframeIndex] leak
-- fix: faster global leak checking
-- fix: reporter pending css selector (#970)
-
-## 1.12.1 / 2013-08-29
-
-- remove test.js from .gitignore
-- update included version of ms.js
-
-## 1.12.0 / 2013-07-01
-
-- add: prevent diffs for differing types. Closes #900
-- add `Mocha.process` hack for phantomjs
-- fix: use compilers with requires
-- fix regexps in diffs. Closes #890
-- fix xunit NaN on failure. Closes #894
-- fix: strip tab indentation in `clean` utility method
-- fix: textmate bundle installation
-
-## 1.11.0 / 2013-06-12
-
-- add --prof support
-- add --harmony support
-- add --harmony-generators support
-- add "Uncaught " prefix to uncaught exceptions
-- add web workers support
-- add `suite.skip()`
-- change to output # of pending / passing even on failures. Closes #872
-- fix: prevent hooks from being called if we are bailing
-- fix `this.timeout(0)`
-
-## 1.10.0 / 2013-05-21
-
-- add add better globbing support for windows via `glob` module
-- add support to pass through flags such as --debug-brk=1234. Closes #852
-- add test.only, test.skip to qunit interface
-- change to always use word-based diffs for now. Closes #733
-- change `mocha init` tests.html to index.html
-- fix `process` global leak in the browser
-- fix: use resolve() instead of join() for --require
-- fix: filterLeaks() condition to not consider indices in global object as leaks
-- fix: restrict mocha.css styling to #mocha id
-- fix: save timer references to avoid Sinon interfering in the browser build.
-
-## 1.9.0 / 2013-04-03
-
-- add improved setImmediate implementation
-- replace --ignore-leaks with --check-leaks
-- change default of ignoreLeaks to true. Closes #791
-- remove scrolling for HTML reporter
-- fix retina support
-- fix tmbundle, restrict to js scope
-
-## 1.8.2 / 2013-03-11
-
-- add `setImmediate` support for 0.10.x
-- fix mocha -w spinner on windows
-
-## 1.8.1 / 2013-01-09
-
-- fix .bail() arity check causing it to default to true
-
-## 1.8.0 / 2013-01-08
-
-- add Mocha() options bail support
-- add `Mocha#bail()` method
-- add instanceof check back for inheriting from Error
-- add component.json
-- add diff.js to browser build
-- update growl
-- fix TAP reporter failures comment :D
-
-## 1.7.4 / 2012-12-06
-
-- add total number of passes and failures to TAP
-- remove .bind() calls. re #680
-- fix indexOf. Closes #680
-
-## 1.7.3 / 2012-11-30
-
-- fix uncaught error support for the browser
-- revert uncaught "fix" which breaks node
-
-## 1.7.2 / 2012-11-28
-
-- fix uncaught errors to expose the original error message
-
-## 1.7.0 / 2012-11-07
-
-- add `--async-only` support to prevent false positives for missing `done()`
-- add sorting by filename in code coverage
-- add HTML 5 doctype to browser template.
-- add play button to html reporter to rerun a single test
-- add `this.timeout(ms)` as Suite#timeout(ms). Closes #599
-- update growl dependency to 1.6.x
-- fix encoding of test-case ?grep. Closes #637
-- fix unicode chars on windows
-- fix dom globals in Opera/IE. Closes #243
-- fix markdown reporter a tags
-- fix `this.timeout("5s")` support
-
-## 1.6.0 / 2012-10-02
-
-- add object diffs when `err.showDiff` is present
-- add hiding of empty suites when pass/failures are toggled
-- add faster `.length` checks to `checkGlobals()` before performing the filter
-
-## 1.5.0 / 2012-09-21
-
-- add `ms()` to `.slow()` and `.timeout()`
-- add `Mocha#checkLeaks()` to re-enable global leak checks
-- add `this.slow()` option [aheckmann]
-- add tab, CR, LF to error diffs for now
-- add faster `.checkGlobals()` solution [guille]
-- remove `fn.call()` from reduce util
-- remove `fn.call()` from filter util
-- fix forEach. Closes #582
-- fix relaying of signals [TooTallNate]
-- fix TAP reporter grep number
-
-## 1.4.2 / 2012-09-01
-
-- add support to multiple `Mocha#globals()` calls, and strings
-- add `mocha.reporter()` constructor support [jfirebaugh]
-- add `mocha.timeout()`
-- move query-string parser to utils.js
-- move highlight code to utils.js
-- fix third-party reporter support [exogen]
-- fix client-side API to match node-side [jfirebaugh]
-- fix mocha in iframe [joliss]
-
-## 1.4.1 / 2012-08-28
-
-- add missing `Markdown` export
-- fix `Mocha#grep()`, escape regexp strings
-- fix reference error when `devicePixelRatio` is not defined. Closes #549
-
-## 1.4.0 / 2012-08-22
-
-- add mkdir -p to `mocha init`. Closes #539
-- add `.only()`. Closes #524
-- add `.skip()`. Closes #524
-- change str.trim() to use utils.trim(). Closes #533
-- fix HTML progress indicator retina display
-- fix url-encoding of click-to-grep HTML functionality
-
-## 1.3.2 / 2012-08-01
-
-- fix exports double-execution regression. Closes #531
-
-## 1.3.1 / 2012-08-01
-
-- add passes/failures toggling to HTML reporter
-- add pending state to `xit()` and `xdescribe()` [Brian Moore]
-- add the @charset "UTF-8"; to fix #522 with FireFox. [Jonathan Creamer]
-- add border-bottom to #stats links
-- add check for runnable in `Runner#uncaught()`. Closes #494
-- add 0.4 and 0.6 back to travis.yml
-- add `-E, --growl-errors` to growl on failures only
-- add prefixes to debug() names. Closes #497
-- add `Mocha#invert()` to js api
-- change dot reporter to use sexy unicode dots
-- fix error when clicking pending test in HTML reporter
-- fix `make tm`
-
-## 1.3.0 / 2012-07-05
-
-- add window scrolling to `HTML` reporter
-- add v8 `--trace-*` option support
-- add support for custom reports via `--reporter MODULE`
-- add `--invert` switch to invert `--grep` matches
-- fix export of `Nyan` reporter. Closes #495
-- fix escaping of `HTML` suite titles. Closes #486
-- fix `done()` called multiple times with an error test
-- change `--grep` - regexp escape the input
-
-## 1.2.2 / 2012-06-28
-
-- Added 0.8.0 support
-
-## 1.2.1 / 2012-06-25
-
-- Added `this.test.error(err)` support to after each hooks. Closes #287
-- Added: export top-level suite on global mocha object (mocha.suite). Closes #448
-- Fixed `js` code block format error in markdown reporter
-- Fixed deprecation warning when using `path.existsSync`
-- Fixed --globals with wildcard
-- Fixed chars in nyan when his head moves back
-- Remove `--growl` from test/mocha.opts. Closes #289
-
-## 1.2.0 / 2012-06-17
-
-- Added `nyan` reporter [Atsuya Takagi]
-- Added `mocha init <path>` to copy client files
-- Added "specify" synonym for "it" [domenic]
-- Added global leak wildcard support [nathanbowser]
-- Fixed runner emitter leak. closes #432
-- Fixed omission of .js extension. Closes #454
-
-## 1.1.0 / 2012-05-30
-
-- Added: check each `mocha(1)` arg for directories to walk
-- Added `--recursive` [tricknotes]
-- Added `context` for BDD [hokaccha]
-- Added styling for new clickable titles
-- Added clickable suite titles to HTML reporter
-- Added warning when strings are thrown as errors
-- Changed: green arrows again in HTML reporter styling
-- Changed ul/li elements instead of divs for better copy-and-pasting [joliss]
-- Fixed issue #325 - add better grep support to js api
-- Fixed: save timer references to avoid Sinon interfering.
-
-## 1.0.3 / 2012-04-30
-
-- Fixed string diff newlines
-- Fixed: removed mocha.css target. Closes #401
-
-## 1.0.2 / 2012-04-25
-
-- Added HTML reporter duration. Closes #47
-- Fixed: one postMessage event listener [exogen]
-- Fixed: allow --globals to be used multiple times. Closes #100 [brendannee]
-- Fixed #158: removes jquery include from browser tests
-- Fixed grep. Closes #372 [brendannee]
-- Fixed #166 - When grepping don't display the empty suites
-- Removed test/browser/style.css. Closes #385
-
-## 1.0.1 / 2012-04-04
-
-- Fixed `.timeout()` in hooks
-- Fixed: allow callback for `mocha.run()` in client version
-- Fixed browser hook error display. Closes #361
-
-## 1.0.0 / 2012-03-24
-
-- Added js API. Closes #265
-- Added: initial run of tests with `--watch`. Closes #345
-- Added: mark `location` as a global on the CS. Closes #311
-- Added `markdown` reporter (github flavour)
-- Added: scrolling menu to coverage.html. Closes #335
-- Added source line to html report for Safari [Tyson Tate]
-- Added "min" reporter, useful for `--watch` [Jakub Nešetřil]
-- Added support for arbitrary compilers via . Closes #338 [Ian Young]
-- Added Teamcity export to lib/reporters/index [Michael Riley]
-- Fixed chopping of first char in error reporting. Closes #334 [reported by topfunky]
-- Fixed terrible FF / Opera stack traces
-
-## 0.14.1 / 2012-03-06
-
-- Added lib-cov to _.npmignore_
-- Added reporter to `mocha.run([reporter])` as argument
-- Added some margin-top to the HTML reporter
-- Removed jQuery dependency
-- Fixed `--watch`: purge require cache. Closes #266
-
-## 0.14.0 / 2012-03-01
-
-- Added string diff support for terminal reporters
-
-## 0.13.0 / 2012-02-23
-
-- Added preliminary test coverage support. Closes #5
-- Added `HTMLCov` reporter
-- Added `JSONCov` reporter [kunklejr]
-- Added `xdescribe()` and `xit()` to the BDD interface. Closes #263 (docs * Changed: make json reporter output pretty json
-- Fixed node-inspector support, swapped `--debug` for `debug` to match node. Closes #247
-
-## 0.12.1 / 2012-02-14
-
-- Added `npm docs mocha` support [TooTallNate]
-- Added a `Context` object used for hook and test-case this. Closes #253
-- Fixed `Suite#clone()` `.ctx` reference. Closes #262
-
-## 0.12.0 / 2012-02-02
-
-- Added .coffee `--watch` support. Closes #242
-- Added support to `--require` files relative to the CWD. Closes #241
-- Added quick n dirty syntax highlighting. Closes #248
-- Changed: made HTML progress indicator smaller
-- Fixed xunit errors attribute [dhendo]
-
-## 0.10.2 / 2012-01-21
-
-- Fixed suite count in reporter stats. Closes #222
-- Fixed `done()` after timeout error reporting [Phil Sung]
-- Changed the 0-based errors to 1
-
-## 0.10.1 / 2012-01-17
-
-- Added support for node 0.7.x
-- Fixed absolute path support. Closes #215 [kompiro]
-- Fixed `--no-colors` option [Jussi Virtanen]
-- Fixed Arial CSS typo in the correct file
-
-## 0.10.0 / 2012-01-13
-
-- Added `-b, --bail` to exit on first exception [guillermo]
-- Added support for `-gc` / `--expose-gc` [TooTallNate]
-- Added `qunit`-inspired interface
-- Added MIT LICENSE. Closes #194
-- Added: `--watch` all .js in the CWD. Closes #139
-- Fixed `self.test` reference in runner. Closes #189
-- Fixed double reporting of uncaught exceptions after timeout. Closes #195
-
-## 0.8.2 / 2012-01-05
-
-- Added test-case context support. Closes #113
-- Fixed exit status. Closes #187
-- Update commander. Closes #190
-
-## 0.8.1 / 2011-12-30
-
-- Fixed reporting of uncaught exceptions. Closes #183
-- Fixed error message defaulting [indutny]
-- Changed mocha(1) from bash to node for windows [Nathan Rajlich]
-
-## 0.8.0 / 2011-12-28
-
-- Added `XUnit` reporter [FeeFighters/visionmedia]
-- Added `say(1)` notification support [Maciej Małecki]
-- Changed: fail when done() is invoked with a non-Error. Closes #171
-- Fixed `err.stack`, defaulting to message. Closes #180
-- Fixed: `make tm` mkdir -p the dest. Closes #137
-- Fixed mocha(1) --help bin name
-- Fixed `-d` for `--debug` support
-
-## 0.7.1 / 2011-12-22
-
-- Removed `mocha-debug(1)`, use `mocha --debug`
-- Fixed CWD relative requires
-- Fixed growl issue on windows [Raynos]
-- Fixed: platform specific line endings [TooTallNate]
-- Fixed: escape strings in HTML reporter. Closes #164
-
-## 0.7.0 / 2011-12-18
-
-- Added support for IE{7,8} [guille]
-- Changed: better browser nextTick implementation [guille]
-
-## 0.6.0 / 2011-12-18
-
-- Added setZeroTimeout timeout for browser (nicer stack traces). Closes #153
-- Added "view source" on hover for HTML reporter to make it obvious
-- Changed: replace custom growl with growl lib
-- Fixed duplicate reporting for HTML reporter. Closes #154
-- Fixed silent hook errors in the HTML reporter. Closes #150
-
-## 0.5.0 / 2011-12-14
-
-- Added: push node_modules directory onto module.paths for relative require Closes #93
-- Added teamcity reporter [blindsey]
-- Fixed: recover from uncaught exceptions for tests. Closes #94
-- Fixed: only emit "test end" for uncaught within test, not hook
-
-## 0.4.0 / 2011-12-14
-
-- Added support for test-specific timeouts via `this.timeout(0)`. Closes #134
-- Added guillermo's client-side EventEmitter. Closes #132
-- Added progress indicator to the HTML reporter
-- Fixed slow browser tests. Closes #135
-- Fixed "suite" color for light terminals
-- Fixed `require()` leak spotted by [guillermo]
-
-## 0.3.6 / 2011-12-09
-
-- Removed suite merging (for now)
-
-## 0.3.5 / 2011-12-08
-
-- Added support for `window.onerror` [guillermo]
-- Fixed: clear timeout on uncaught exceptions. Closes #131 [guillermo]
-- Added `mocha.css` to PHONY list.
-- Added `mocha.js` to PHONY list.
-
-## 0.3.4 / 2011-12-08
-
-- Added: allow `done()` to be called with non-Error
-- Added: return Runner from `mocha.run()`. Closes #126
-- Fixed: run afterEach even on failures. Closes #125
-- Fixed clobbering of current runnable. Closes #121
-
-## 0.3.3 / 2011-12-08
-
-- Fixed hook timeouts. Closes #120
-- Fixed uncaught exceptions in hooks
-
-## 0.3.2 / 2011-12-05
-
-- Fixed weird reporting when `err.message` is not present
-
-## 0.3.1 / 2011-12-04
-
-- Fixed hook event emitter leak. Closes #117
-- Fixed: export `Spec` constructor. Closes #116
-
-## 0.3.0 / 2011-12-04
-
-- Added `-w, --watch`. Closes #72
-- Added `--ignore-leaks` to ignore global leak checking
-- Added browser `?grep=pattern` support
-- Added `--globals <names>` to specify accepted globals. Closes #99
-- Fixed `mocha-debug(1)` on some systems. Closes #232
-- Fixed growl total, use `runner.total`
-
-## 0.2.0 / 2011-11-30
-
-- Added `--globals <names>` to specify accepted globals. Closes #99
-- Fixed funky highlighting of messages. Closes #97
-- Fixed `mocha-debug(1)`. Closes #232
-- Fixed growl total, use runner.total
-
-## 0.1.0 / 2011-11-29
-
-- Added `suiteSetup` and `suiteTeardown` to TDD interface [David Henderson]
-- Added growl icons. Closes #84
-- Fixed coffee-script support
-
-## 0.0.8 / 2011-11-25
-
-- Fixed: use `Runner#total` for accurate reporting
-
-## 0.0.7 / 2011-11-25
-
-- Added `Hook`
-- Added `Runnable`
-- Changed: `Test` is `Runnable`
-- Fixed global leak reporting in hooks
-- Fixed: > 2 calls to done() only report the error once
-- Fixed: clear timer on failure. Closes #80
-
-## 0.0.6 / 2011-11-25
-
-- Fixed return on immediate async error. Closes #80
-
-## 0.0.5 / 2011-11-24
-
-- Fixed: make mocha.opts whitespace less picky [kkaefer]
-
-## 0.0.4 / 2011-11-24
-
-- Added `--interfaces`
-- Added `--reporters`
-- Added `-c, --colors`. Closes #69
-- Fixed hook timeouts
-
-## 0.0.3 / 2011-11-23
-
-- Added `-C, --no-colors` to explicitly disable
-- Added coffee-script support
-
-## 0.0.2 / 2011-11-22
-
-- Fixed global leak detection due to Safari bind() change
-- Fixed: escape html entities in Doc reporter
-- Fixed: escape html entities in HTML reporter
-- Fixed pending test support for HTML reporter. Closes #66
-
-## 0.0.1 / 2011-11-22
-
-- Added `--timeout` second shorthand support, ex `--timeout 3s`.
-- Fixed "test end" event for uncaughtExceptions. Closes #61
-
-## 0.0.1-alpha6 / 2011-11-19
-
-- Added travis CI support (needs enabling when public)
-- Added preliminary browser support
-- Added `make mocha.css` target. Closes #45
-- Added stack trace to TAP errors. Closes #52
-- Renamed tearDown to teardown. Closes #49
-- Fixed: cascading hooksc. Closes #30
-- Fixed some colors for non-tty
-- Fixed errors thrown in sync test-cases due to nextTick
-- Fixed Base.window.width... again give precedence to 0.6.x
-
-## 0.0.1-alpha5 / 2011-11-17
-
-- Added `doc` reporter. Closes #33
-- Added suite merging. Closes #28
-- Added TextMate bundle and `make tm`. Closes #20
-
-## 0.0.1-alpha4 / 2011-11-15
-
-- Fixed getWindowSize() for 0.4.x
-
-## 0.0.1-alpha3 / 2011-11-15
-
-- Added `-s, --slow <ms>` to specify "slow" test threshold
-- Added `mocha-debug(1)`
-- Added `mocha.opts` support. Closes #31
-- Added: default [files] to _test/*.js_
-- Added protection against multiple calls to `done()`. Closes #35
-- Changed: bright yellow for slow Dot reporter tests
-
-## 0.0.1-alpha2 / 2011-11-08
-
-- Missed this one :)
-
-## 0.0.1-alpha1 / 2011-11-08
-
-- Initial release

images/error.png

Binary file images/error.png has changed

images/ok.png

Binary file images/ok.png has changed

lib/browser/.eslintrc.yml

@@ -1,4 +0,0 @@
-env:
- node: false
- browser: false
- commonjs: true

lib/browser/progress.js

@@ -9,7 +9,7 @@
/**
* Initialize a new `Progress` indicator.
*/
-function Progress () {
+function Progress() {
this.percent = 0;
this.size(0);
this.fontSize(11);
@@ -23,7 +23,7 @@
* @param {number} size
* @return {Progress} Progress instance.
*/
-Progress.prototype.size = function (size) {
+Progress.prototype.size = function(size) {
this._size = size;
return this;
};
@@ -35,7 +35,7 @@
* @param {string} text
* @return {Progress} Progress instance.
*/
-Progress.prototype.text = function (text) {
+Progress.prototype.text = function(text) {
this._text = text;
return this;
};
@@ -47,7 +47,7 @@
* @param {number} size
* @return {Progress} Progress instance.
*/
-Progress.prototype.fontSize = function (size) {
+Progress.prototype.fontSize = function(size) {
this._fontSize = size;
return this;
};
@@ -58,7 +58,7 @@
* @param {string} family
* @return {Progress} Progress instance.
*/
-Progress.prototype.font = function (family) {
+Progress.prototype.font = function(family) {
this._font = family;
return this;
};
@@ -69,7 +69,7 @@
* @param {number} n
* @return {Progress} Progress instance.
*/
-Progress.prototype.update = function (n) {
+Progress.prototype.update = function(n) {
this.percent = n;
return this;
};
@@ -80,7 +80,7 @@
* @param {CanvasRenderingContext2d} ctx
* @return {Progress} Progress instance.
*/
-Progress.prototype.draw = function (ctx) {
+Progress.prototype.draw = function(ctx) {
try {
var percent = Math.min(this.percent, 100);
var size = this._size;
@@ -112,7 +112,7 @@
var w = ctx.measureText(text).width;
ctx.fillText(text, x - w / 2 + 1, y + fontSize / 2 - 1);
- } catch (err) {
+ } catch (ignore) {
// don't fail if we can't render progress
}
return this;

lib/browser/tty.js

@@ -1,10 +1,10 @@
'use strict';
-exports.isatty = function isatty () {
+exports.isatty = function isatty() {
return true;
};
-exports.getWindowSize = function getWindowSize () {
+exports.getWindowSize = function getWindowSize() {
if ('innerHeight' in global) {
return [global.innerHeight, global.innerWidth];
}

lib/context.js

@@ -1,5 +1,7 @@
'use strict';
-
+/**
+ * @module Context
+ */
/**
* Expose `Context`.
*/
@@ -11,16 +13,16 @@
*
* @api private
*/
-function Context () {}
+function Context() {}
/**
* Set or get the context `Runnable` to `runnable`.
*
* @api private
* @param {Runnable} runnable
- * @return {Context}
+ * @return {Context} context
*/
-Context.prototype.runnable = function (runnable) {
+Context.prototype.runnable = function(runnable) {
if (!arguments.length) {
return this._runnable;
}
@@ -35,7 +37,7 @@
* @param {number} ms
* @return {Context} self
*/
-Context.prototype.timeout = function (ms) {
+Context.prototype.timeout = function(ms) {
if (!arguments.length) {
return this.runnable().timeout();
}
@@ -50,7 +52,7 @@
* @param {boolean} enabled
* @return {Context} self
*/
-Context.prototype.enableTimeouts = function (enabled) {
+Context.prototype.enableTimeouts = function(enabled) {
if (!arguments.length) {
return this.runnable().enableTimeouts();
}
@@ -65,7 +67,7 @@
* @param {number} ms
* @return {Context} self
*/
-Context.prototype.slow = function (ms) {
+Context.prototype.slow = function(ms) {
if (!arguments.length) {
return this.runnable().slow();
}
@@ -79,7 +81,7 @@
* @api private
* @throws Pending
*/
-Context.prototype.skip = function () {
+Context.prototype.skip = function() {
this.runnable().skip();
};
@@ -90,7 +92,7 @@
* @param {number} n
* @return {Context} self
*/
-Context.prototype.retries = function (n) {
+Context.prototype.retries = function(n) {
if (!arguments.length) {
return this.runnable().retries();
}

lib/hook.js

@@ -1,9 +1,5 @@
'use strict';
-/**
- * Module dependencies.
- */
-
var Runnable = require('./runnable');
var inherits = require('./utils').inherits;
@@ -14,13 +10,14 @@
module.exports = Hook;
/**
- * Initialize a new `Hook` with the given `title` and callback `fn`.
+ * Initialize a new `Hook` with the given `title` and callback `fn`
*
+ * @class
+ * @extends Runnable
* @param {String} title
* @param {Function} fn
- * @api private
*/
-function Hook (title, fn) {
+function Hook(title, fn) {
Runnable.call(this, title, fn);
this.type = 'hook';
}
@@ -33,11 +30,12 @@
/**
* Get or set the test `err`.
*
+ * @memberof Hook
+ * @public
* @param {Error} err
* @return {Error}
- * @api public
*/
-Hook.prototype.error = function (err) {
+Hook.prototype.error = function(err) {
if (!arguments.length) {
err = this._error;
this._error = null;

lib/interfaces/bdd.js

@@ -1,9 +1,5 @@
'use strict';
-/**
- * Module dependencies.
- */
-
var Test = require('../test');
/**
@@ -23,10 +19,10 @@
*
* @param {Suite} suite Root suite.
*/
-module.exports = function (suite) {
+module.exports = function bddInterface(suite) {
var suites = [suite];
- suite.on('pre-require', function (context, file, mocha) {
+ suite.on('pre-require', function(context, file, mocha) {
var common = require('./common')(suites, context, mocha);
context.before = common.before;
@@ -40,7 +36,7 @@
* and/or tests.
*/
- context.describe = context.context = function (title, fn) {
+ context.describe = context.context = function(title, fn) {
return common.suite.create({
title: title,
file: file,
@@ -52,7 +48,10 @@
* Pending describe.
*/
- context.xdescribe = context.xcontext = context.describe.skip = function (title, fn) {
+ context.xdescribe = context.xcontext = context.describe.skip = function(
+ title,
+ fn
+ ) {
return common.suite.skip({
title: title,
file: file,
@@ -64,7 +63,7 @@
* Exclusive suite.
*/
- context.describe.only = function (title, fn) {
+ context.describe.only = function(title, fn) {
return common.suite.only({
title: title,
file: file,
@@ -78,7 +77,7 @@
* acting as a thunk.
*/
- context.it = context.specify = function (title, fn) {
+ context.it = context.specify = function(title, fn) {
var suite = suites[0];
if (suite.isPending()) {
fn = null;
@@ -93,7 +92,7 @@
* Exclusive test-case.
*/
- context.it.only = function (title, fn) {
+ context.it.only = function(title, fn) {
return common.test.only(mocha, context.it(title, fn));
};
@@ -101,14 +100,14 @@
* Pending test case.
*/
- context.xit = context.xspecify = context.it.skip = function (title) {
+ context.xit = context.xspecify = context.it.skip = function(title) {
return context.it(title);
};
/**
* Number of attempts to retry.
*/
- context.it.retries = function (n) {
+ context.it.retries = function(n) {
context.retries(n);
};
});

lib/interfaces/common.js

@@ -10,7 +10,7 @@
* @param {Mocha} mocha
* @return {Object} An object containing common functions.
*/
-module.exports = function (suites, context, mocha) {
+module.exports = function(suites, context, mocha) {
return {
/**
* This is only present if flag --delay is passed into Mocha. It triggers
@@ -19,8 +19,8 @@
* @param {Suite} suite The root suite.
* @return {Function} A function which runs the root suite
*/
- runWithSuite: function runWithSuite (suite) {
- return function run () {
+ runWithSuite: function runWithSuite(suite) {
+ return function run() {
suite.run();
};
},
@@ -31,7 +31,7 @@
* @param {string} name
* @param {Function} fn
*/
- before: function (name, fn) {
+ before: function(name, fn) {
suites[0].beforeAll(name, fn);
},
@@ -41,7 +41,7 @@
* @param {string} name
* @param {Function} fn
*/
- after: function (name, fn) {
+ after: function(name, fn) {
suites[0].afterAll(name, fn);
},
@@ -51,7 +51,7 @@
* @param {string} name
* @param {Function} fn
*/
- beforeEach: function (name, fn) {
+ beforeEach: function(name, fn) {
suites[0].beforeEach(name, fn);
},
@@ -61,7 +61,7 @@
* @param {string} name
* @param {Function} fn
*/
- afterEach: function (name, fn) {
+ afterEach: function(name, fn) {
suites[0].afterEach(name, fn);
},
@@ -73,7 +73,7 @@
* @param {Object} opts
* @returns {Suite}
*/
- only: function only (opts) {
+ only: function only(opts) {
opts.isOnly = true;
return this.create(opts);
},
@@ -85,7 +85,7 @@
* @param {Object} opts
* @returns {Suite}
*/
- skip: function skip (opts) {
+ skip: function skip(opts) {
opts.pending = true;
return this.create(opts);
},
@@ -100,7 +100,7 @@
* @param {boolean} [opts.isOnly] Is Suite exclusive?
* @returns {Suite}
*/
- create: function create (opts) {
+ create: function create(opts) {
var suite = Suite.create(suites[0], opts.title);
suite.pending = Boolean(opts.pending);
suite.file = opts.file;
@@ -112,7 +112,13 @@
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.');
+ throw new Error(
+ 'Suite "' +
+ suite.fullTitle() +
+ '" was defined but no callback was supplied. Supply a callback or explicitly skip the suite.'
+ );
+ } else if (!opts.fn && suite.pending) {
+ suites.shift();
}
return suite;
@@ -128,7 +133,7 @@
* @param {Function} test
* @returns {*}
*/
- only: function (mocha, test) {
+ only: function(mocha, test) {
test.parent._onlyTests = test.parent._onlyTests.concat(test);
return test;
},
@@ -138,7 +143,7 @@
*
* @param {string} title
*/
- skip: function (title) {
+ skip: function(title) {
context.test(title);
},
@@ -147,7 +152,7 @@
*
* @param {number} n
*/
- retries: function (n) {
+ retries: function(n) {
context.retries(n);
}
}

lib/interfaces/exports.js

@@ -1,9 +1,4 @@
'use strict';
-
-/**
- * Module dependencies.
- */
-
var Suite = require('../suite');
var Test = require('../test');
@@ -24,12 +19,12 @@
*
* @param {Suite} suite Root suite.
*/
-module.exports = function (suite) {
+module.exports = function(suite) {
var suites = [suite];
suite.on('require', visit);
- function visit (obj, file) {
+ function visit(obj, file) {
var suite;
for (var key in obj) {
if (typeof obj[key] === 'function') {

lib/interfaces/qunit.js

@@ -1,9 +1,5 @@
'use strict';
-/**
- * Module dependencies.
- */
-
var Test = require('../test');
/**
@@ -31,10 +27,10 @@
*
* @param {Suite} suite Root suite.
*/
-module.exports = function (suite) {
+module.exports = function qUnitInterface(suite) {
var suites = [suite];
- suite.on('pre-require', function (context, file, mocha) {
+ suite.on('pre-require', function(context, file, mocha) {
var common = require('./common')(suites, context, mocha);
context.before = common.before;
@@ -46,7 +42,7 @@
* Describe a "suite" with the given `title`.
*/
- context.suite = function (title) {
+ context.suite = function(title) {
if (suites.length > 1) {
suites.shift();
}
@@ -61,7 +57,7 @@
* Exclusive Suite.
*/
- context.suite.only = function (title) {
+ context.suite.only = function(title) {
if (suites.length > 1) {
suites.shift();
}
@@ -78,7 +74,7 @@
* acting as a thunk.
*/
- context.test = function (title, fn) {
+ context.test = function(title, fn) {
var test = new Test(title, fn);
test.file = file;
suites[0].addTest(test);
@@ -89,7 +85,7 @@
* Exclusive test-case.
*/
- context.test.only = function (title, fn) {
+ context.test.only = function(title, fn) {
return common.test.only(mocha, context.test(title, fn));
};

lib/interfaces/tdd.js

@@ -1,9 +1,5 @@
'use strict';
-/**
- * Module dependencies.
- */
-
var Test = require('../test');
/**
@@ -31,10 +27,10 @@
*
* @param {Suite} suite Root suite.
*/
-module.exports = function (suite) {
+module.exports = function(suite) {
var suites = [suite];
- suite.on('pre-require', function (context, file, mocha) {
+ suite.on('pre-require', function(context, file, mocha) {
var common = require('./common')(suites, context, mocha);
context.setup = common.beforeEach;
@@ -47,7 +43,7 @@
* Describe a "suite" with the given `title` and callback `fn` containing
* nested suites and/or tests.
*/
- context.suite = function (title, fn) {
+ context.suite = function(title, fn) {
return common.suite.create({
title: title,
file: file,
@@ -58,7 +54,7 @@
/**
* Pending suite.
*/
- context.suite.skip = function (title, fn) {
+ context.suite.skip = function(title, fn) {
return common.suite.skip({
title: title,
file: file,
@@ -69,7 +65,7 @@
/**
* Exclusive test-case.
*/
- context.suite.only = function (title, fn) {
+ context.suite.only = function(title, fn) {
return common.suite.only({
title: title,
file: file,
@@ -81,7 +77,7 @@
* Describe a specification or test-case with the given `title` and
* callback `fn` acting as a thunk.
*/
- context.test = function (title, fn) {
+ context.test = function(title, fn) {
var suite = suites[0];
if (suite.isPending()) {
fn = null;
@@ -96,7 +92,7 @@
* Exclusive test-case.
*/
- context.test.only = function (title, fn) {
+ context.test.only = function(title, fn) {
return common.test.only(mocha, context.test(title, fn));
};

lib/mocha.js

@@ -6,19 +6,11 @@
* 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;
/**
@@ -34,11 +26,25 @@
* Expose internals.
*/
+/**
+ * @public
+ * @class utils
+ * @memberof Mocha
+ */
exports.utils = utils;
exports.interfaces = require('./interfaces');
+/**
+ *
+ * @memberof Mocha
+ * @public
+ */
exports.reporters = reporters;
exports.Runnable = require('./runnable');
exports.Context = require('./context');
+/**
+ *
+ * @memberof Mocha
+ */
exports.Runner = require('./runner');
exports.Suite = require('./suite');
exports.Hook = require('./hook');
@@ -47,12 +53,12 @@
/**
* Return image `name` path.
*
- * @api private
+ * @private
* @param {string} name
* @return {string}
*/
-function image (name) {
- return path.join(__dirname, '../images', name + '.png');
+function image(name) {
+ return path.join(__dirname, '..', 'assets', 'growl', name + '.png');
}
/**
@@ -71,10 +77,10 @@
* - `fullTrace` display the full stack-trace on failing
* - `grep` string or regexp to filter tests with
*
+ * @class Mocha
* @param {Object} options
- * @api public
*/
-function Mocha (options) {
+function Mocha(options) {
options = options || {};
this.files = [];
this.options = options;
@@ -106,10 +112,11 @@
/**
* Enable or disable bailing on the first failure.
*
+ * @public
* @api public
* @param {boolean} [bail]
*/
-Mocha.prototype.bail = function (bail) {
+Mocha.prototype.bail = function(bail) {
if (!arguments.length) {
bail = true;
}
@@ -120,10 +127,11 @@
/**
* Add test `file`.
*
+ * @public
* @api public
* @param {string} file
*/
-Mocha.prototype.addFile = function (file) {
+Mocha.prototype.addFile = function(file) {
this.files.push(file);
return this;
};
@@ -131,13 +139,14 @@
/**
* Set reporter to `reporter`, defaults to "spec".
*
+ * @public
* @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) {
+Mocha.prototype.reporter = function(reporter, reporterOptions) {
if (typeof reporter === 'function') {
this._reporter = reporter;
} else {
@@ -157,18 +166,28 @@
try {
_reporter = require(path.resolve(process.cwd(), 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);
+ err.message.indexOf('Cannot find module') !== -1
+ ? console.warn('"' + reporter + '" reporter not found')
+ : console.warn(
+ '"' +
+ reporter +
+ '" reporter blew up with error:\n' +
+ err.stack
+ );
}
} else {
- console.warn('"' + reporter + '" reporter blew up with error:\n' + err.stack);
+ 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 ' +
+ console.warn(
+ 'The Teamcity reporter was moved to a package named ' +
'mocha-teamcity-reporter ' +
- '(https://npmjs.org/package/mocha-teamcity-reporter).');
+ '(https://npmjs.org/package/mocha-teamcity-reporter).'
+ );
}
if (!_reporter) {
throw new Error('invalid reporter "' + reporter + '"');
@@ -181,11 +200,11 @@
/**
* Set test UI `name`, defaults to "bdd".
- *
+ * @public
* @api public
* @param {string} bdd
*/
-Mocha.prototype.ui = function (name) {
+Mocha.prototype.ui = function(name) {
name = name || 'bdd';
this._ui = exports.interfaces[name];
if (!this._ui) {
@@ -197,7 +216,7 @@
}
this._ui = this._ui(this.suite);
- this.suite.on('pre-require', function (context) {
+ 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;
@@ -222,10 +241,10 @@
*
* @api private
*/
-Mocha.prototype.loadFiles = function (fn) {
+Mocha.prototype.loadFiles = function(fn) {
var self = this;
var suite = this.suite;
- this.files.forEach(function (file) {
+ this.files.forEach(function(file) {
file = path.resolve(file);
suite.emit('pre-require', global, file, self);
suite.emit('require', require(file), file, self);
@@ -239,14 +258,14 @@
*
* @api private
*/
-Mocha.prototype._growl = function (runner, reporter) {
+Mocha.prototype._growl = function(runner, reporter) {
var notify = require('growl');
- runner.on('end', function () {
+ 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') });
+ notify(msg, {name: 'mocha', title: 'Failed', image: image('error')});
} else {
notify(stats.passes + ' tests passed in ' + stats.duration + 'ms', {
name: 'mocha',
@@ -260,24 +279,26 @@
/**
* Escape string and add it to grep as a regexp.
*
+ * @public
* @api public
* @param str
* @returns {Mocha}
*/
-Mocha.prototype.fgrep = function (str) {
+Mocha.prototype.fgrep = function(str) {
return this.grep(new RegExp(escapeRe(str)));
};
/**
* Add regexp to grep, if `re` is a string it is escaped.
*
+ * @public
* @param {RegExp|String} re
* @return {Mocha}
* @api public
* @param {RegExp|string} re
* @return {Mocha}
*/
-Mocha.prototype.grep = function (re) {
+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|)$|.*/);
@@ -290,10 +311,11 @@
/**
* Invert `.grep()` matches.
*
+ * @public
* @return {Mocha}
* @api public
*/
-Mocha.prototype.invert = function () {
+Mocha.prototype.invert = function() {
this.options.invert = true;
return this;
};
@@ -301,13 +323,14 @@
/**
* Ignore global leaks.
*
+ * @public
* @param {Boolean} ignore
* @return {Mocha}
* @api public
* @param {boolean} ignore
* @return {Mocha}
*/
-Mocha.prototype.ignoreLeaks = function (ignore) {
+Mocha.prototype.ignoreLeaks = function(ignore) {
this.options.ignoreLeaks = Boolean(ignore);
return this;
};
@@ -317,8 +340,9 @@
*
* @return {Mocha}
* @api public
+ * @public
*/
-Mocha.prototype.checkLeaks = function () {
+Mocha.prototype.checkLeaks = function() {
this.options.ignoreLeaks = false;
return this;
};
@@ -328,8 +352,9 @@
*
* @return {Mocha}
* @api public
+ * @public
*/
-Mocha.prototype.fullTrace = function () {
+Mocha.prototype.fullTrace = function() {
this.options.fullStackTrace = true;
return this;
};
@@ -339,8 +364,9 @@
*
* @return {Mocha}
* @api public
+ * @public
*/
-Mocha.prototype.growl = function () {
+Mocha.prototype.growl = function() {
this.options.growl = true;
return this;
};
@@ -351,10 +377,11 @@
* @param {Array|String} globals
* @return {Mocha}
* @api public
+ * @public
* @param {Array|string} globals
* @return {Mocha}
*/
-Mocha.prototype.globals = function (globals) {
+Mocha.prototype.globals = function(globals) {
this.options.globals = (this.options.globals || []).concat(globals);
return this;
};
@@ -365,10 +392,11 @@
* @param {Boolean} colors
* @return {Mocha}
* @api public
+ * @public
* @param {boolean} colors
* @return {Mocha}
*/
-Mocha.prototype.useColors = function (colors) {
+Mocha.prototype.useColors = function(colors) {
if (colors !== undefined) {
this.options.useColors = colors;
}
@@ -381,10 +409,11 @@
* @param {Boolean} inlineDiffs
* @return {Mocha}
* @api public
+ * @public
* @param {boolean} inlineDiffs
* @return {Mocha}
*/
-Mocha.prototype.useInlineDiffs = function (inlineDiffs) {
+Mocha.prototype.useInlineDiffs = function(inlineDiffs) {
this.options.useInlineDiffs = inlineDiffs !== undefined && inlineDiffs;
return this;
};
@@ -395,10 +424,11 @@
* @param {Boolean} hideDiff
* @return {Mocha}
* @api public
+ * @public
* @param {boolean} hideDiff
* @return {Mocha}
*/
-Mocha.prototype.hideDiff = function (hideDiff) {
+Mocha.prototype.hideDiff = function(hideDiff) {
this.options.hideDiff = hideDiff !== undefined && hideDiff;
return this;
};
@@ -409,10 +439,11 @@
* @param {Number} timeout
* @return {Mocha}
* @api public
+ * @public
* @param {number} timeout
* @return {Mocha}
*/
-Mocha.prototype.timeout = function (timeout) {
+Mocha.prototype.timeout = function(timeout) {
this.suite.timeout(timeout);
return this;
};
@@ -423,8 +454,9 @@
* @param {Number} retry times
* @return {Mocha}
* @api public
+ * @public
*/
-Mocha.prototype.retries = function (n) {
+Mocha.prototype.retries = function(n) {
this.suite.retries(n);
return this;
};
@@ -435,10 +467,11 @@
* @param {Number} slow
* @return {Mocha}
* @api public
+ * @public
* @param {number} slow
* @return {Mocha}
*/
-Mocha.prototype.slow = function (slow) {
+Mocha.prototype.slow = function(slow) {
this.suite.slow(slow);
return this;
};
@@ -449,11 +482,14 @@
* @param {Boolean} enabled
* @return {Mocha}
* @api public
+ * @public
* @param {boolean} enabled
* @return {Mocha}
*/
-Mocha.prototype.enableTimeouts = function (enabled) {
- this.suite.enableTimeouts(arguments.length && enabled !== undefined ? enabled : true);
+Mocha.prototype.enableTimeouts = function(enabled) {
+ this.suite.enableTimeouts(
+ arguments.length && enabled !== undefined ? enabled : true
+ );
return this;
};
@@ -462,8 +498,9 @@
*
* @return {Mocha}
* @api public
+ * @public
*/
-Mocha.prototype.asyncOnly = function () {
+Mocha.prototype.asyncOnly = function() {
this.options.asyncOnly = true;
return this;
};
@@ -472,8 +509,9 @@
* Disable syntax highlighting (in browser).
*
* @api public
+ * @public
*/
-Mocha.prototype.noHighlighting = function () {
+Mocha.prototype.noHighlighting = function() {
this.options.noHighlighting = true;
return this;
};
@@ -483,8 +521,9 @@
*
* @return {Mocha}
* @api public
+ * @public
*/
-Mocha.prototype.allowUncaught = function () {
+Mocha.prototype.allowUncaught = function() {
this.options.allowUncaught = true;
return this;
};
@@ -493,7 +532,7 @@
* Delay root suite execution.
* @returns {Mocha}
*/
-Mocha.prototype.delay = function delay () {
+Mocha.prototype.delay = function delay() {
this.options.delay = true;
return this;
};
@@ -502,7 +541,7 @@
* Tests marked only fail the suite
* @returns {Mocha}
*/
-Mocha.prototype.forbidOnly = function () {
+Mocha.prototype.forbidOnly = function() {
this.options.forbidOnly = true;
return this;
};
@@ -511,7 +550,7 @@
* Pending tests and tests marked skip fail the suite
* @returns {Mocha}
*/
-Mocha.prototype.forbidPending = function () {
+Mocha.prototype.forbidPending = function() {
this.options.forbidPending = true;
return this;
};
@@ -528,10 +567,11 @@
* cache first in whichever manner best suits your needs.
*
* @api public
+ * @public
* @param {Function} fn
* @return {Runner}
*/
-Mocha.prototype.run = function (fn) {
+Mocha.prototype.run = function(fn) {
if (this.files.length) {
this.loadFiles();
}
@@ -561,7 +601,7 @@
exports.reporters.Base.inlineDiffs = options.useInlineDiffs;
exports.reporters.Base.hideDiff = options.hideDiff;
- function done (failures) {
+ function done(failures) {
if (reporter.done) {
reporter.done(failures, fn);
} else {

lib/ms.js

@@ -1,5 +1,7 @@
'use strict';
-
+/**
+ * @module milliseconds
+ */
/**
* Helpers.
*/
@@ -13,11 +15,13 @@
/**
* Parse or format the given `val`.
*
+ * @memberof Mocha
+ * @public
* @api public
* @param {string|number} val
* @return {string|number}
*/
-module.exports = function (val) {
+module.exports = function(val) {
if (typeof val === 'string') {
return parse(val);
}
@@ -31,8 +35,10 @@
* @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);
+function parse(str) {
+ var match = /^((?:\d+)?\.?\d+) *(ms|seconds?|s|minutes?|m|hours?|h|days?|d|years?|y)?$/i.exec(
+ str
+ );
if (!match) {
return;
}
@@ -73,7 +79,7 @@
* @param {number} ms
* @return {string}
*/
-function format (ms) {
+function format(ms) {
if (ms >= d) {
return Math.round(ms / d) + 'd';
}

lib/pending.js

@@ -1,9 +1,5 @@
'use strict';
-/**
- * Expose `Pending`.
- */
-
module.exports = Pending;
/**
@@ -11,6 +7,6 @@
*
* @param {string} message
*/
-function Pending (message) {
+function Pending(message) {
this.message = message;
}

lib/reporters/base.js

@@ -1,5 +1,7 @@
'use strict';
-
+/**
+ * @module Base
+ */
/**
* Module dependencies.
*/
@@ -39,7 +41,9 @@
* Enable coloring by default, except in the browser interface.
*/
-exports.useColors = !process.browser && (supportsColor || (process.env.MOCHA_COLORS !== undefined));
+exports.useColors =
+ !process.browser &&
+ (supportsColor.stdout || process.env.MOCHA_COLORS !== undefined);
/**
* Inline diffs instead of +/-
@@ -103,12 +107,12 @@
* @return {string}
* @api private
*/
-var color = exports.color = function (type, str) {
+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.
@@ -129,23 +133,23 @@
*/
exports.cursor = {
- hide: function () {
+ hide: function() {
isatty && process.stdout.write('\u001b[?25l');
},
- show: function () {
+ show: function() {
isatty && process.stdout.write('\u001b[?25h');
},
- deleteLine: function () {
+ deleteLine: function() {
isatty && process.stdout.write('\u001b[2K');
},
- beginningOfLine: function () {
+ beginningOfLine: function() {
isatty && process.stdout.write('\u001b[0G');
},
- CR: function () {
+ CR: function() {
if (isatty) {
exports.cursor.deleteLine();
exports.cursor.beginningOfLine();
@@ -155,11 +159,16 @@
}
};
-function showDiff (err) {
- return err && err.showDiff !== false && sameType(err.actual, err.expected) && err.expected !== undefined;
+function showDiff(err) {
+ return (
+ err &&
+ err.showDiff !== false &&
+ sameType(err.actual, err.expected) &&
+ err.expected !== undefined
+ );
}
-function stringifyDiffObjs (err) {
+function stringifyDiffObjs(err) {
if (!utils.isString(err.actual) || !utils.isString(err.expected)) {
err.actual = utils.stringify(err.actual);
err.expected = utils.stringify(err.expected);
@@ -167,17 +176,37 @@
}
/**
+ * Returns a diff between 2 strings with coloured ANSI output.
+ *
+ * The diff will be either inline or unified dependant on the value
+ * of `Base.inlineDiff`.
+ *
+ * @param {string} actual
+ * @param {string} expected
+ * @return {string} Diff
+ */
+var generateDiff = (exports.generateDiff = function(actual, expected) {
+ return exports.inlineDiffs
+ ? inlineDiff(actual, expected)
+ : unifiedDiff(actual, expected);
+});
+
+/**
* Output the given `failures` as a list.
*
+ * @public
+ * @memberof Mocha.reporters.Base
+ * @variation 1
* @param {Array} failures
* @api public
*/
-exports.list = function (failures) {
+exports.list = function(failures) {
console.log();
- failures.forEach(function (test, i) {
+ failures.forEach(function(test, i) {
// format
- var fmt = color('error title', ' %s) %s:\n') +
+ var fmt =
+ color('error title', ' %s) %s:\n') +
color('error message', ' %s') +
color('error stack', '\n%s\n');
@@ -211,15 +240,12 @@
// explicitly show diff
if (!exports.hideDiff && showDiff(err)) {
stringifyDiffObjs(err);
- fmt = color('error title', ' %s) %s:\n%s') + color('error stack', '\n%s\n');
+ 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);
- } else {
- msg += unifiedDiff(err);
- }
+ msg += generateDiff(err.actual, err.expected);
}
// indent stack trace
@@ -227,7 +253,7 @@
// indented test title
var testTitle = '';
- test.titlePath().forEach(function (str, index) {
+ test.titlePath().forEach(function(str, index) {
if (index !== 0) {
testTitle += '\n ';
}
@@ -237,7 +263,7 @@
testTitle += str;
});
- console.log(fmt, (i + 1), testTitle, msg, stack);
+ console.log(fmt, i + 1, testTitle, msg, stack);
});
};
@@ -249,13 +275,22 @@
* stats such as test duration, number
* of tests passed / failed etc.
*
+ * @memberof Mocha.reporters
+ * @public
+ * @class
* @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 = [];
+function Base(runner) {
+ var stats = (this.stats = {
+ suites: 0,
+ tests: 0,
+ passes: 0,
+ pending: 0,
+ failures: 0
+ });
+ var failures = (this.failures = []);
if (!runner) {
return;
@@ -264,21 +299,21 @@
runner.stats = stats;
- runner.on('start', function () {
+ runner.on('start', function() {
stats.start = new Date();
});
- runner.on('suite', function (suite) {
+ runner.on('suite', function(suite) {
stats.suites = stats.suites || 0;
suite.root || stats.suites++;
});
- runner.on('test end', function () {
+ runner.on('test end', function() {
stats.tests = stats.tests || 0;
stats.tests++;
});
- runner.on('pass', function (test) {
+ runner.on('pass', function(test) {
stats.passes = stats.passes || 0;
if (test.duration > test.slow()) {
@@ -292,7 +327,7 @@
stats.passes++;
});
- runner.on('fail', function (test, err) {
+ runner.on('fail', function(test, err) {
stats.failures = stats.failures || 0;
stats.failures++;
if (showDiff(err)) {
@@ -302,12 +337,12 @@
failures.push(test);
});
- runner.on('end', function () {
+ runner.once('end', function() {
stats.end = new Date();
stats.duration = stats.end - stats.start;
});
- runner.on('pending', function () {
+ runner.on('pending', function() {
stats.pending++;
});
}
@@ -316,27 +351,27 @@
* Output common epilogue used by many of
* the bundled reporters.
*
+ * @memberof Mocha.reporters.Base
+ * @public
* @api public
*/
-Base.prototype.epilogue = function () {
+Base.prototype.epilogue = function() {
var stats = this.stats;
var fmt;
console.log();
// passes
- fmt = color('bright pass', ' ') +
+ fmt =
+ color('bright pass', ' ') +
color('green', ' %d passing') +
color('light', ' (%s)');
- console.log(fmt,
- stats.passes || 0,
- ms(stats.duration));
+ console.log(fmt, stats.passes || 0, ms(stats.duration));
// pending
if (stats.pending) {
- fmt = color('pending', ' ') +
- color('pending', ' %d pending');
+ fmt = color('pending', ' ') + color('pending', ' %d pending');
console.log(fmt, stats.pending);
}
@@ -362,32 +397,36 @@
* @param {string} len
* @return {string}
*/
-function pad (str, len) {
+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
+ * Returns an inline diff between 2 strings with coloured ANSI output.
*
* @api private
- * @param {Error} err with actual/expected
+ * @param {String} actual
+ * @param {String} expected
* @return {string} Diff
*/
-function inlineDiff (err) {
- var msg = errorDiff(err);
+function inlineDiff(actual, expected) {
+ var msg = errorDiff(actual, expected);
// linenos
var lines = msg.split('\n');
if (lines.length > 4) {
var width = String(lines.length).length;
- msg = lines.map(function (str, i) {
+ msg = lines
+ .map(function(str, i) {
return pad(++i, width) + ' |' + ' ' + str;
- }).join('\n');
+ })
+ .join('\n');
}
// legend
- msg = '\n' +
+ msg =
+ '\n' +
color('diff removed', 'actual') +
' ' +
color('diff added', 'expected') +
@@ -401,15 +440,16 @@
}
/**
- * Returns a unified diff between two strings.
+ * Returns a unified diff between two strings with coloured ANSI output.
*
* @api private
- * @param {Error} err with actual/expected
+ * @param {String} actual
+ * @param {String} expected
* @return {string} The diff.
*/
-function unifiedDiff (err) {
+function unifiedDiff(actual, expected) {
var indent = ' ';
- function cleanUp (line) {
+ function cleanUp(line) {
if (line[0] === '+') {
return indent + colorLines('diff added', line);
}
@@ -424,27 +464,36 @@
}
return indent + line;
}
- function notBlank (line) {
+ function notBlank(line) {
return typeof line !== 'undefined' && line !== null;
}
- var msg = diff.createPatch('string', err.actual, err.expected);
+ var msg = diff.createPatch('string', actual, expected);
var lines = msg.split('\n').splice(5);
- return '\n ' +
- colorLines('diff added', '+ expected') + ' ' +
+ return (
+ '\n ' +
+ colorLines('diff added', '+ expected') +
+ ' ' +
colorLines('diff removed', '- actual') +
'\n\n' +
- lines.map(cleanUp).filter(notBlank).join('\n');
+ lines
+ .map(cleanUp)
+ .filter(notBlank)
+ .join('\n')
+ );
}
/**
* Return a character diff for `err`.
*
* @api private
- * @param {Error} err
- * @return {string}
- */
-function errorDiff (err) {
- return diff.diffWordsWithSpace(err.actual, err.expected).map(function (str) {
+ * @param {String} actual
+ * @param {String} expected
+ * @return {string} the diff
+ */
+function errorDiff(actual, expected) {
+ return diff
+ .diffWordsWithSpace(actual, expected)
+ .map(function(str) {
if (str.added) {
return colorLines('diff added', str.value);
}
@@ -452,7 +501,8 @@
return colorLines('diff removed', str.value);
}
return str.value;
- }).join('');
+ })
+ .join('');
}
/**
@@ -463,10 +513,13 @@
* @param {string} str
* @return {string}
*/
-function colorLines (name, str) {
- return str.split('\n').map(function (str) {
+function colorLines(name, str) {
+ return str
+ .split('\n')
+ .map(function(str) {
return color(name, str);
- }).join('\n');
+ })
+ .join('\n');
}
/**
@@ -482,6 +535,6 @@
* @param {Object} b
* @return {boolean}
*/
-function sameType (a, b) {
+function sameType(a, b) {
return objToString.call(a) === objToString.call(b);
}

lib/reporters/doc.js

@@ -1,5 +1,7 @@
'use strict';
-
+/**
+ * @module Doc
+ */
/**
* Module dependencies.
*/
@@ -16,19 +18,23 @@
/**
* Initialize a new `Doc` reporter.
*
+ * @class
+ * @memberof Mocha.reporters
+ * @extends {Base}
+ * @public
* @param {Runner} runner
* @api public
*/
-function Doc (runner) {
+function Doc(runner) {
Base.call(this, runner);
var indents = 2;
- function indent () {
+ function indent() {
return Array(indents).join(' ');
}
- runner.on('suite', function (suite) {
+ runner.on('suite', function(suite) {
if (suite.root) {
return;
}
@@ -39,7 +45,7 @@
console.log('%s<dl>', indent());
});
- runner.on('suite end', function (suite) {
+ runner.on('suite end', function(suite) {
if (suite.root) {
return;
}
@@ -49,16 +55,24 @@
--indents;
});
- runner.on('pass', function (test) {
+ runner.on('pass', function(test) {
console.log('%s <dt>%s</dt>', indent(), utils.escape(test.title));
var code = utils.escape(utils.clean(test.body));
console.log('%s <dd><pre><code>%s</code></pre></dd>', indent(), code);
});
- runner.on('fail', function (test, err) {
- console.log('%s <dt class="error">%s</dt>', indent(), utils.escape(test.title));
+ runner.on('fail', function(test, err) {
+ console.log(
+ '%s <dt class="error">%s</dt>',
+ indent(),
+ utils.escape(test.title)
+ );
var code = utils.escape(utils.clean(test.body));
- console.log('%s <dd class="error"><pre><code>%s</code></pre></dd>', indent(), code);
+ console.log(
+ '%s <dd class="error"><pre><code>%s</code></pre></dd>',
+ indent(),
+ code
+ );
console.log('%s <dd class="error">%s</dd>', indent(), utils.escape(err));
});
}

lib/reporters/dot.js

@@ -1,5 +1,7 @@
'use strict';
-
+/**
+ * @module Dot
+ */
/**
* Module dependencies.
*/
@@ -17,28 +19,32 @@
/**
* Initialize a new `Dot` matrix test reporter.
*
+ * @class
+ * @memberof Mocha.reporters
+ * @extends Mocha.reporters.Base
+ * @public
* @api public
* @param {Runner} runner
*/
-function Dot (runner) {
+function Dot(runner) {
Base.call(this, runner);
var self = this;
- var width = Base.window.width * 0.75 | 0;
+ var width = (Base.window.width * 0.75) | 0;
var n = -1;
- runner.on('start', function () {
+ runner.on('start', function() {
process.stdout.write('\n');
});
- runner.on('pending', function () {
+ runner.on('pending', function() {
if (++n % width === 0) {
process.stdout.write('\n ');
}
process.stdout.write(color('pending', Base.symbols.comma));
});
- runner.on('pass', function (test) {
+ runner.on('pass', function(test) {
if (++n % width === 0) {
process.stdout.write('\n ');
}
@@ -49,14 +55,14 @@
}
});
- runner.on('fail', function () {
+ runner.on('fail', function() {
if (++n % width === 0) {
process.stdout.write('\n ');
}
process.stdout.write(color('fail', Base.symbols.bang));
});
- runner.on('end', function () {
+ runner.once('end', function() {
console.log();
self.epilogue();
});

lib/reporters/html.js

@@ -1,7 +1,9 @@
'use strict';
/* eslint-env browser */
-
+/**
+ * @module HTML
+ */
/**
* Module dependencies.
*/
@@ -34,7 +36,8 @@
* Stats template.
*/
-var statsTemplate = '<ul id="mocha-stats">' +
+var statsTemplate =
+ '<ul id="mocha-stats">' +
'<li class="progress"><canvas width="40" height="40"></canvas></li>' +
'<li class="passes"><a href="javascript:void(0);">passes:</a> <em>0</em></li>' +
'<li class="failures"><a href="javascript:void(0);">failures:</a> <em>0</em></li>' +
@@ -46,10 +49,14 @@
/**
* Initialize a new `HTML` reporter.
*
+ * @public
+ * @class
+ * @memberof Mocha.reporters
+ * @extends Mocha.reporters.Base
* @api public
* @param {Runner} runner
*/
-function HTML (runner) {
+function HTML(runner) {
Base.call(this, runner);
var self = this;
@@ -84,10 +91,10 @@
}
// pass toggle
- on(passesLink, 'click', function (evt) {
+ on(passesLink, 'click', function(evt) {
evt.preventDefault();
unhide();
- var name = (/pass/).test(report.className) ? '' : ' pass';
+ var name = /pass/.test(report.className) ? '' : ' pass';
report.className = report.className.replace(/fail|pass/g, '') + name;
if (report.className.trim()) {
hideSuitesWithout('test pass');
@@ -95,10 +102,10 @@
});
// failure toggle
- on(failuresLink, 'click', function (evt) {
+ on(failuresLink, 'click', function(evt) {
evt.preventDefault();
unhide();
- var name = (/fail/).test(report.className) ? '' : ' fail';
+ var name = /fail/.test(report.className) ? '' : ' fail';
report.className = report.className.replace(/fail|pass/g, '') + name;
if (report.className.trim()) {
hideSuitesWithout('test fail');
@@ -112,14 +119,18 @@
progress.size(40);
}
- runner.on('suite', function (suite) {
+ runner.on('suite', function(suite) {
if (suite.root) {
return;
}
// suite
var url = self.suiteURL(suite);
- var el = fragment('<li class="suite"><h1><a href="%s">%s</a></h1></li>', url, escape(suite.title));
+ var el = fragment(
+ '<li class="suite"><h1><a href="%s">%s</a></h1></li>',
+ url,
+ escape(suite.title)
+ );
// container
stack[0].appendChild(el);
@@ -127,7 +138,7 @@
el.appendChild(stack[0]);
});
- runner.on('suite end', function (suite) {
+ runner.on('suite end', function(suite) {
if (suite.root) {
updateStats();
return;
@@ -135,19 +146,27 @@
stack.shift();
});
- runner.on('pass', function (test) {
+ runner.on('pass', function(test) {
var url = self.testURL(test);
- var markup = '<li class="test pass %e"><h2>%e<span class="duration">%ems</span> ' +
- '<a href="%s" class="replay">' + playIcon + '</a></h2></li>';
+ var markup =
+ '<li class="test pass %e"><h2>%e<span class="duration">%ems</span> ' +
+ '<a href="%s" class="replay">' +
+ playIcon +
+ '</a></h2></li>';
var el = fragment(markup, test.speed, test.title, test.duration, url);
self.addCodeToggle(el, test.body);
appendToStack(el);
updateStats();
});
- runner.on('fail', function (test) {
- var el = fragment('<li class="test fail"><h2>%e <a href="%e" class="replay">' + playIcon + '</a></h2></li>',
- test.title, self.testURL(test));
+ runner.on('fail', function(test) {
+ var el = fragment(
+ '<li class="test fail"><h2>%e <a href="%e" class="replay">' +
+ playIcon +
+ '</a></h2></li>',
+ test.title,
+ self.testURL(test)
+ );
var stackString; // Note: Includes leading newline
var message = test.err.toString();
@@ -162,7 +181,9 @@
if (indexOfMessage === -1) {
stackString = test.err.stack;
} else {
- stackString = test.err.stack.substr(test.err.message.length + indexOfMessage);
+ stackString = test.err.stack.substr(
+ test.err.message.length + indexOfMessage
+ );
}
} else if (test.err.sourceURL && test.err.line !== undefined) {
// Safari doesn't give you a stack. Let's at least provide a source line.
@@ -172,12 +193,21 @@
stackString = stackString || '';
if (test.err.htmlMessage && stackString) {
- el.appendChild(fragment('<div class="html-error">%s\n<pre class="error">%e</pre></div>',
- test.err.htmlMessage, stackString));
+ el.appendChild(
+ fragment(
+ '<div class="html-error">%s\n<pre class="error">%e</pre></div>',
+ test.err.htmlMessage,
+ stackString
+ )
+ );
} else if (test.err.htmlMessage) {
- el.appendChild(fragment('<div class="html-error">%s</div>', test.err.htmlMessage));
+ el.appendChild(
+ fragment('<div class="html-error">%s</div>', test.err.htmlMessage)
+ );
} else {
- el.appendChild(fragment('<pre class="error">%e%e</pre>', message, stackString));
+ el.appendChild(
+ fragment('<pre class="error">%e%e</pre>', message, stackString)
+ );
}
self.addCodeToggle(el, test.body);
@@ -185,22 +215,25 @@
updateStats();
});
- runner.on('pending', function (test) {
- var el = fragment('<li class="test pass pending"><h2>%e</h2></li>', test.title);
+ runner.on('pending', function(test) {
+ var el = fragment(
+ '<li class="test pass pending"><h2>%e</h2></li>',
+ test.title
+ );
appendToStack(el);
updateStats();
});
- function appendToStack (el) {
+ function appendToStack(el) {
// Don't call .appendChild if #mocha-report was already .shift()'ed off the stack.
if (stack[0]) {
stack[0].appendChild(el);
}
}
- function updateStats () {
+ function updateStats() {
// TODO: add to stats
- var percent = stats.tests / runner.total * 100 | 0;
+ var percent = (stats.tests / runner.total * 100) | 0;
if (progress) {
progress.update(percent).draw(ctx);
}
@@ -219,7 +252,7 @@
* @param {string} s
* @return {string} A new URL.
*/
-function makeUrl (s) {
+function makeUrl(s) {
var search = window.location.search;
// Remove previous grep query parameter if present
@@ -227,7 +260,12 @@
search = search.replace(/[?&]grep=[^&\s]*/g, '').replace(/^&/, '?');
}
- return window.location.pathname + (search ? search + '&' : '?') + 'grep=' + encodeURIComponent(escapeRe(s));
+ return (
+ window.location.pathname +
+ (search ? search + '&' : '?') +
+ 'grep=' +
+ encodeURIComponent(escapeRe(s))
+ );
}
/**
@@ -235,7 +273,7 @@
*
* @param {Object} [suite]
*/
-HTML.prototype.suiteURL = function (suite) {
+HTML.prototype.suiteURL = function(suite) {
return makeUrl(suite.fullTitle());
};
@@ -244,7 +282,7 @@
*
* @param {Object} [test]
*/
-HTML.prototype.testURL = function (test) {
+HTML.prototype.testURL = function(test) {
return makeUrl(test.fullTitle());
};
@@ -254,10 +292,10 @@
* @param {HTMLLIElement} el
* @param {string} contents
*/
-HTML.prototype.addCodeToggle = function (el, contents) {
+HTML.prototype.addCodeToggle = function(el, contents) {
var h2 = el.getElementsByTagName('h2')[0];
- on(h2, 'click', function () {
+ on(h2, 'click', function() {
pre.style.display = pre.style.display === 'none' ? 'block' : 'none';
});
@@ -271,7 +309,7 @@
*
* @param {string} msg
*/
-function error (msg) {
+function error(msg) {
document.body.appendChild(fragment('<div id="mocha-error">%s</div>', msg));
}
@@ -280,15 +318,17 @@
*
* @param {string} html
*/
-function fragment (html) {
+function fragment(html) {
var args = arguments;
var div = document.createElement('div');
var i = 1;
- div.innerHTML = html.replace(/%([se])/g, function (_, type) {
+ div.innerHTML = html.replace(/%([se])/g, function(_, type) {
switch (type) {
- case 's': return String(args[i++]);
- case 'e': return escape(args[i++]);
+ case 's':
+ return String(args[i++]);
+ case 'e':
+ return escape(args[i++]);
// no default
}
});
@@ -302,7 +342,7 @@
*
* @param {text} classname
*/
-function hideSuitesWithout (classname) {
+function hideSuitesWithout(classname) {
var suites = document.getElementsByClassName('suite');
for (var i = 0; i < suites.length; i++) {
var els = suites[i].getElementsByClassName(classname);
@@ -315,7 +355,7 @@
/**
* Unhide .hidden suites.
*/
-function unhide () {
+function unhide() {
var els = document.getElementsByClassName('suite hidden');
for (var i = 0; i < els.length; ++i) {
els[i].className = els[i].className.replace('suite hidden', 'suite');
@@ -328,7 +368,7 @@
* @param {HTMLElement} el
* @param {string} contents
*/
-function text (el, contents) {
+function text(el, contents) {
if (el.textContent) {
el.textContent = contents;
} else {
@@ -339,7 +379,7 @@
/**
* Listen on `event` with callback `fn`.
*/
-function on (el, event, fn) {
+function on(el, event, fn) {
if (el.addEventListener) {
el.addEventListener(event, fn, false);
} else {

lib/reporters/json.js

@@ -1,5 +1,7 @@
'use strict';
-
+/**
+ * @module JSON
+ */
/**
* Module dependencies.
*/
@@ -15,10 +17,14 @@
/**
* Initialize a new `JSON` reporter.
*
+ * @public
+ * @class JSON
+ * @memberof Mocha.reporters
+ * @extends Mocha.reporters.Base
* @api public
* @param {Runner} runner
*/
-function JSONReporter (runner) {
+function JSONReporter(runner) {
Base.call(this, runner);
var self = this;
@@ -27,23 +33,23 @@
var failures = [];
var passes = [];
- runner.on('test end', function (test) {
+ runner.on('test end', function(test) {
tests.push(test);
});
- runner.on('pass', function (test) {
+ runner.on('pass', function(test) {
passes.push(test);
});
- runner.on('fail', function (test) {
+ runner.on('fail', function(test) {
failures.push(test);
});
- runner.on('pending', function (test) {
+ runner.on('pending', function(test) {
pending.push(test);
});
- runner.on('end', function () {
+ runner.once('end', function() {
var obj = {
stats: self.stats,
tests: tests.map(clean),
@@ -66,26 +72,55 @@
* @param {Object} test
* @return {Object}
*/
-function clean (test) {
+function clean(test) {
+ var err = test.err || {};
+ if (err instanceof Error) {
+ err = errorJSON(err);
+ }
+
return {
title: test.title,
fullTitle: test.fullTitle(),
duration: test.duration,
currentRetry: test.currentRetry(),
- err: errorJSON(test.err || {})
+ err: cleanCycles(err)
};
}
/**
- * Transform `error` into a JSON object.
+ * Replaces any circular references inside `obj` with '[object Object]'
+ *
+ * @api private
+ * @param {Object} obj
+ * @return {Object}
+ */
+function cleanCycles(obj) {
+ var cache = [];
+ return JSON.parse(
+ JSON.stringify(obj, function(key, value) {
+ if (typeof value === 'object' && value !== null) {
+ if (cache.indexOf(value) !== -1) {
+ // Instead of going in a circle, we'll print [object Object]
+ return '' + value;
+ }
+ cache.push(value);
+ }
+
+ return value;
+ })
+ );
+}
+
+/**
+ * Transform an Error object into a JSON object.
*
* @api private
* @param {Error} err
* @return {Object}
*/
-function errorJSON (err) {
+function errorJSON(err) {
var res = {};
- Object.getOwnPropertyNames(err).forEach(function (key) {
+ Object.getOwnPropertyNames(err).forEach(function(key) {
res[key] = err[key];
}, err);
return res;

lib/reporters/json.js.orig

@@ -0,0 +1,128 @@
+'use strict';
+
+/**
+ * Module dependencies.
+ */
+
+var Base = require('./base');
+
+/**
+ * Expose `JSON`.
+ */
+
+exports = module.exports = JSONReporter;
+
+/**
+ * Initialize a new `JSON` reporter.
+ *
+ * @api public
+ * @param {Runner} runner
+ * @param {options} mocha invocation options. Invoking
+ * `mocha -R --reporter-options output-file=asdf` yields options like:
+ * { ... reporterOptions: { "output-file": "asdf" } ... }
+ */
+function JSONReporter (runner, options) {
+<<<<<<< HEAD
+=======
+ options = options || {};
+ var reptOptions = options.reporterOptions || {};
+>>>>>>> + json ouput controls: output-file, output-object
+ Base.call(this, runner);
+
+ var self = this;
+ var tests = [];
+ var pending = [];
+ var failures = [];
+ var passes = [];
+
+ runner.on('test end', function (test) {
+ tests.push(test);
+ });
+
+ runner.on('pass', function (test) {
+ passes.push(test);
+ });
+
+ runner.on('fail', function (test) {
+ failures.push(test);
+ });
+
+ runner.on('pending', function (test) {
+ pending.push(test);
+ });
+
+ runner.once('end', function () {
+ var obj = {
+ stats: self.stats,
+ tests: tests.map(clean),
+ pending: pending.map(clean),
+ failures: failures.map(clean),
+ passes: passes.map(clean)
+ };
+
+ runner.testResults = obj;
+<<<<<<< HEAD
+ if ('output-object' in options.reporterOptions) {
+ // Pass to reporter with: reporter("json", {"output-object": myObject})
+ Object.assign(options.reporterOptions['output-object'], obj);
+ } else {
+ var text = JSON.stringify(obj, null, 2);
+ if ('output-file' in options.reporterOptions) {
+ // Direct output with `mocha -R --reporter-options output-file=rpt.json`
+ try {
+ require('fs').writeFileSync(options.reporterOptions['output-file'], text);
+ } catch (e) {
+ console.warn('error writing to ' + options.reporterOptions.output + ':', e);
+=======
+ if ('output-object' in reptOptions) {
+ // Pass to reporter with: reporter("json", {"output-object": myObject})
+ Object.assign(reptOptions['output-object'], obj);
+ } else {
+ var text = JSON.stringify(obj, null, 2);
+ if ('output-file' in reptOptions) {
+ // Direct output with `mocha -R --reporter-options output-file=rpt.json`
+ try {
+ require('fs').writeFileSync(reptOptions['output-file'], text);
+ } catch (e) {
+ console.warn('error writing to ' + reptOptions.output + ':', e);
+>>>>>>> + json ouput controls: output-file, output-object
+ }
+ } else {
+ process.stdout.write(text);
+ }
+ }
+ });
+}
+
+/**
+ * Return a plain-object representation of `test`
+ * free of cyclic properties etc.
+ *
+ * @api private
+ * @param {Object} test
+ * @return {Object}
+ */
+function clean (test) {
+ return {
+ title: test.title,
+ fullTitle: test.fullTitle(),
+ duration: test.duration,
+ currentRetry: test.currentRetry(),
+ err: errorJSON(test.err || {})
+ };
+}
+
+/**
+ * Transform `error` into a JSON object.
+ *
+ * @api private
+ * @param {Error} err
+ * @return {Object}
+ */
+function errorJSON (err) {
+ var res = {};
+ Object.getOwnPropertyNames(err).forEach(function (key) {
+ res[key] = err[key];
+ }, err);
+ return res;
+}

lib/reporters/json-stream.js

@@ -1,5 +1,7 @@
'use strict';
-
+/**
+ * @module JSONStream
+ */
/**
* Module dependencies.
*/
@@ -13,33 +15,38 @@
exports = module.exports = List;
/**
- * Initialize a new `List` test reporter.
+ * Initialize a new `JSONStream` test reporter.
*
+ * @public
+ * @name JSONStream
+ * @class JSONStream
+ * @memberof Mocha.reporters
+ * @extends Mocha.reporters.Base
* @api public
* @param {Runner} runner
*/
-function List (runner) {
+function List(runner) {
Base.call(this, runner);
var self = this;
var total = runner.total;
- runner.on('start', function () {
- console.log(JSON.stringify(['start', { total: total }]));
+ runner.on('start', function() {
+ console.log(JSON.stringify(['start', {total: total}]));
});
- runner.on('pass', function (test) {
+ runner.on('pass', function(test) {
console.log(JSON.stringify(['pass', clean(test)]));
});
- runner.on('fail', function (test, err) {
+ runner.on('fail', function(test, err) {
test = clean(test);
test.err = err.message;
test.stack = err.stack || null;
console.log(JSON.stringify(['fail', test]));
});
- runner.on('end', function () {
+ runner.once('end', function() {
process.stdout.write(JSON.stringify(['end', self.stats]));
});
}
@@ -52,7 +59,7 @@
* @param {Object} test
* @return {Object}
*/
-function clean (test) {
+function clean(test) {
return {
title: test.title,
fullTitle: test.fullTitle(),

lib/reporters/landing.js

@@ -1,5 +1,7 @@
'use strict';
-
+/**
+ * @module Landing
+ */
/**
* Module dependencies.
*/
@@ -36,33 +38,37 @@
/**
* Initialize a new `Landing` reporter.
*
+ * @public
+ * @class
+ * @memberof Mocha.reporters
+ * @extends Mocha.reporters.Base
* @api public
* @param {Runner} runner
*/
-function Landing (runner) {
+function Landing(runner) {
Base.call(this, runner);
var self = this;
- var width = Base.window.width * 0.75 | 0;
+ var width = (Base.window.width * 0.75) | 0;
var total = runner.total;
var stream = process.stdout;
var plane = color('plane', '✈');
var crashed = -1;
var n = 0;
- function runway () {
+ function runway() {
var buf = Array(width).join('-');
return ' ' + color('runway', buf);
}
- runner.on('start', function () {
+ runner.on('start', function() {
stream.write('\n\n\n ');
cursor.hide();
});
- runner.on('test end', function (test) {
+ runner.on('test end', function(test) {
// check if the plane crashed
- var col = crashed === -1 ? width * ++n / total | 0 : crashed;
+ var col = crashed === -1 ? (width * ++n / total) | 0 : crashed;
// show the crash
if (test.state === 'failed') {
@@ -81,7 +87,7 @@
stream.write('\u001b[0m');
});
- runner.on('end', function () {
+ runner.once('end', function() {
cursor.show();
console.log();
self.epilogue();

lib/reporters/list.js

@@ -1,5 +1,7 @@
'use strict';
-
+/**
+ * @module List
+ */
/**
* Module dependencies.
*/
@@ -18,43 +20,47 @@
/**
* Initialize a new `List` test reporter.
*
+ * @public
+ * @class
+ * @memberof Mocha.reporters
+ * @extends Mocha.reporters.Base
* @api public
* @param {Runner} runner
*/
-function List (runner) {
+function List(runner) {
Base.call(this, runner);
var self = this;
var n = 0;
- runner.on('start', function () {
+ runner.on('start', function() {
console.log();
});
- runner.on('test', function (test) {
+ runner.on('test', function(test) {
process.stdout.write(color('pass', ' ' + test.fullTitle() + ': '));
});
- runner.on('pending', function (test) {
- var fmt = color('checkmark', ' -') +
- color('pending', ' %s');
+ runner.on('pending', function(test) {
+ var fmt = color('checkmark', ' -') + color('pending', ' %s');
console.log(fmt, test.fullTitle());
});
- runner.on('pass', function (test) {
- var fmt = color('checkmark', ' ' + Base.symbols.ok) +
+ runner.on('pass', function(test) {
+ var fmt =
+ color('checkmark', ' ' + Base.symbols.ok) +
color('pass', ' %s: ') +
color(test.speed, '%dms');
cursor.CR();
console.log(fmt, test.fullTitle(), test.duration);
});
- runner.on('fail', function (test) {
+ runner.on('fail', function(test) {
cursor.CR();
console.log(color('fail', ' %d) %s'), ++n, test.fullTitle());
});
- runner.on('end', self.epilogue.bind(self));
+ runner.once('end', self.epilogue.bind(self));
}
/**

lib/reporters/markdown.js

@@ -1,5 +1,7 @@
'use strict';
-
+/**
+ * @module Markdown
+ */
/**
* Module dependencies.
*/
@@ -22,32 +24,36 @@
/**
* Initialize a new `Markdown` reporter.
*
+ * @public
+ * @class
+ * @memberof Mocha.reporters
+ * @extends Mocha.reporters.Base
* @api public
* @param {Runner} runner
*/
-function Markdown (runner) {
+function Markdown(runner) {
Base.call(this, runner);
var level = 0;
var buf = '';
- function title (str) {
+ function title(str) {
return Array(level).join('#') + ' ' + str;
}
- function mapTOC (suite, obj) {
+ function mapTOC(suite, obj) {
var ret = obj;
var key = SUITE_PREFIX + suite.title;
- obj = obj[key] = obj[key] || { suite: suite };
- suite.suites.forEach(function (suite) {
+ obj = obj[key] = obj[key] || {suite: suite};
+ suite.suites.forEach(function(suite) {
mapTOC(suite, obj);
});
return ret;
}
- function stringifyTOC (obj, level) {
+ function stringifyTOC(obj, level) {
++level;
var buf = '';
var link;
@@ -65,25 +71,25 @@
return buf;
}
- function generateTOC (suite) {
+ function generateTOC(suite) {
var obj = mapTOC(suite, {});
return stringifyTOC(obj, 0);
}
generateTOC(runner.suite);
- runner.on('suite', function (suite) {
+ runner.on('suite', function(suite) {
++level;
var slug = utils.slug(suite.fullTitle());
buf += '<a name="' + slug + '"></a>' + '\n';
buf += title(suite.title) + '\n';
});
- runner.on('suite end', function () {
+ runner.on('suite end', function() {
--level;
});
- runner.on('pass', function (test) {
+ runner.on('pass', function(test) {
var code = utils.clean(test.body);
buf += test.title + '.\n';
buf += '\n```js\n';
@@ -91,7 +97,7 @@
buf += '```\n\n';
});
- runner.on('end', function () {
+ runner.once('end', function() {
process.stdout.write('# TOC\n');
process.stdout.write(generateTOC(runner.suite));
process.stdout.write(buf);

lib/reporters/min.js

@@ -1,5 +1,7 @@
'use strict';
-
+/**
+ * @module Min
+ */
/**
* Module dependencies.
*/
@@ -16,20 +18,24 @@
/**
* Initialize a new `Min` minimal test reporter (best used with --watch).
*
+ * @public
+ * @class
+ * @memberof Mocha.reporters
+ * @extends Mocha.reporters.Base
* @api public
* @param {Runner} runner
*/
-function Min (runner) {
+function Min(runner) {
Base.call(this, runner);
- runner.on('start', function () {
+ runner.on('start', function() {
// clear screen
process.stdout.write('\u001b[2J');
// set cursor position
process.stdout.write('\u001b[1;3H');
});
- runner.on('end', this.epilogue.bind(this));
+ runner.once('end', this.epilogue.bind(this));
}
/**

lib/reporters/nyan.js

@@ -1,5 +1,7 @@
'use strict';
-
+/**
+ * @module Nyan
+ */
/**
* Module dependencies.
*/
@@ -18,14 +20,18 @@
*
* @param {Runner} runner
* @api public
+ * @public
+ * @class Nyan
+ * @memberof Mocha.reporters
+ * @extends Mocha.reporters.Base
*/
-function NyanCat (runner) {
+function NyanCat(runner) {
Base.call(this, runner);
var self = this;
- var width = Base.window.width * 0.75 | 0;
- var nyanCatWidth = this.nyanCatWidth = 11;
+ var width = (Base.window.width * 0.75) | 0;
+ var nyanCatWidth = (this.nyanCatWidth = 11);
this.colorIndex = 0;
this.numberOfLines = 4;
@@ -33,26 +39,26 @@
this.scoreboardWidth = 5;
this.tick = 0;
this.trajectories = [[], [], [], []];
- this.trajectoryWidthMax = (width - nyanCatWidth);
+ this.trajectoryWidthMax = width - nyanCatWidth;
- runner.on('start', function () {
+ runner.on('start', function() {
Base.cursor.hide();
self.draw();
});
- runner.on('pending', function () {
+ runner.on('pending', function() {
self.draw();
});
- runner.on('pass', function () {
+ runner.on('pass', function() {
self.draw();
});
- runner.on('fail', function () {
+ runner.on('fail', function() {
self.draw();
});
- runner.on('end', function () {
+ runner.once('end', function() {
Base.cursor.show();
for (var i = 0; i < self.numberOfLines; i++) {
write('\n');
@@ -72,7 +78,7 @@
* @api private
*/
-NyanCat.prototype.draw = function () {
+NyanCat.prototype.draw = function() {
this.appendRainbow();
this.drawScoreboard();
this.drawRainbow();
@@ -87,10 +93,10 @@
* @api private
*/
-NyanCat.prototype.drawScoreboard = function () {
+NyanCat.prototype.drawScoreboard = function() {
var stats = this.stats;
- function draw (type, n) {
+ function draw(type, n) {
write(' ');
write(Base.color(type, n));
write('\n');
@@ -110,7 +116,7 @@
* @api private
*/
-NyanCat.prototype.appendRainbow = function () {
+NyanCat.prototype.appendRainbow = function() {
var segment = this.tick ? '_' : '-';
var rainbowified = this.rainbowify(segment);
@@ -129,10 +135,10 @@
* @api private
*/
-NyanCat.prototype.drawRainbow = function () {
+NyanCat.prototype.drawRainbow = function() {
var self = this;
- this.trajectories.forEach(function (line) {
+ this.trajectories.forEach(function(line) {
write('\u001b[' + self.scoreboardWidth + 'C');
write(line.join(''));
write('\n');
@@ -146,7 +152,7 @@
*
* @api private
*/
-NyanCat.prototype.drawNyanCat = function () {
+NyanCat.prototype.drawNyanCat = function() {
var self = this;
var startWidth = this.scoreboardWidth + this.trajectories[0].length;
var dist = '\u001b[' + startWidth + 'C';
@@ -182,7 +188,7 @@
* @return {string}
*/
-NyanCat.prototype.face = function () {
+NyanCat.prototype.face = function() {
var stats = this.stats;
if (stats.failures) {
return '( x .x)';
@@ -201,7 +207,7 @@
* @param {number} n
*/
-NyanCat.prototype.cursorUp = function (n) {
+NyanCat.prototype.cursorUp = function(n) {
write('\u001b[' + n + 'A');
};
@@ -212,7 +218,7 @@
* @param {number} n
*/
-NyanCat.prototype.cursorDown = function (n) {
+NyanCat.prototype.cursorDown = function(n) {
write('\u001b[' + n + 'B');
};
@@ -222,12 +228,12 @@
* @api private
* @return {Array}
*/
-NyanCat.prototype.generateColors = function () {
+NyanCat.prototype.generateColors = function() {
var colors = [];
- for (var i = 0; i < (6 * 7); i++) {
+ for (var i = 0; i < 6 * 7; i++) {
var pi3 = Math.floor(Math.PI / 3);
- var n = (i * (1.0 / 6));
+ var n = i * (1.0 / 6);
var r = Math.floor(3 * Math.sin(n) + 3);
var g = Math.floor(3 * Math.sin(n + 2 * pi3) + 3);
var b = Math.floor(3 * Math.sin(n + 4 * pi3) + 3);
@@ -244,7 +250,7 @@
* @param {string} str
* @return {string}
*/
-NyanCat.prototype.rainbowify = function (str) {
+NyanCat.prototype.rainbowify = function(str) {
if (!Base.useColors) {
return str;
}
@@ -258,6 +264,6 @@
*
* @param {string} string A message to write to stdout.
*/
-function write (string) {
+function write(string) {
process.stdout.write(string);
}

lib/reporters/progress.js

@@ -1,5 +1,7 @@
'use strict';
-
+/**
+ * @module Progress
+ */
/**
* Module dependencies.
*/
@@ -24,15 +26,19 @@
/**
* Initialize a new `Progress` bar test reporter.
*
+ * @public
+ * @class
+ * @memberof Mocha.reporters
+ * @extends Mocha.reporters.Base
* @api public
* @param {Runner} runner
* @param {Object} options
*/
-function Progress (runner, options) {
+function Progress(runner, options) {
Base.call(this, runner);
var self = this;
- var width = Base.window.width * 0.50 | 0;
+ var width = (Base.window.width * 0.5) | 0;
var total = runner.total;
var complete = 0;
var lastN = -1;
@@ -48,17 +54,17 @@
options.verbose = reporterOptions.verbose || false;
// tests started
- runner.on('start', function () {
+ runner.on('start', function() {
console.log();
cursor.hide();
});
// tests complete
- runner.on('test end', function () {
+ runner.on('test end', function() {
complete++;
var percent = complete / total;
- var n = width * percent | 0;
+ var n = (width * percent) | 0;
var i = width - n;
if (n === lastN && !options.verbose) {
@@ -80,7 +86,7 @@
// tests are complete, output some stats
// and the failures if any
- runner.on('end', function () {
+ runner.once('end', function() {
cursor.show();
console.log();
self.epilogue();

lib/reporters/spec.js

@@ -1,5 +1,7 @@
'use strict';
-
+/**
+ * @module Spec
+ */
/**
* Module dependencies.
*/
@@ -17,50 +19,56 @@
/**
* Initialize a new `Spec` test reporter.
*
+ * @public
+ * @class
+ * @memberof Mocha.reporters
+ * @extends Mocha.reporters.Base
* @api public
* @param {Runner} runner
*/
-function Spec (runner) {
+function Spec(runner) {
Base.call(this, runner);
var self = this;
var indents = 0;
var n = 0;
- function indent () {
+ function indent() {
return Array(indents).join(' ');
}
- runner.on('start', function () {
+ runner.on('start', function() {
console.log();
});
- runner.on('suite', function (suite) {
+ runner.on('suite', function(suite) {
++indents;
console.log(color('suite', '%s%s'), indent(), suite.title);
});
- runner.on('suite end', function () {
+ runner.on('suite end', function() {
--indents;
if (indents === 1) {
console.log();
}
});
- runner.on('pending', function (test) {
+ runner.on('pending', function(test) {
var fmt = indent() + color('pending', ' - %s');
console.log(fmt, test.title);
});
- runner.on('pass', function (test) {
+ runner.on('pass', function(test) {
var fmt;
if (test.speed === 'fast') {
- fmt = indent() +
+ fmt =
+ indent() +
color('checkmark', ' ' + Base.symbols.ok) +
color('pass', ' %s');
console.log(fmt, test.title);
} else {
- fmt = indent() +
+ fmt =
+ indent() +
color('checkmark', ' ' + Base.symbols.ok) +
color('pass', ' %s') +
color(test.speed, ' (%dms)');
@@ -68,11 +76,11 @@
}
});
- runner.on('fail', function (test) {
+ runner.on('fail', function(test) {
console.log(indent() + color('fail', ' %d) %s'), ++n, test.title);
});
- runner.on('end', self.epilogue.bind(self));
+ runner.once('end', self.epilogue.bind(self));
}
/**

lib/reporters/tap.js

@@ -1,5 +1,7 @@
'use strict';
-
+/**
+ * @module TAP
+ */
/**
* Module dependencies.
*/
@@ -15,35 +17,39 @@
/**
* Initialize a new `TAP` reporter.
*
+ * @public
+ * @class
+ * @memberof Mocha.reporters
+ * @extends Mocha.reporters.Base
* @api public
* @param {Runner} runner
*/
-function TAP (runner) {
+function TAP(runner) {
Base.call(this, runner);
var n = 1;
var passes = 0;
var failures = 0;
- runner.on('start', function () {
+ runner.on('start', function() {
var total = runner.grepTotal(runner.suite);
console.log('%d..%d', 1, total);
});
- runner.on('test end', function () {
+ runner.on('test end', function() {
++n;
});
- runner.on('pending', function (test) {
+ runner.on('pending', function(test) {
console.log('ok %d %s # SKIP -', n, title(test));
});
- runner.on('pass', function (test) {
+ runner.on('pass', function(test) {
passes++;
console.log('ok %d %s', n, title(test));
});
- runner.on('fail', function (test, err) {
+ runner.on('fail', function(test, err) {
failures++;
console.log('not ok %d %s', n, title(test));
if (err.stack) {
@@ -51,7 +57,7 @@
}
});
- runner.on('end', function () {
+ runner.once('end', function() {
console.log('# tests ' + (passes + failures));
console.log('# pass ' + passes);
console.log('# fail ' + failures);
@@ -65,6 +71,6 @@
* @param {Object} test
* @return {String}
*/
-function title (test) {
+function title(test) {
return test.fullTitle().replace(/#/g, '');
}

lib/reporters/xunit.js

@@ -1,5 +1,7 @@
'use strict';
-
+/**
+ * @module XUnit
+ */
/**
* Module dependencies.
*/
@@ -33,10 +35,14 @@
/**
* Initialize a new `XUnit` reporter.
*
+ * @public
+ * @class
+ * @memberof Mocha.reporters
+ * @extends Mocha.reporters.Base
* @api public
* @param {Runner} runner
*/
-function XUnit (runner, options) {
+function XUnit(runner, options) {
Base.call(this, runner);
var stats = this.stats;
@@ -66,30 +72,36 @@
// fall back to the default suite name
suiteName = suiteName || DEFAULT_SUITE_NAME;
- runner.on('pending', function (test) {
+ runner.on('pending', function(test) {
tests.push(test);
});
- runner.on('pass', function (test) {
+ runner.on('pass', function(test) {
tests.push(test);
});
- runner.on('fail', function (test) {
+ runner.on('fail', function(test) {
tests.push(test);
});
- runner.on('end', function () {
- self.write(tag('testsuite', {
+ runner.once('end', function() {
+ self.write(
+ tag(
+ 'testsuite',
+ {
name: suiteName,
tests: stats.tests,
failures: stats.failures,
errors: stats.failures,
skipped: stats.tests - stats.failures - stats.passes,
- timestamp: (new Date()).toUTCString(),
- time: (stats.duration / 1000) || 0
- }, false));
+ timestamp: new Date().toUTCString(),
+ time: stats.duration / 1000 || 0
+ },
+ false
+ )
+ );
- tests.forEach(function (t) {
+ tests.forEach(function(t) {
self.test(t);
});
@@ -108,9 +120,9 @@
* @param failures
* @param {Function} fn
*/
-XUnit.prototype.done = function (failures, fn) {
+XUnit.prototype.done = function(failures, fn) {
if (this.fileStream) {
- this.fileStream.end(function () {
+ this.fileStream.end(function() {
fn(failures);
});
} else {
@@ -123,7 +135,7 @@
*
* @param {string} line
*/
-XUnit.prototype.write = function (line) {
+XUnit.prototype.write = function(line) {
if (this.fileStream) {
this.fileStream.write(line + '\n');
} else if (typeof process === 'object' && process.stdout) {
@@ -138,16 +150,28 @@
*
* @param {Test} test
*/
-XUnit.prototype.test = function (test) {
+XUnit.prototype.test = function(test) {
var attrs = {
classname: test.parent.fullTitle(),
name: test.title,
- time: (test.duration / 1000) || 0
+ time: test.duration / 1000 || 0
};
if (test.state === 'failed') {
var err = test.err;
- this.write(tag('testcase', attrs, false, tag('failure', {}, false, escape(err.message) + '\n' + escape(err.stack))));
+ this.write(
+ tag(
+ 'testcase',
+ attrs,
+ false,
+ tag(
+ 'failure',
+ {},
+ false,
+ escape(err.message) + '\n' + escape(err.stack)
+ )
+ )
+ );
} else if (test.isPending()) {
this.write(tag('testcase', attrs, false, tag('skipped', {}, true)));
} else {
@@ -164,7 +188,7 @@
* @param content
* @return {string}
*/
-function tag (name, attrs, close, content) {
+function tag(name, attrs, close, content) {
var end = close ? '/>' : '>';
var pairs = [];
var tag;

lib/runnable.js

@@ -1,9 +1,4 @@
'use strict';
-
-/**
- * Module dependencies.
- */
-
var EventEmitter = require('events').EventEmitter;
var Pending = require('./pending');
var debug = require('debug')('mocha:runnable');
@@ -22,28 +17,19 @@
var clearInterval = global.clearInterval;
/* eslint-enable no-unused-vars, no-native-reassign */
-/**
- * Object#toString().
- */
-
var toString = Object.prototype.toString;
-/**
- * Expose `Runnable`.
- */
-
module.exports = Runnable;
/**
- * Initialize a new `Runnable` with the given `title` and callback `fn`.
+ * Initialize a new `Runnable` with the given `title` and callback `fn`. Derived from [EventEmitter](https://nodejs.org/api/events.html#events_class_eventemitter)
*
+ * @class
+ * @extends EventEmitter
* @param {String} title
* @param {Function} fn
- * @api private
- * @param {string} title
- * @param {Function} fn
*/
-function Runnable (title, fn) {
+function Runnable(title, fn) {
this.title = title;
this.fn = fn;
this.body = (fn || '').toString();
@@ -53,7 +39,6 @@
this._slow = 75;
this._enableTimeouts = true;
this.timedOut = false;
- this._trace = new Error('done() called multiple times');
this._retries = -1;
this._currentRetry = 0;
this.pending = false;
@@ -71,7 +56,7 @@
* @param {number|string} ms
* @return {Runnable|number} ms or Runnable instance.
*/
-Runnable.prototype.timeout = function (ms) {
+Runnable.prototype.timeout = function(ms) {
if (!arguments.length) {
return this._timeout;
}
@@ -97,14 +82,14 @@
* @param {number|string} ms
* @return {Runnable|number} ms or Runnable instance.
*/
-Runnable.prototype.slow = function (ms) {
+Runnable.prototype.slow = function(ms) {
if (!arguments.length || typeof ms === 'undefined') {
return this._slow;
}
if (typeof ms === 'string') {
ms = milliseconds(ms);
}
- debug('timeout %d', ms);
+ debug('slow %d', ms);
this._slow = ms;
return this;
};
@@ -116,7 +101,7 @@
* @param {boolean} enabled
* @return {Runnable|boolean} enabled or Runnable instance.
*/
-Runnable.prototype.enableTimeouts = function (enabled) {
+Runnable.prototype.enableTimeouts = function(enabled) {
if (!arguments.length) {
return this._enableTimeouts;
}
@@ -128,9 +113,11 @@
/**
* Halt and mark as pending.
*
+ * @memberof Mocha.Runnable
+ * @public
* @api public
*/
-Runnable.prototype.skip = function () {
+Runnable.prototype.skip = function() {
throw new Pending('sync skip');
};
@@ -139,16 +126,34 @@
*
* @api private
*/
-Runnable.prototype.isPending = function () {
+Runnable.prototype.isPending = function() {
return this.pending || (this.parent && this.parent.isPending());
};
/**
+ * Return `true` if this Runnable has failed.
+ * @return {boolean}
+ * @private
+ */
+Runnable.prototype.isFailed = function() {
+ return !this.isPending() && this.state === 'failed';
+};
+
+/**
+ * Return `true` if this Runnable has passed.
+ * @return {boolean}
+ * @private
+ */
+Runnable.prototype.isPassed = function() {
+ return !this.isPending() && this.state === 'passed';
+};
+
+/**
* Set or get number of retries.
*
* @api private
*/
-Runnable.prototype.retries = function (n) {
+Runnable.prototype.retries = function(n) {
if (!arguments.length) {
return this._retries;
}
@@ -160,7 +165,7 @@
*
* @api private
*/
-Runnable.prototype.currentRetry = function (n) {
+Runnable.prototype.currentRetry = function(n) {
if (!arguments.length) {
return this._currentRetry;
}
@@ -171,20 +176,24 @@
* Return the full title generated by recursively concatenating the parent's
* full title.
*
+ * @memberof Mocha.Runnable
+ * @public
* @api public
* @return {string}
*/
-Runnable.prototype.fullTitle = function () {
+Runnable.prototype.fullTitle = function() {
return this.titlePath().join(' ');
};
/**
* Return the title path generated by concatenating the parent's title path with the title.
*
+ * @memberof Mocha.Runnable
+ * @public
* @api public
* @return {string}
*/
-Runnable.prototype.titlePath = function () {
+Runnable.prototype.titlePath = function() {
return this.parent.titlePath().concat([this.title]);
};
@@ -193,7 +202,7 @@
*
* @api private
*/
-Runnable.prototype.clearTimeout = function () {
+Runnable.prototype.clearTimeout = function() {
clearTimeout(this.timer);
};
@@ -203,8 +212,10 @@
* @api private
* @return {string}
*/
-Runnable.prototype.inspect = function () {
- return JSON.stringify(this, function (key, val) {
+Runnable.prototype.inspect = function() {
+ return JSON.stringify(
+ this,
+ function(key, val) {
if (key[0] === '_') {
return;
}
@@ -215,7 +226,9 @@
return '#<Context>';
}
return val;
- }, 2);
+ },
+ 2
+ );
};
/**
@@ -223,7 +236,7 @@
*
* @api private
*/
-Runnable.prototype.resetTimeout = function () {
+Runnable.prototype.resetTimeout = function() {
var self = this;
var ms = this.timeout() || 1e9;
@@ -231,12 +244,11 @@
return;
}
this.clearTimeout();
- this.timer = setTimeout(function () {
+ this.timer = setTimeout(function() {
if (!self._enableTimeouts) {
return;
}
- self.callback(new Error('Timeout of ' + ms +
- 'ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves.'));
+ self.callback(self._timeoutError(ms));
self.timedOut = true;
}, ms);
};
@@ -247,7 +259,7 @@
* @api private
* @param {string[]} globals
*/
-Runnable.prototype.globals = function (globals) {
+Runnable.prototype.globals = function(globals) {
if (!arguments.length) {
return this._allowedGlobals;
}
@@ -260,7 +272,7 @@
* @param {Function} fn
* @api private
*/
-Runnable.prototype.run = function (fn) {
+Runnable.prototype.run = function(fn) {
var self = this;
var start = new Date();
var ctx = this.ctx;
@@ -273,16 +285,22 @@
}
// called multiple times
- function multiple (err) {
+ function multiple(err) {
if (emitted) {
return;
}
emitted = true;
- self.emit('error', err || new Error('done() called multiple times; stacktrace may be inaccurate'));
+ var msg = 'done() called multiple times';
+ if (err && err.message) {
+ err.message += " (and Mocha's " + msg + ')';
+ self.emit('error', err);
+ } else {
+ self.emit('error', new Error(msg));
+ }
}
// finished
- function done (err) {
+ function done(err) {
var ms = self.timeout();
if (self.timedOut) {
return;
@@ -287,16 +305,16 @@
if (self.timedOut) {
return;
}
+
if (finished) {
- return multiple(err || self._trace);
+ 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. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves.');
+ err = self._timeoutError(ms);
}
fn(err);
}
@@ -309,7 +327,7 @@
this.resetTimeout();
// allows skip() to be used in an explicit async context
- this.skip = function asyncSkip () {
+ this.skip = function asyncSkip() {
done(new Pending('async skip call'));
// halt execution. the Runnable will be marked pending
// by the previous call, and the uncaught handler will ignore
@@ -350,46 +368,74 @@
done(utils.getError(err));
}
- function callFn (fn) {
+ function callFn(fn) {
var result = fn.call(ctx);
if (result && typeof result.then === 'function') {
self.resetTimeout();
- result
- .then(function () {
+ result.then(
+ function() {
done();
// Return null so libraries like bluebird do not warn about
// subsequently constructed Promises.
return null;
},
- function (reason) {
+ function(reason) {
done(reason || new Error('Promise rejected with no or falsy reason'));
- });
+ }
+ );
} else {
if (self.asyncOnly) {
- return done(new Error('--async-only option in use without declaring `done()` or returning a promise'));
+ return done(
+ new Error(
+ '--async-only option in use without declaring `done()` or returning a promise'
+ )
+ );
}
done();
}
}
- function callFnAsync (fn) {
- var result = fn.call(ctx, function (err) {
+ function callFnAsync(fn) {
+ var result = fn.call(ctx, function(err) {
if (err instanceof Error || toString.call(err) === '[object Error]') {
return done(err);
}
if (err) {
if (Object.prototype.toString.call(err) === '[object Object]') {
- return done(new Error('done() invoked with non-Error: ' +
- JSON.stringify(err)));
+ return done(
+ new Error('done() invoked with non-Error: ' + JSON.stringify(err))
+ );
}
return done(new Error('done() invoked with non-Error: ' + err));
}
if (result && utils.isPromise(result)) {
- return done(new Error('Resolution method is overspecified. Specify a callback *or* return a Promise; not both.'));
+ return done(
+ new Error(
+ 'Resolution method is overspecified. Specify a callback *or* return a Promise; not both.'
+ )
+ );
}
done();
});
}
};
+
+/**
+ * Instantiates a "timeout" error
+ *
+ * @param {number} ms - Timeout (in milliseconds)
+ * @returns {Error} a "timeout" error
+ * @private
+ */
+Runnable.prototype._timeoutError = function(ms) {
+ var msg =
+ 'Timeout of ' +
+ ms +
+ 'ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves.';
+ if (this.file) {
+ msg += ' (' + this.file + ')';
+ }
+ return new Error(msg);
+};

lib/runner.js

@@ -1,9 +1,11 @@
'use strict';
/**
+ * @module Runner
+ */
+/**
* Module dependencies.
*/
-
var EventEmitter = require('events').EventEmitter;
var Pending = require('./pending');
var utils = require('./utils');
@@ -37,7 +39,7 @@
module.exports = Runner;
/**
- * Initialize a `Runner` for the given `suite`.
+ * Initialize a `Runner` for the given `suite`. Derived from [EventEmitter](https://nodejs.org/api/events.html#events_class_eventemitter)
*
* Events:
*
@@ -53,12 +55,15 @@
* - `fail` (test, err) test failed
* - `pending` (test) test pending
*
+ * @memberof Mocha
+ * @public
+ * @class
* @api public
- * @param {Suite} suite Root suite
+ * @param {Suite} [suite] Root suite
* @param {boolean} [delay] Whether or not to delay execution of root suite
* until ready.
*/
-function Runner (suite, delay) {
+function Runner(suite, delay) {
var self = this;
this._globals = [];
this._abort = false;
@@ -67,10 +72,10 @@
this.started = false;
this.total = suite.total();
this.failures = 0;
- this.on('test end', function (test) {
+ this.on('test end', function(test) {
self.checkGlobals(test);
});
- this.on('hook end', function (hook) {
+ this.on('hook end', function(hook) {
self.checkGlobals(hook);
});
this._defaultGrep = /.*/;
@@ -95,15 +100,14 @@
* 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
+ * @public
+ * @memberof Mocha.Runner
* @param {RegExp} re
* @param {boolean} invert
* @return {Runner} Runner instance.
*/
-Runner.prototype.grep = function (re, invert) {
+Runner.prototype.grep = function(re, invert) {
debug('grep %s', re);
this._grep = re;
this._invert = invert;
@@ -115,17 +119,17 @@
* Returns the number of tests matching the grep search for the
* given suite.
*
- * @param {Suite} suite
- * @return {Number}
+ * @memberof Mocha.Runner
* @api public
+ * @public
* @param {Suite} suite
* @return {number}
*/
-Runner.prototype.grepTotal = function (suite) {
+Runner.prototype.grepTotal = function(suite) {
var self = this;
var total = 0;
- suite.eachTest(function (test) {
+ suite.eachTest(function(test) {
var match = self._grep.test(test.fullTitle());
if (self._invert) {
match = !match;
@@ -144,7 +148,7 @@
* @return {Array}
* @api private
*/
-Runner.prototype.globalProps = function () {
+Runner.prototype.globalProps = function() {
var props = Object.keys(global);
// non-enumerables
@@ -161,13 +165,13 @@
/**
* Allow the given `arr` of globals.
*
- * @param {Array} arr
- * @return {Runner} for chaining
* @api public
+ * @public
+ * @memberof Mocha.Runner
* @param {Array} arr
* @return {Runner} Runner instance.
*/
-Runner.prototype.globals = function (arr) {
+Runner.prototype.globals = function(arr) {
if (!arguments.length) {
return this._globals;
}
@@ -181,7 +185,7 @@
*
* @api private
*/
-Runner.prototype.checkGlobals = function (test) {
+Runner.prototype.checkGlobals = function(test) {
if (this.ignoreLeaks) {
return;
}
@@ -203,7 +207,10 @@
this._globals = this._globals.concat(leaks);
if (leaks.length > 1) {
- this.fail(test, new Error('global leaks detected: ' + leaks.join(', ') + ''));
+ this.fail(
+ test,
+ new Error('global leaks detected: ' + leaks.join(', ') + '')
+ );
} else if (leaks.length) {
this.fail(test, new Error('global leak detected: ' + leaks[0]));
}
@@ -216,7 +223,7 @@
* @param {Test} test
* @param {Error} err
*/
-Runner.prototype.fail = function (test, err) {
+Runner.prototype.fail = function(test, err) {
if (test.isPending()) {
return;
}
@@ -225,18 +232,26 @@
test.state = 'failed';
if (!(err instanceof Error || (err && typeof err.message === 'string'))) {
- err = new Error('the ' + type(err) + ' ' + stringify(err) + ' was thrown, throw an Error :)');
+ err = new Error(
+ 'the ' +
+ type(err) +
+ ' ' +
+ stringify(err) +
+ ' was thrown, throw an Error :)'
+ );
}
try {
- err.stack = (this.fullStackTrace || !err.stack)
- ? err.stack
- : stackFilter(err.stack);
- } catch (ignored) {
+ err.stack =
+ this.fullStackTrace || !err.stack ? err.stack : stackFilter(err.stack);
+ } catch (ignore) {
// some environments do not take kindly to monkeying with the stack
}
this.emit('fail', test, err);
+ if (this.suite.bail()) {
+ this.emit('end');
+ }
};
/**
@@ -259,16 +274,14 @@
* @param {Hook} hook
* @param {Error} err
*/
-Runner.prototype.failHook = function (hook, err) {
+Runner.prototype.failHook = function(hook, err) {
if (hook.ctx && hook.ctx.currentTest) {
hook.originalTitle = hook.originalTitle || hook.title;
- hook.title = hook.originalTitle + ' for "' + hook.ctx.currentTest.title + '"';
+ hook.title =
+ hook.originalTitle + ' for "' + hook.ctx.currentTest.title + '"';
}
this.fail(hook, err);
- if (this.suite.bail()) {
- this.emit('end');
- }
};
/**
@@ -279,12 +292,12 @@
* @param {Function} fn
*/
-Runner.prototype.hook = function (name, fn) {
+Runner.prototype.hook = function(name, fn) {
var suite = this.suite;
var hooks = suite['_' + name];
var self = this;
- function next (i) {
+ function next(i) {
var hook = hooks[i];
if (!hook) {
return fn();
@@ -296,12 +309,12 @@
self.emit('hook', hook);
if (!hook.listeners('error').length) {
- hook.on('error', function (err) {
+ hook.on('error', function(err) {
self.failHook(hook, err);
});
}
- hook.run(function (err) {
+ hook.run(function(err) {
var testError = hook.error();
if (testError) {
self.fail(self.test, testError);
@@ -311,7 +324,7 @@
if (name === 'beforeEach' || name === 'afterEach') {
self.test.pending = true;
} else {
- suite.tests.forEach(function (test) {
+ suite.tests.forEach(function(test) {
test.pending = true;
});
// a pending hook won't be executed twice.
@@ -330,7 +343,7 @@
});
}
- Runner.immediately(function () {
+ Runner.immediately(function() {
next(0);
});
};
@@ -344,11 +357,11 @@
* @param {Array} suites
* @param {Function} fn
*/
-Runner.prototype.hooks = function (name, suites, fn) {
+Runner.prototype.hooks = function(name, suites, fn) {
var self = this;
var orig = this.suite;
- function next (suite) {
+ function next(suite) {
self.suite = suite;
if (!suite) {
@@ -356,7 +369,7 @@
return fn();
}
- self.hook(name, function (err) {
+ self.hook(name, function(err) {
if (err) {
var errSuite = self.suite;
self.suite = orig;
@@ -377,7 +390,7 @@
* @param {Function} fn
* @api private
*/
-Runner.prototype.hookUp = function (name, fn) {
+Runner.prototype.hookUp = function(name, fn) {
var suites = [this.suite].concat(this.parents()).reverse();
this.hooks(name, suites, fn);
};
@@ -389,7 +402,7 @@
* @param {Function} fn
* @api private
*/
-Runner.prototype.hookDown = function (name, fn) {
+Runner.prototype.hookDown = function(name, fn) {
var suites = [this.suite].concat(this.parents());
this.hooks(name, suites, fn);
};
@@ -401,7 +414,7 @@
* @return {Array}
* @api private
*/
-Runner.prototype.parents = function () {
+Runner.prototype.parents = function() {
var suite = this.suite;
var suites = [];
while (suite.parent) {
@@ -417,7 +430,7 @@
* @param {Function} fn
* @api private
*/
-Runner.prototype.runTest = function (fn) {
+Runner.prototype.runTest = function(fn) {
var self = this;
var test = this.test;
@@ -431,7 +444,7 @@
if (this.asyncOnly) {
test.asyncOnly = true;
}
- test.on('error', function (err) {
+ test.on('error', function(err) {
self.fail(test, err);
});
if (this.allowUncaught) {
@@ -452,12 +465,12 @@
* @param {Suite} suite
* @param {Function} fn
*/
-Runner.prototype.runTests = function (suite, fn) {
+Runner.prototype.runTests = function(suite, fn) {
var self = this;
var tests = suite.tests.slice();
var test;
- function hookErr (_, errSuite, after) {
+ function hookErr(_, errSuite, after) {
// before/after Each hook for errSuite failed:
var orig = self.suite;
@@ -467,7 +480,7 @@
if (self.suite) {
// call hookUp afterEach
- self.hookUp('afterEach', function (err2, errSuite2) {
+ self.hookUp('afterEach', function(err2, errSuite2) {
self.suite = orig;
// some hooks may fail even now
if (err2) {
@@ -483,7 +496,7 @@
}
}
- function next (err, errSuite) {
+ function next(err, errSuite) {
// if we bail after first err
if (self.failures && suite._bail) {
return fn();
@@ -540,8 +553,8 @@
}
// execute test and hook(s)
- self.emit('test', self.test = test);
- self.hookDown('beforeEach', function (err, errSuite) {
+ self.emit('test', (self.test = test));
+ self.hookDown('beforeEach', function(err, errSuite) {
if (test.isPending()) {
if (self.forbidPending) {
test.isPending = alwaysFalse;
@@ -557,7 +570,7 @@
return hookErr(err, errSuite, false);
}
self.currentRunnable = self.test;
- self.runTest(function (err) {
+ self.runTest(function(err) {
test = self.test;
if (err) {
var retry = test.currentRetry();
@@ -599,7 +612,7 @@
next();
};
-function alwaysFalse () {
+function alwaysFalse() {
return false;
}
@@ -610,7 +623,7 @@
* @param {Suite} suite
* @param {Function} fn
*/
-Runner.prototype.runSuite = function (suite, fn) {
+Runner.prototype.runSuite = function(suite, fn) {
var i = 0;
var self = this;
var total = this.grepTotal(suite);
@@ -622,9 +635,9 @@
return fn();
}
- this.emit('suite', this.suite = suite);
+ this.emit('suite', (this.suite = suite));
- function next (errSuite) {
+ function next(errSuite) {
if (errSuite) {
// current suite failed on a hook from errSuite
if (errSuite === suite) {
@@ -650,7 +663,7 @@
// huge recursive loop and thus a maximum call stack error.
// See comment in `this.runTests()` for more information.
if (self._grep !== self._defaultGrep) {
- Runner.immediately(function () {
+ Runner.immediately(function() {
self.runSuite(curr, next);
});
} else {
@@ -658,7 +671,7 @@
}
}
- function done (errSuite) {
+ function done(errSuite) {
self.suite = suite;
self.nextSuite = next;
@@ -672,7 +685,7 @@
// remove reference to test
delete self.test;
- self.hook('afterAll', function () {
+ self.hook('afterAll', function() {
self.emit('suite end', suite);
fn(errSuite);
});
@@ -681,7 +694,7 @@
this.nextSuite = next;
- this.hook('beforeAll', function (err) {
+ this.hook('beforeAll', function(err) {
if (err) {
return done();
}
@@ -695,11 +708,17 @@
* @param {Error} err
* @api private
*/
-Runner.prototype.uncaught = function (err) {
+Runner.prototype.uncaught = function(err) {
if (err) {
- debug('uncaught exception %s', err === (function () {
+ debug(
+ 'uncaught exception %s',
+ err ===
+ function() {
return this;
- }.call(err)) ? (err.message || err) : err);
+ }.call(err)
+ ? err.message || err
+ : err
+ );
} else {
debug('uncaught undefined exception');
err = undefinedError();
@@ -726,12 +745,17 @@
runnable.clearTimeout();
- // Ignore errors if complete or pending
- if (runnable.state || runnable.isPending()) {
+ // Ignore errors if already failed or pending
+ // See #3226
+ if (runnable.isFailed() || runnable.isPending()) {
return;
}
+ // we cannot recover gracefully if a Runnable has already passed
+ // then fails asynchronously
+ var alreadyPassed = runnable.isPassed();
+ // this will change the state to "failed" regardless of the current value
this.fail(runnable, err);
-
+ if (!alreadyPassed) {
// recover from test
if (runnable.type === 'test') {
this.emit('test end', runnable);
@@ -740,7 +764,6 @@
}
// recover from hooks
- if (runnable.type === 'hook') {
var errSuite = this.suite;
// if hook failure is in afterEach block
if (runnable.fullTitle().indexOf('after each') > -1) {
@@ -768,8 +791,8 @@
*
* @param {Suite} suite
*/
-function cleanSuiteReferences (suite) {
- function cleanArrReferences (arr) {
+function cleanSuiteReferences(suite) {
+ function cleanArrReferences(arr) {
for (var i = 0; i < arr.length; i++) {
delete arr[i].fn;
}
@@ -800,31 +823,30 @@
* Run the root suite and invoke `fn(failures)`
* on completion.
*
- * @param {Function} fn
- * @return {Runner} for chaining
* @api public
+ * @public
+ * @memberof Mocha.Runner
* @param {Function} fn
* @return {Runner} Runner instance.
*/
-Runner.prototype.run = function (fn) {
+Runner.prototype.run = function(fn) {
var self = this;
var rootSuite = this.suite;
- // If there is an `only` filter
- if (hasOnly(rootSuite)) {
- filterOnly(rootSuite);
- }
+ fn = fn || function() {};
- fn = fn || function () {};
-
- function uncaught (err) {
+ function uncaught(err) {
self.uncaught(err);
}
- function start () {
+ function start() {
+ // If there is an `only` filter
+ if (hasOnly(rootSuite)) {
+ filterOnly(rootSuite);
+ }
self.started = true;
self.emit('start');
- self.runSuite(rootSuite, function () {
+ self.runSuite(rootSuite, function() {
debug('finished running');
self.emit('end');
});
@@ -836,7 +858,7 @@
this.on('suite end', cleanSuiteReferences);
// callback
- this.on('end', function () {
+ this.on('end', function() {
debug('end');
process.removeListener('uncaughtException', uncaught);
fn(self.failures);
@@ -860,10 +882,12 @@
/**
* Cleanly abort execution.
*
+ * @memberof Mocha.Runner
+ * @public
* @api public
* @return {Runner} Runner instance.
*/
-Runner.prototype.abort = function () {
+Runner.prototype.abort = function() {
debug('aborting');
this._abort = true;
@@ -877,7 +901,7 @@
* @returns {Boolean}
* @api private
*/
-function filterOnly (suite) {
+function filterOnly(suite) {
if (suite._onlyTests.length) {
// If the suite contains `only` tests, run those and ignore any nested suites.
suite.tests = suite._onlyTests;
@@ -885,7 +909,7 @@
} else {
// Otherwise, do not run any of the tests in this suite.
suite.tests = [];
- suite._onlySuites.forEach(function (onlySuite) {
+ suite._onlySuites.forEach(function(onlySuite) {
// If there are other `only` tests/suites nested in the current `only` suite, then filter that `only` suite.
// Otherwise, all of the tests on this `only` suite should be run, so don't filter it.
if (hasOnly(onlySuite)) {
@@ -893,8 +917,10 @@
}
});
// Run the `only` suites, as well as any other suites that have `only` tests/suites as descendants.
- suite.suites = suite.suites.filter(function (childSuite) {
- return suite._onlySuites.indexOf(childSuite) !== -1 || filterOnly(childSuite);
+ suite.suites = suite.suites.filter(function(childSuite) {
+ return (
+ suite._onlySuites.indexOf(childSuite) !== -1 || filterOnly(childSuite)
+ );
});
}
// Keep the suite only if there is something to run
@@ -908,8 +934,12 @@
* @returns {Boolean}
* @api private
*/
-function hasOnly (suite) {
- return suite._onlyTests.length || suite._onlySuites.length || suite.suites.some(hasOnly);
+function hasOnly(suite) {
+ return (
+ suite._onlyTests.length ||
+ suite._onlySuites.length ||
+ suite.suites.some(hasOnly)
+ );
}
/**
@@ -920,8 +950,8 @@
* @param {Array} globals
* @return {Array}
*/
-function filterLeaks (ok, globals) {
- return globals.filter(function (key) {
+function filterLeaks(ok, globals) {
+ return globals.filter(function(key) {
// Firefox and Chrome exposes iframes as index inside the window object
if (/^\d+/.test(key)) {
return false;
@@ -930,13 +960,13 @@
// in firefox
// if runner runs in an iframe, this iframe's window.getInterface method
// not init at first it is assigned in some seconds
- if (global.navigator && (/^getInterface/).test(key)) {
+ if (global.navigator && /^getInterface/.test(key)) {
return false;
}
// an iframe could be approached by window[iframeIndex]
// in ie6,7,8 and opera, iframeIndex is enumerable, this could cause leak
- if (global.navigator && (/^\d+/).test(key)) {
+ if (global.navigator && /^\d+/.test(key)) {
return false;
}
@@ -945,7 +975,7 @@
return false;
}
- var matched = ok.filter(function (ok) {
+ var matched = ok.filter(function(ok) {
if (~ok.indexOf('*')) {
return key.indexOf(ok.split('*')[0]) === 0;
}
@@ -961,16 +991,16 @@
* @return {Array}
* @api private
*/
-function extraGlobals () {
+function extraGlobals() {
if (typeof process === 'object' && typeof process.version === 'string') {
var parts = process.version.split('.');
- var nodeVersion = parts.reduce(function (a, v) {
- return a << 8 | v;
+ var nodeVersion = parts.reduce(function(a, v) {
+ return (a << 8) | v;
});
// 'errno' was renamed to process._errno in v0.9.11.
- if (nodeVersion < 0x00090B) {
+ if (nodeVersion < 0x00090b) {
return ['errno'];
}
}

lib/suite.js

@@ -1,4 +1,7 @@
'use strict';
+/**
+ * @module Suite
+ */
/**
* Module dependencies.
@@ -22,12 +24,14 @@
* with the same title is already present, that suite is returned to provide
* nicer reporter and more flexible meta-testing.
*
+ * @memberof Mocha
+ * @public
* @api public
* @param {Suite} parent
* @param {string} title
* @return {Suite}
*/
-exports.create = function (parent, title) {
+exports.create = function(parent, title) {
var suite = new Suite(title, parent.ctx);
suite.parent = parent;
title = suite.fullTitle();
@@ -36,18 +40,24 @@
};
/**
- * Initialize a new `Suite` with the given `title` and `ctx`.
+ * Initialize a new `Suite` with the given `title` and `ctx`. Derived from [EventEmitter](https://nodejs.org/api/events.html#events_class_eventemitter)
*
- * @api private
+ * @memberof Mocha
+ * @public
+ * @class
* @param {string} title
* @param {Context} parentContext
*/
-function Suite (title, parentContext) {
+function Suite(title, parentContext) {
if (!utils.isString(title)) {
- throw new Error('Suite `title` should be a "string" but "' + typeof title + '" was given instead.');
+ throw new Error(
+ 'Suite `title` should be a "string" but "' +
+ typeof title +
+ '" was given instead.'
+ );
}
this.title = title;
- function Context () {}
+ function Context() {}
Context.prototype = parentContext;
this.ctx = new Context();
this.suites = [];
@@ -79,7 +89,7 @@
* @api private
* @return {Suite}
*/
-Suite.prototype.clone = function () {
+Suite.prototype.clone = function() {
var suite = new Suite(this.title);
debug('clone');
suite.ctx = this.ctx;
@@ -98,7 +108,7 @@
* @param {number|string} ms
* @return {Suite|number} for chaining
*/
-Suite.prototype.timeout = function (ms) {
+Suite.prototype.timeout = function(ms) {
if (!arguments.length) {
return this._timeout;
}
@@ -120,7 +130,7 @@
* @param {number|string} n
* @return {Suite|number} for chaining
*/
-Suite.prototype.retries = function (n) {
+Suite.prototype.retries = function(n) {
if (!arguments.length) {
return this._retries;
}
@@ -136,7 +146,7 @@
* @param {boolean} enabled
* @return {Suite|boolean} self or enabled
*/
-Suite.prototype.enableTimeouts = function (enabled) {
+Suite.prototype.enableTimeouts = function(enabled) {
if (!arguments.length) {
return this._enableTimeouts;
}
@@ -152,7 +162,7 @@
* @param {number|string} ms
* @return {Suite|number} for chaining
*/
-Suite.prototype.slow = function (ms) {
+Suite.prototype.slow = function(ms) {
if (!arguments.length) {
return this._slow;
}
@@ -171,7 +181,7 @@
* @param {boolean} bail
* @return {Suite|number} for chaining
*/
-Suite.prototype.bail = function (bail) {
+Suite.prototype.bail = function(bail) {
if (!arguments.length) {
return this._bail;
}
@@ -185,11 +195,30 @@
*
* @api private
*/
-Suite.prototype.isPending = function () {
+Suite.prototype.isPending = function() {
return this.pending || (this.parent && this.parent.isPending());
};
/**
+ * Generic hook-creator.
+ * @private
+ * @param {string} title - Title of hook
+ * @param {Function} fn - Hook callback
+ * @returns {Hook} A new hook
+ */
+Suite.prototype._createHook = function(title, fn) {
+ var hook = new Hook(title, fn);
+ hook.parent = this;
+ hook.timeout(this.timeout());
+ hook.retries(this.retries());
+ hook.enableTimeouts(this.enableTimeouts());
+ hook.slow(this.slow());
+ hook.ctx = this.ctx;
+ hook.file = this.file;
+ return hook;
+};
+
+/**
* Run `fn(test[, done])` before running tests.
*
* @api private
@@ -197,7 +226,7 @@
* @param {Function} fn
* @return {Suite} for chaining
*/
-Suite.prototype.beforeAll = function (title, fn) {
+Suite.prototype.beforeAll = function(title, fn) {
if (this.isPending()) {
return this;
}
@@ -207,13 +236,7 @@
}
title = '"before all" hook' + (title ? ': ' + title : '');
- var hook = new Hook(title, fn);
- hook.parent = this;
- hook.timeout(this.timeout());
- hook.retries(this.retries());
- hook.enableTimeouts(this.enableTimeouts());
- hook.slow(this.slow());
- hook.ctx = this.ctx;
+ var hook = this._createHook(title, fn);
this._beforeAll.push(hook);
this.emit('beforeAll', hook);
return this;
@@ -227,7 +250,7 @@
* @param {Function} fn
* @return {Suite} for chaining
*/
-Suite.prototype.afterAll = function (title, fn) {
+Suite.prototype.afterAll = function(title, fn) {
if (this.isPending()) {
return this;
}
@@ -237,13 +260,7 @@
}
title = '"after all" hook' + (title ? ': ' + title : '');
- var hook = new Hook(title, fn);
- hook.parent = this;
- hook.timeout(this.timeout());
- hook.retries(this.retries());
- hook.enableTimeouts(this.enableTimeouts());
- hook.slow(this.slow());
- hook.ctx = this.ctx;
+ var hook = this._createHook(title, fn);
this._afterAll.push(hook);
this.emit('afterAll', hook);
return this;
@@ -257,7 +274,7 @@
* @param {Function} fn
* @return {Suite} for chaining
*/
-Suite.prototype.beforeEach = function (title, fn) {
+Suite.prototype.beforeEach = function(title, fn) {
if (this.isPending()) {
return this;
}
@@ -267,13 +284,7 @@
}
title = '"before each" hook' + (title ? ': ' + title : '');
- var hook = new Hook(title, fn);
- hook.parent = this;
- hook.timeout(this.timeout());
- hook.retries(this.retries());
- hook.enableTimeouts(this.enableTimeouts());
- hook.slow(this.slow());
- hook.ctx = this.ctx;
+ var hook = this._createHook(title, fn);
this._beforeEach.push(hook);
this.emit('beforeEach', hook);
return this;
@@ -287,7 +298,7 @@
* @param {Function} fn
* @return {Suite} for chaining
*/
-Suite.prototype.afterEach = function (title, fn) {
+Suite.prototype.afterEach = function(title, fn) {
if (this.isPending()) {
return this;
}
@@ -297,13 +308,7 @@
}
title = '"after each" hook' + (title ? ': ' + title : '');
- var hook = new Hook(title, fn);
- hook.parent = this;
- hook.timeout(this.timeout());
- hook.retries(this.retries());
- hook.enableTimeouts(this.enableTimeouts());
- hook.slow(this.slow());
- hook.ctx = this.ctx;
+ var hook = this._createHook(title, fn);
this._afterEach.push(hook);
this.emit('afterEach', hook);
return this;
@@ -316,7 +321,7 @@
* @param {Suite} suite
* @return {Suite} for chaining
*/
-Suite.prototype.addSuite = function (suite) {
+Suite.prototype.addSuite = function(suite) {
suite.parent = this;
suite.timeout(this.timeout());
suite.retries(this.retries());
@@ -335,7 +340,7 @@
* @param {Test} test
* @return {Suite} for chaining
*/
-Suite.prototype.addTest = function (test) {
+Suite.prototype.addTest = function(test) {
test.parent = this;
test.timeout(this.timeout());
test.retries(this.retries());
@@ -351,10 +356,12 @@
* Return the full title generated by recursively concatenating the parent's
* full title.
*
+ * @memberof Mocha.Suite
+ * @public
* @api public
* @return {string}
*/
-Suite.prototype.fullTitle = function () {
+Suite.prototype.fullTitle = function() {
return this.titlePath().join(' ');
};
@@ -362,10 +369,12 @@
* Return the title path generated by recursively concatenating the parent's
* title path.
*
+ * @memberof Mocha.Suite
+ * @public
* @api public
* @return {string}
*/
-Suite.prototype.titlePath = function () {
+Suite.prototype.titlePath = function() {
var result = [];
if (this.parent) {
result = result.concat(this.parent.titlePath());
@@ -379,13 +388,17 @@
/**
* Return the total number of tests.
*
+ * @memberof Mocha.Suite
+ * @public
* @api public
* @return {number}
*/
-Suite.prototype.total = function () {
- return this.suites.reduce(function (sum, suite) {
+Suite.prototype.total = function() {
+ return (
+ this.suites.reduce(function(sum, suite) {
return sum + suite.total();
- }, 0) + this.tests.length;
+ }, 0) + this.tests.length
+ );
};
/**
@@ -396,9 +409,9 @@
* @param {Function} fn
* @return {Suite}
*/
-Suite.prototype.eachTest = function (fn) {
+Suite.prototype.eachTest = function(fn) {
this.tests.forEach(fn);
- this.suites.forEach(function (suite) {
+ this.suites.forEach(function(suite) {
suite.eachTest(fn);
});
return this;
@@ -407,7 +420,7 @@
/**
* This will run the root suite if we happen to be running in delayed mode.
*/
-Suite.prototype.run = function run () {
+Suite.prototype.run = function run() {
if (this.root) {
this.emit('run');
}

lib/test.js

@@ -1,29 +1,25 @@
'use strict';
-
-/**
- * Module dependencies.
- */
-
var Runnable = require('./runnable');
var utils = require('./utils');
var isString = utils.isString;
-/**
- * Expose `Test`.
- */
-
module.exports = Test;
/**
* Initialize a new `Test` with the given `title` and callback `fn`.
*
- * @api private
+ * @class
+ * @extends Runnable
* @param {String} title
* @param {Function} fn
*/
-function Test (title, fn) {
+function Test(title, fn) {
if (!isString(title)) {
- throw new Error('Test `title` should be a "string" but "' + typeof title + '" was given instead.');
+ throw new Error(
+ 'Test `title` should be a "string" but "' +
+ typeof title +
+ '" was given instead.'
+ );
}
Runnable.call(this, title, fn);
this.pending = !fn;
@@ -35,7 +31,7 @@
*/
utils.inherits(Test, Runnable);
-Test.prototype.clone = function () {
+Test.prototype.clone = function() {
var test = new Test(this.title, this.fn);
test.timeout(this.timeout());
test.slow(this.slow());

lib/utils.js

@@ -1,21 +1,18 @@
'use strict';
-/* eslint-env browser */
+/**
+ * @module
+ */
/**
* Module dependencies.
*/
-var basename = require('path').basename;
var debug = require('debug')('mocha:watch');
-var exists = require('fs').existsSync;
+var fs = require('fs');
var glob = require('glob');
var path = require('path');
var join = path.join;
-var readdirSync = require('fs').readdirSync;
-var statSync = require('fs').statSync;
-var watchFile = require('fs').watchFile;
-var lstatSync = require('fs').lstatSync;
var he = require('he');
/**
@@ -33,8 +30,8 @@
* @param {string} html
* @return {string}
*/
-exports.escape = function (html) {
- return he.encode(String(html), { useNamedReferences: false });
+exports.escape = function(html) {
+ return he.encode(String(html), {useNamedReferences: false});
};
/**
@@ -44,7 +41,7 @@
* @param {Object} obj
* @return {boolean}
*/
-exports.isString = function (obj) {
+exports.isString = function(obj) {
return typeof obj === 'string';
};
@@ -56,11 +53,11 @@
* @param {Array} files
* @param {Function} fn
*/
-exports.watch = function (files, fn) {
- var options = { interval: 100 };
- files.forEach(function (file) {
+exports.watch = function(files, fn) {
+ var options = {interval: 100};
+ files.forEach(function(file) {
debug('file %s', file);
- watchFile(file, options, function (curr, prev) {
+ fs.watchFile(file, options, function(curr, prev) {
if (prev.mtime < curr.mtime) {
fn(file);
}
@@ -75,7 +72,7 @@
* @param {string} path
* @return {boolean}
*/
-function ignored (path) {
+function ignored(path) {
return !~ignore.indexOf(path);
}
@@ -88,17 +85,18 @@
* @param {Array} [ret=[]]
* @return {Array}
*/
-exports.files = function (dir, ext, ret) {
+exports.files = function(dir, ext, ret) {
ret = ret || [];
ext = ext || ['js'];
var re = new RegExp('\\.(' + ext.join('|') + ')$');
- readdirSync(dir)
+ fs
+ .readdirSync(dir)
.filter(ignored)
- .forEach(function (path) {
+ .forEach(function(path) {
path = join(dir, path);
- if (lstatSync(path).isDirectory()) {
+ if (fs.lstatSync(path).isDirectory()) {
exports.files(path, ext, ret);
} else if (path.match(re)) {
ret.push(path);
@@ -115,7 +113,7 @@
* @param {string} str
* @return {string}
*/
-exports.slug = function (str) {
+exports.slug = function(str) {
return str
.toLowerCase()
.replace(/ +/g, '-')
@@ -128,15 +126,22 @@
* @param {string} str
* @return {string}
*/
-exports.clean = function (str) {
+exports.clean = function(str) {
str = str
- .replace(/\r\n?|[\n\u2028\u2029]/g, '\n').replace(/^\uFEFF/, '')
+ .replace(/\r\n?|[\n\u2028\u2029]/g, '\n')
+ .replace(/^\uFEFF/, '')
// (traditional)-> space/name parameters body (lambda)-> parameters body multi-statement/single keep body content
- .replace(/^function(?:\s*|\s+[^(]*)\([^)]*\)\s*\{((?:.|\n)*?)\s*\}$|^\([^)]*\)\s*=>\s*(?:\{((?:.|\n)*?)\s*\}|((?:.|\n)*))$/, '$1$2$3');
+ .replace(
+ /^function(?:\s*|\s+[^(]*)\([^)]*\)\s*\{((?:.|\n)*?)\s*\}$|^\([^)]*\)\s*=>\s*(?:\{((?:.|\n)*?)\s*\}|((?:.|\n)*))$/,
+ '$1$2$3'
+ );
var spaces = str.match(/^\n?( *)/)[1].length;
var tabs = str.match(/^\n?(\t*)/)[1].length;
- var re = new RegExp('^\n?' + (tabs ? '\t' : ' ') + '{' + (tabs || spaces) + '}', 'gm');
+ var re = new RegExp(
+ '^\n?' + (tabs ? '\t' : ' ') + '{' + (tabs || spaces) + '}',
+ 'gm'
+ );
str = str.replace(re, '');
@@ -150,8 +155,11 @@
* @param {string} qs
* @return {Object}
*/
-exports.parseQuery = function (qs) {
- return qs.replace('?', '').split('&').reduce(function (obj, pair) {
+exports.parseQuery = function(qs) {
+ return qs
+ .replace('?', '')
+ .split('&')
+ .reduce(function(obj, pair) {
var i = pair.indexOf('=');
var key = pair.slice(0, i);
var val = pair.slice(++i);
@@ -170,7 +178,7 @@
* @param {string} js
* @return {string}
*/
-function highlight (js) {
+function highlight(js) {
return js
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
@@ -178,8 +186,14 @@
.replace(/('.*?')/gm, '<span class="string">$1</span>')
.replace(/(\d+\.\d+)/gm, '<span class="number">$1</span>')
.replace(/(\d+)/gm, '<span class="number">$1</span>')
- .replace(/\bnew[ \t]+(\w+)/gm, '<span class="keyword">new</span> <span class="init">$1</span>')
- .replace(/\b(function|new|throw|return|var|if|else)\b/gm, '<span class="keyword">$1</span>');
+ .replace(
+ /\bnew[ \t]+(\w+)/gm,
+ '<span class="keyword">new</span> <span class="init">$1</span>'
+ )
+ .replace(
+ /\b(function|new|throw|return|var|if|else)\b/gm,
+ '<span class="keyword">$1</span>'
+ );
}
/**
@@ -188,7 +202,7 @@
* @api private
* @param {string} name
*/
-exports.highlightTags = function (name) {
+exports.highlightTags = function(name) {
var code = document.getElementById('mocha').getElementsByTagName(name);
for (var i = 0, len = code.length; i < len; ++i) {
code[i].innerHTML = highlight(code[i].innerHTML);
@@ -209,7 +223,7 @@
* @param {string} typeHint The type of the value
* @returns {string}
*/
-function emptyRepresentation (value, typeHint) {
+function emptyRepresentation(value, typeHint) {
switch (typeHint) {
case 'function':
return '[Function]';
@@ -243,7 +257,7 @@
* type(global) // 'global'
* type(new String('foo') // 'object'
*/
-var type = exports.type = function type (value) {
+var type = (exports.type = function type(value) {
if (value === undefined) {
return 'undefined';
} else if (value === null) {
@@ -251,10 +265,11 @@
} else if (Buffer.isBuffer(value)) {
return 'buffer';
}
- return Object.prototype.toString.call(value)
+ return Object.prototype.toString
+ .call(value)
.replace(/^\[.+\s(.+?)]$/, '$1')
.toLowerCase();
-};
+});
/**
* Stringify `value`. Different behavior depending on type of value:
@@ -271,21 +286,23 @@
* @param {*} value
* @return {string}
*/
-exports.stringify = function (value) {
+exports.stringify = function(value) {
var typeHint = type(value);
if (!~['object', 'array', 'function'].indexOf(typeHint)) {
if (typeHint === 'buffer') {
var json = Buffer.prototype.toJSON.call(value);
// Based on the toJSON result
- return jsonStringify(json.data && json.type ? json.data : json, 2)
- .replace(/,(\n|$)/g, '$1');
+ return jsonStringify(
+ json.data && json.type ? json.data : json,
+ 2
+ ).replace(/,(\n|$)/g, '$1');
}
// IE7/IE8 has a bizarre String constructor; needs to be coerced
// into an array and back to obj.
if (typeHint === 'string' && typeof value === 'object') {
- value = value.split('').reduce(function (acc, char, idx) {
+ value = value.split('').reduce(function(acc, char, idx) {
acc[idx] = char;
return acc;
}, {});
@@ -297,7 +314,10 @@
for (var prop in value) {
if (Object.prototype.hasOwnProperty.call(value, prop)) {
- return jsonStringify(exports.canonicalize(value, null, typeHint), 2).replace(/,(\n|$)/g, '$1');
+ return jsonStringify(
+ exports.canonicalize(value, null, typeHint),
+ 2
+ ).replace(/,(\n|$)/g, '$1');
}
}
@@ -313,7 +333,7 @@
* @param {number=} depth
* @returns {*}
*/
-function jsonStringify (object, spaces, depth) {
+function jsonStringify(object, spaces, depth) {
if (typeof spaces === 'undefined') {
// primitive types
return _stringify(object);
@@ -323,13 +343,16 @@
var space = spaces * depth;
var str = Array.isArray(object) ? '[' : '{';
var end = Array.isArray(object) ? ']' : '}';
- var length = typeof object.length === 'number' ? object.length : Object.keys(object).length;
+ var length =
+ typeof object.length === 'number'
+ ? object.length
+ : Object.keys(object).length;
// `.repeat()` polyfill
- function repeat (s, n) {
+ function repeat(s, n) {
return new Array(n).join(s);
}
- function _stringify (val) {
+ function _stringify(val) {
switch (type(val)) {
case 'null':
case 'undefined':
@@ -343,7 +366,8 @@
case 'regexp':
case 'symbol':
case 'number':
- val = val === 0 && (1 / val) === -Infinity // `-0`
+ val =
+ val === 0 && 1 / val === -Infinity // `-0`
? '-0'
: val.toString();
break;
@@ -358,7 +382,8 @@
val = '[Buffer: ' + jsonStringify(json, 2, depth + 1) + ']';
break;
default:
- val = (val === '[Function]' || val === '[Circular]')
+ val =
+ val === '[Function]' || val === '[Circular]'
? val
: JSON.stringify(val); // string
}
@@ -370,15 +395,19 @@
continue; // not my business
}
--length;
- str += '\n ' + repeat(' ', space) +
+ str +=
+ '\n ' +
+ repeat(' ', space) +
(Array.isArray(object) ? '' : '"' + i + '": ') + // key
_stringify(object[i]) + // value
(length ? ',' : ''); // comma
}
- return str +
+ return (
+ str +
// [], {}
- (str.length !== 1 ? '\n' + repeat(' ', --space) + end : end);
+ (str.length !== 1 ? '\n' + repeat(' ', --space) + end : end)
+ );
}
/**
@@ -400,13 +429,13 @@
* @param {string} [typeHint] Type hint
* @return {(Object|Array|Function|string|undefined)}
*/
-exports.canonicalize = function canonicalize (value, stack, typeHint) {
+exports.canonicalize = function canonicalize(value, stack, typeHint) {
var canonicalizedObj;
/* eslint-disable no-unused-vars */
var prop;
/* eslint-enable no-unused-vars */
typeHint = typeHint || type(value);
- function withStack (value, fn) {
+ function withStack(value, fn) {
stack.push(value);
fn();
stack.pop();
@@ -425,8 +454,8 @@
canonicalizedObj = value;
break;
case 'array':
- withStack(value, function () {
- canonicalizedObj = value.map(function (item) {
+ withStack(value, function() {
+ canonicalizedObj = value.map(function(item) {
return exports.canonicalize(item, stack);
});
});
@@ -445,8 +474,10 @@
/* falls through */
case 'object':
canonicalizedObj = canonicalizedObj || {};
- withStack(value, function () {
- Object.keys(value).sort().forEach(function (key) {
+ withStack(value, function() {
+ Object.keys(value)
+ .sort()
+ .forEach(function(key) {
canonicalizedObj[key] = exports.canonicalize(value[key], stack);
});
});
@@ -468,41 +499,43 @@
/**
* Lookup file names at the given `path`.
*
+ * @memberof Mocha.utils
+ * @public
* @api public
- * @param {string} path Base path to start searching from.
+ * @param {string} filepath Base path to start searching from.
* @param {string[]} extensions File extensions to look for.
* @param {boolean} recursive Whether or not to recurse into subdirectories.
* @return {string[]} An array of paths.
*/
-exports.lookupFiles = function lookupFiles (path, extensions, recursive) {
+exports.lookupFiles = function lookupFiles(filepath, extensions, recursive) {
var files = [];
- if (!exists(path)) {
- if (exists(path + '.js')) {
- path += '.js';
+ if (!fs.existsSync(filepath)) {
+ if (fs.existsSync(filepath + '.js')) {
+ filepath += '.js';
} else {
- files = glob.sync(path);
+ files = glob.sync(filepath);
if (!files.length) {
- throw new Error("cannot resolve path (or pattern) '" + path + "'");
+ throw new Error("cannot resolve path (or pattern) '" + filepath + "'");
}
return files;
}
}
try {
- var stat = statSync(path);
+ var stat = fs.statSync(filepath);
if (stat.isFile()) {
- return path;
+ return filepath;
}
} catch (err) {
// ignore error
return;
}
- readdirSync(path).forEach(function (file) {
- file = join(path, file);
+ fs.readdirSync(filepath).forEach(function(file) {
+ file = path.join(filepath, file);
try {
- var stat = statSync(file);
+ var stat = fs.statSync(file);
if (stat.isDirectory()) {
if (recursive) {
files = files.concat(lookupFiles(file, extensions, recursive));
@@ -513,8 +546,13 @@
// ignore error
return;
}
+ if (!extensions) {
+ throw new Error(
+ 'extensions parameter required when filepath is a directory'
+ );
+ }
var re = new RegExp('\\.(?:' + extensions.join('|') + ')$');
- if (!stat.isFile() || !re.test(file) || basename(file)[0] === '.') {
+ if (!stat.isFile() || !re.test(file) || path.basename(file)[0] === '.') {
return;
}
files.push(file);
@@ -529,8 +567,10 @@
* @return {Error}
*/
-exports.undefinedError = function () {
- return new Error('Caught undefined error, did you throw without specifying what?');
+exports.undefinedError = function() {
+ return new Error(
+ 'Caught undefined error, did you throw without specifying what?'
+ );
};
/**
@@ -540,7 +580,7 @@
* @return {Error}
*/
-exports.getError = function (err) {
+exports.getError = function(err) {
return err || exports.undefinedError();
};
@@ -553,9 +593,9 @@
* (i.e: strip Mocha and internal node functions from stack trace).
* @returns {Function}
*/
-exports.stackTraceFilter = function () {
+exports.stackTraceFilter = function() {
// TODO: Replace with `process.browser`
- var is = typeof document === 'undefined' ? { node: true } : { browser: true };
+ var is = typeof document === 'undefined' ? {node: true} : {browser: true};
var slash = path.sep;
var cwd;
if (is.node) {
@@ -563,30 +603,35 @@
} else {
cwd = (typeof location === 'undefined'
? window.location
- : location).href.replace(/\/[^/]*$/, '/');
+ : location
+ ).href.replace(/\/[^/]*$/, '/');
slash = '/';
}
- function isMochaInternal (line) {
- return (~line.indexOf('node_modules' + slash + 'mocha' + slash)) ||
- (~line.indexOf('node_modules' + slash + 'mocha.js')) ||
- (~line.indexOf('bower_components' + slash + 'mocha.js')) ||
- (~line.indexOf(slash + 'mocha.js'));
- }
-
- function isNodeInternal (line) {
- return (~line.indexOf('(timers.js:')) ||
- (~line.indexOf('(events.js:')) ||
- (~line.indexOf('(node.js:')) ||
- (~line.indexOf('(module.js:')) ||
- (~line.indexOf('GeneratorFunctionPrototype.next (native)')) ||
- false;
+ function isMochaInternal(line) {
+ return (
+ ~line.indexOf('node_modules' + slash + 'mocha' + slash) ||
+ ~line.indexOf('node_modules' + slash + 'mocha.js') ||
+ ~line.indexOf('bower_components' + slash + 'mocha.js') ||
+ ~line.indexOf(slash + 'mocha.js')
+ );
+ }
+
+ function isNodeInternal(line) {
+ return (
+ ~line.indexOf('(timers.js:') ||
+ ~line.indexOf('(events.js:') ||
+ ~line.indexOf('(node.js:') ||
+ ~line.indexOf('(module.js:') ||
+ ~line.indexOf('GeneratorFunctionPrototype.next (native)') ||
+ false
+ );
}
- return function (stack) {
+ return function(stack) {
stack = stack.split('\n');
- stack = stack.reduce(function (list, line) {
+ stack = stack.reduce(function(list, line) {
if (isMochaInternal(line)) {
return list;
}
@@ -597,7 +642,7 @@
// Clean up cwd(absolute)
if (/\(?.+:\d+:\d+\)?$/.test(line)) {
- line = line.replace(cwd, '');
+ line = line.replace('(' + cwd, '(');
}
list.push(line);
@@ -614,7 +659,7 @@
* @param {*} value
* @returns {boolean} Whether or not `value` is a Promise
*/
-exports.isPromise = function isPromise (value) {
+exports.isPromise = function isPromise(value) {
return typeof value === 'object' && typeof value.then === 'function';
};
@@ -622,4 +667,4 @@
* It's a noop.
* @api
*/
-exports.noop = function () {};
+exports.noop = function() {};

LICENSE

@@ -1,6 +1,6 @@
(The MIT License)
-Copyright (c) 2011-2017 JS Foundation and contributors, https://js.foundation
+Copyright (c) 2011-2018 JS Foundation and contributors, https://js.foundation
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the

mocha.js

@@ -1,4 +1,4 @@
-(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(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
(function (process,global){
'use strict';
@@ -19,7 +19,7 @@
* @return {undefined}
*/
-var mocha = new Mocha({ reporter: 'html' });
+var mocha = new Mocha({reporter: 'html'});
/**
* Save timer references to avoid Sinon interfering (see GH-237).
@@ -40,12 +40,12 @@
* Revert to original onerror handler if previously defined.
*/
-process.removeListener = function (e, fn) {
+process.removeListener = function(e, fn) {
if (e === 'uncaughtException') {
if (originalOnerrorHandler) {
global.onerror = originalOnerrorHandler;
} else {
- global.onerror = function () {};
+ global.onerror = function() {};
}
var i = uncaughtExceptionHandlers.indexOf(fn);
if (i !== -1) {
@@ -58,9 +58,9 @@
* Implements uncaughtException listener.
*/
-process.on = function (e, fn) {
+process.on = function(e, fn) {
if (e === 'uncaughtException') {
- global.onerror = function (err, url, line) {
+ global.onerror = function(err, url, line) {
fn(new Error(err + ' (' + url + ':' + line + ')'));
return !mocha.allowUncaught;
};
@@ -76,9 +76,9 @@
var immediateQueue = [];
var immediateTimeout;
-function timeslice () {
+function timeslice() {
var immediateStart = new Date().getTime();
- while (immediateQueue.length && (new Date().getTime() - immediateStart) < 100) {
+ while (immediateQueue.length && new Date().getTime() - immediateStart < 100) {
immediateQueue.shift()();
}
if (immediateQueue.length) {
@@ -92,7 +92,7 @@
* High-performance override of Runner.immediately.
*/
-Mocha.Runner.immediately = function (callback) {
+Mocha.Runner.immediately = function(callback) {
immediateQueue.push(callback);
if (!immediateTimeout) {
immediateTimeout = setTimeout(timeslice, 0);
@@ -104,8 +104,8 @@
* 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) {
+mocha.throwError = function(err) {
+ uncaughtExceptionHandlers.forEach(function(fn) {
fn(err);
});
throw err;
@@ -116,7 +116,7 @@
* Normally this would happen in Mocha.prototype.loadFiles.
*/
-mocha.ui = function (ui) {
+mocha.ui = function(ui) {
Mocha.prototype.ui.call(this, ui);
this.suite.emit('pre-require', global, null, this);
return this;
@@ -126,9 +126,9 @@
* Setup mocha with the given setting options.
*/
-mocha.setup = function (opts) {
+mocha.setup = function(opts) {
if (typeof opts === 'string') {
- opts = { ui: opts };
+ opts = {ui: opts};
}
for (var opt in opts) {
if (opts.hasOwnProperty(opt)) {
@@ -142,7 +142,7 @@
* Run mocha, returning the Runner.
*/
-mocha.run = function (fn) {
+mocha.run = function(fn) {
var options = mocha.options;
mocha.globals('location');
@@ -157,10 +157,14 @@
mocha.invert();
}
- return Mocha.prototype.run.call(mocha, function (err) {
+ 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) {
+ if (
+ document &&
+ document.getElementById('mocha') &&
+ options.noHighlighting !== true
+ ) {
Mocha.utils.highlightTags('code');
}
if (fn) {
@@ -208,7 +212,7 @@
/**
* Initialize a new `Progress` indicator.
*/
-function Progress () {
+function Progress() {
this.percent = 0;
this.size(0);
this.fontSize(11);
@@ -222,7 +226,7 @@
* @param {number} size
* @return {Progress} Progress instance.
*/
-Progress.prototype.size = function (size) {
+Progress.prototype.size = function(size) {
this._size = size;
return this;
};
@@ -234,7 +238,7 @@
* @param {string} text
* @return {Progress} Progress instance.
*/
-Progress.prototype.text = function (text) {
+Progress.prototype.text = function(text) {
this._text = text;
return this;
};
@@ -246,7 +250,7 @@
* @param {number} size
* @return {Progress} Progress instance.
*/
-Progress.prototype.fontSize = function (size) {
+Progress.prototype.fontSize = function(size) {
this._fontSize = size;
return this;
};
@@ -257,7 +261,7 @@
* @param {string} family
* @return {Progress} Progress instance.
*/
-Progress.prototype.font = function (family) {
+Progress.prototype.font = function(family) {
this._font = family;
return this;
};
@@ -268,7 +272,7 @@
* @param {number} n
* @return {Progress} Progress instance.
*/
-Progress.prototype.update = function (n) {
+Progress.prototype.update = function(n) {
this.percent = n;
return this;
};
@@ -279,7 +283,7 @@
* @param {CanvasRenderingContext2d} ctx
* @return {Progress} Progress instance.
*/
-Progress.prototype.draw = function (ctx) {
+Progress.prototype.draw = function(ctx) {
try {
var percent = Math.min(this.percent, 100);
var size = this._size;
@@ -311,7 +315,7 @@
var w = ctx.measureText(text).width;
ctx.fillText(text, x - w / 2 + 1, y + fontSize / 2 - 1);
- } catch (err) {
+ } catch (ignore) {
// don't fail if we can't render progress
}
return this;
@@ -321,11 +325,11 @@
(function (global){
'use strict';
-exports.isatty = function isatty () {
+exports.isatty = function isatty() {
return true;
};
-exports.getWindowSize = function getWindowSize () {
+exports.getWindowSize = function getWindowSize() {
if ('innerHeight' in global) {
return [global.innerHeight, global.innerWidth];
}
@@ -336,7 +340,9 @@
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{}],5:[function(require,module,exports){
'use strict';
-
+/**
+ * @module Context
+ */
/**
* Expose `Context`.
*/
@@ -348,16 +354,16 @@
*
* @api private
*/
-function Context () {}
+function Context() {}
/**
* Set or get the context `Runnable` to `runnable`.
*
* @api private
* @param {Runnable} runnable
- * @return {Context}
+ * @return {Context} context
*/
-Context.prototype.runnable = function (runnable) {
+Context.prototype.runnable = function(runnable) {
if (!arguments.length) {
return this._runnable;
}
@@ -372,7 +378,7 @@
* @param {number} ms
* @return {Context} self
*/
-Context.prototype.timeout = function (ms) {
+Context.prototype.timeout = function(ms) {
if (!arguments.length) {
return this.runnable().timeout();
}
@@ -387,7 +393,7 @@
* @param {boolean} enabled
* @return {Context} self
*/
-Context.prototype.enableTimeouts = function (enabled) {
+Context.prototype.enableTimeouts = function(enabled) {
if (!arguments.length) {
return this.runnable().enableTimeouts();
}
@@ -402,7 +408,7 @@
* @param {number} ms
* @return {Context} self
*/
-Context.prototype.slow = function (ms) {
+Context.prototype.slow = function(ms) {
if (!arguments.length) {
return this.runnable().slow();
}
@@ -416,7 +422,7 @@
* @api private
* @throws Pending
*/
-Context.prototype.skip = function () {
+Context.prototype.skip = function() {
this.runnable().skip();
};
@@ -427,7 +433,7 @@
* @param {number} n
* @return {Context} self
*/
-Context.prototype.retries = function (n) {
+Context.prototype.retries = function(n) {
if (!arguments.length) {
return this.runnable().retries();
}
@@ -438,10 +444,6 @@
},{}],6:[function(require,module,exports){
'use strict';
-/**
- * Module dependencies.
- */
-
var Runnable = require('./runnable');
var inherits = require('./utils').inherits;
@@ -452,13 +454,14 @@
module.exports = Hook;
/**
- * Initialize a new `Hook` with the given `title` and callback `fn`.
+ * Initialize a new `Hook` with the given `title` and callback `fn`
*
+ * @class
+ * @extends Runnable
* @param {String} title
* @param {Function} fn
- * @api private
*/
-function Hook (title, fn) {
+function Hook(title, fn) {
Runnable.call(this, title, fn);
this.type = 'hook';
}
@@ -471,11 +474,12 @@
/**
* Get or set the test `err`.
*
+ * @memberof Hook
+ * @public
* @param {Error} err
* @return {Error}
- * @api public
*/
-Hook.prototype.error = function (err) {
+Hook.prototype.error = function(err) {
if (!arguments.length) {
err = this._error;
this._error = null;
@@ -488,10 +492,6 @@
},{"./runnable":32,"./utils":36}],7:[function(require,module,exports){
'use strict';
-/**
- * Module dependencies.
- */
-
var Test = require('../test');
/**
@@ -511,10 +511,10 @@
*
* @param {Suite} suite Root suite.
*/
-module.exports = function (suite) {
+module.exports = function bddInterface(suite) {
var suites = [suite];
- suite.on('pre-require', function (context, file, mocha) {
+ suite.on('pre-require', function(context, file, mocha) {
var common = require('./common')(suites, context, mocha);
context.before = common.before;
@@ -528,7 +528,7 @@
* and/or tests.
*/
- context.describe = context.context = function (title, fn) {
+ context.describe = context.context = function(title, fn) {
return common.suite.create({
title: title,
file: file,
@@ -540,7 +540,10 @@
* Pending describe.
*/
- context.xdescribe = context.xcontext = context.describe.skip = function (title, fn) {
+ context.xdescribe = context.xcontext = context.describe.skip = function(
+ title,
+ fn
+ ) {
return common.suite.skip({
title: title,
file: file,
@@ -552,7 +555,7 @@
* Exclusive suite.
*/
- context.describe.only = function (title, fn) {
+ context.describe.only = function(title, fn) {
return common.suite.only({
title: title,
file: file,
@@ -566,7 +569,7 @@
* acting as a thunk.
*/
- context.it = context.specify = function (title, fn) {
+ context.it = context.specify = function(title, fn) {
var suite = suites[0];
if (suite.isPending()) {
fn = null;
@@ -581,7 +584,7 @@
* Exclusive test-case.
*/
- context.it.only = function (title, fn) {
+ context.it.only = function(title, fn) {
return common.test.only(mocha, context.it(title, fn));
};
@@ -589,14 +592,14 @@
* Pending test case.
*/
- context.xit = context.xspecify = context.it.skip = function (title) {
+ context.xit = context.xspecify = context.it.skip = function(title) {
return context.it(title);
};
/**
* Number of attempts to retry.
*/
- context.it.retries = function (n) {
+ context.it.retries = function(n) {
context.retries(n);
};
});
@@ -615,7 +618,7 @@
* @param {Mocha} mocha
* @return {Object} An object containing common functions.
*/
-module.exports = function (suites, context, mocha) {
+module.exports = function(suites, context, mocha) {
return {
/**
* This is only present if flag --delay is passed into Mocha. It triggers
@@ -624,8 +627,8 @@
* @param {Suite} suite The root suite.
* @return {Function} A function which runs the root suite
*/
- runWithSuite: function runWithSuite (suite) {
- return function run () {
+ runWithSuite: function runWithSuite(suite) {
+ return function run() {
suite.run();
};
},
@@ -636,7 +639,7 @@
* @param {string} name
* @param {Function} fn
*/
- before: function (name, fn) {
+ before: function(name, fn) {
suites[0].beforeAll(name, fn);
},
@@ -646,7 +649,7 @@
* @param {string} name
* @param {Function} fn
*/
- after: function (name, fn) {
+ after: function(name, fn) {
suites[0].afterAll(name, fn);
},
@@ -656,7 +659,7 @@
* @param {string} name
* @param {Function} fn
*/
- beforeEach: function (name, fn) {
+ beforeEach: function(name, fn) {
suites[0].beforeEach(name, fn);
},
@@ -666,7 +669,7 @@
* @param {string} name
* @param {Function} fn
*/
- afterEach: function (name, fn) {
+ afterEach: function(name, fn) {
suites[0].afterEach(name, fn);
},
@@ -678,7 +681,7 @@
* @param {Object} opts
* @returns {Suite}
*/
- only: function only (opts) {
+ only: function only(opts) {
opts.isOnly = true;
return this.create(opts);
},
@@ -690,7 +693,7 @@
* @param {Object} opts
* @returns {Suite}
*/
- skip: function skip (opts) {
+ skip: function skip(opts) {
opts.pending = true;
return this.create(opts);
},
@@ -705,7 +708,7 @@
* @param {boolean} [opts.isOnly] Is Suite exclusive?
* @returns {Suite}
*/
- create: function create (opts) {
+ create: function create(opts) {
var suite = Suite.create(suites[0], opts.title);
suite.pending = Boolean(opts.pending);
suite.file = opts.file;
@@ -717,7 +720,13 @@
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.');
+ throw new Error(
+ 'Suite "' +
+ suite.fullTitle() +
+ '" was defined but no callback was supplied. Supply a callback or explicitly skip the suite.'
+ );
+ } else if (!opts.fn && suite.pending) {
+ suites.shift();
}
return suite;
@@ -733,7 +741,7 @@
* @param {Function} test
* @returns {*}
*/
- only: function (mocha, test) {
+ only: function(mocha, test) {
test.parent._onlyTests = test.parent._onlyTests.concat(test);
return test;
},
@@ -743,7 +751,7 @@
*
* @param {string} title
*/
- skip: function (title) {
+ skip: function(title) {
context.test(title);
},
@@ -752,7 +760,7 @@
*
* @param {number} n
*/
- retries: function (n) {
+ retries: function(n) {
context.retries(n);
}
}
@@ -761,11 +769,6 @@
},{"../suite":34}],9:[function(require,module,exports){
'use strict';
-
-/**
- * Module dependencies.
- */
-
var Suite = require('../suite');
var Test = require('../test');
@@ -786,12 +789,12 @@
*
* @param {Suite} suite Root suite.
*/
-module.exports = function (suite) {
+module.exports = function(suite) {
var suites = [suite];
suite.on('require', visit);
- function visit (obj, file) {
+ function visit(obj, file) {
var suite;
for (var key in obj) {
if (typeof obj[key] === 'function') {
@@ -835,10 +838,6 @@
},{"./bdd":7,"./exports":9,"./qunit":11,"./tdd":12}],11:[function(require,module,exports){
'use strict';
-/**
- * Module dependencies.
- */
-
var Test = require('../test');
/**
@@ -866,10 +865,10 @@
*
* @param {Suite} suite Root suite.
*/
-module.exports = function (suite) {
+module.exports = function qUnitInterface(suite) {
var suites = [suite];
- suite.on('pre-require', function (context, file, mocha) {
+ suite.on('pre-require', function(context, file, mocha) {
var common = require('./common')(suites, context, mocha);
context.before = common.before;
@@ -881,7 +880,7 @@
* Describe a "suite" with the given `title`.
*/
- context.suite = function (title) {
+ context.suite = function(title) {
if (suites.length > 1) {
suites.shift();
}
@@ -896,7 +895,7 @@
* Exclusive Suite.
*/
- context.suite.only = function (title) {
+ context.suite.only = function(title) {
if (suites.length > 1) {
suites.shift();
}
@@ -913,7 +912,7 @@
* acting as a thunk.
*/
- context.test = function (title, fn) {
+ context.test = function(title, fn) {
var test = new Test(title, fn);
test.file = file;
suites[0].addTest(test);
@@ -924,7 +923,7 @@
* Exclusive test-case.
*/
- context.test.only = function (title, fn) {
+ context.test.only = function(title, fn) {
return common.test.only(mocha, context.test(title, fn));
};
@@ -936,10 +935,6 @@
},{"../test":35,"./common":8}],12:[function(require,module,exports){
'use strict';
-/**
- * Module dependencies.
- */
-
var Test = require('../test');
/**
@@ -967,10 +962,10 @@
*
* @param {Suite} suite Root suite.
*/
-module.exports = function (suite) {
+module.exports = function(suite) {
var suites = [suite];
- suite.on('pre-require', function (context, file, mocha) {
+ suite.on('pre-require', function(context, file, mocha) {
var common = require('./common')(suites, context, mocha);
context.setup = common.beforeEach;
@@ -983,7 +978,7 @@
* Describe a "suite" with the given `title` and callback `fn` containing
* nested suites and/or tests.
*/
- context.suite = function (title, fn) {
+ context.suite = function(title, fn) {
return common.suite.create({
title: title,
file: file,
@@ -994,7 +989,7 @@
/**
* Pending suite.
*/
- context.suite.skip = function (title, fn) {
+ context.suite.skip = function(title, fn) {
return common.suite.skip({
title: title,
file: file,
@@ -1005,7 +1000,7 @@
/**
* Exclusive test-case.
*/
- context.suite.only = function (title, fn) {
+ context.suite.only = function(title, fn) {
return common.suite.only({
title: title,
file: file,
@@ -1017,7 +1012,7 @@
* Describe a specification or test-case with the given `title` and
* callback `fn` acting as a thunk.
*/
- context.test = function (title, fn) {
+ context.test = function(title, fn) {
var suite = suites[0];
if (suite.isPending()) {
fn = null;
@@ -1032,7 +1027,7 @@
* Exclusive test-case.
*/
- context.test.only = function (title, fn) {
+ context.test.only = function(title, fn) {
return common.test.only(mocha, context.test(title, fn));
};
@@ -1051,19 +1046,11 @@
* 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;
/**
@@ -1079,11 +1066,25 @@
* Expose internals.
*/
+/**
+ * @public
+ * @class utils
+ * @memberof Mocha
+ */
exports.utils = utils;
exports.interfaces = require('./interfaces');
+/**
+ *
+ * @memberof Mocha
+ * @public
+ */
exports.reporters = reporters;
exports.Runnable = require('./runnable');
exports.Context = require('./context');
+/**
+ *
+ * @memberof Mocha
+ */
exports.Runner = require('./runner');
exports.Suite = require('./suite');
exports.Hook = require('./hook');
@@ -1092,12 +1093,12 @@
/**
* Return image `name` path.
*
- * @api private
+ * @private
* @param {string} name
* @return {string}
*/
-function image (name) {
- return path.join(__dirname, '../images', name + '.png');
+function image(name) {
+ return path.join(__dirname, '..', 'assets', 'growl', name + '.png');
}
/**
@@ -1116,10 +1117,10 @@
* - `fullTrace` display the full stack-trace on failing
* - `grep` string or regexp to filter tests with
*
+ * @class Mocha
* @param {Object} options
- * @api public
*/
-function Mocha (options) {
+function Mocha(options) {
options = options || {};
this.files = [];
this.options = options;
@@ -1151,10 +1152,11 @@
/**
* Enable or disable bailing on the first failure.
*
+ * @public
* @api public
* @param {boolean} [bail]
*/
-Mocha.prototype.bail = function (bail) {
+Mocha.prototype.bail = function(bail) {
if (!arguments.length) {
bail = true;
}
@@ -1165,10 +1167,11 @@
/**
* Add test `file`.
*
+ * @public
* @api public
* @param {string} file
*/
-Mocha.prototype.addFile = function (file) {
+Mocha.prototype.addFile = function(file) {
this.files.push(file);
return this;
};
@@ -1176,13 +1179,14 @@
/**
* Set reporter to `reporter`, defaults to "spec".
*
+ * @public
* @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) {
+Mocha.prototype.reporter = function(reporter, reporterOptions) {
if (typeof reporter === 'function') {
this._reporter = reporter;
} else {
@@ -1202,18 +1206,28 @@
try {
_reporter = require(path.resolve(process.cwd(), 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);
+ err.message.indexOf('Cannot find module') !== -1
+ ? console.warn('"' + reporter + '" reporter not found')
+ : console.warn(
+ '"' +
+ reporter +
+ '" reporter blew up with error:\n' +
+ err.stack
+ );
}
} else {
- console.warn('"' + reporter + '" reporter blew up with error:\n' + err.stack);
+ 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 ' +
+ console.warn(
+ 'The Teamcity reporter was moved to a package named ' +
'mocha-teamcity-reporter ' +
- '(https://npmjs.org/package/mocha-teamcity-reporter).');
+ '(https://npmjs.org/package/mocha-teamcity-reporter).'
+ );
}
if (!_reporter) {
throw new Error('invalid reporter "' + reporter + '"');
@@ -1226,11 +1240,11 @@
/**
* Set test UI `name`, defaults to "bdd".
- *
+ * @public
* @api public
* @param {string} bdd
*/
-Mocha.prototype.ui = function (name) {
+Mocha.prototype.ui = function(name) {
name = name || 'bdd';
this._ui = exports.interfaces[name];
if (!this._ui) {
@@ -1242,7 +1256,7 @@
}
this._ui = this._ui(this.suite);
- this.suite.on('pre-require', function (context) {
+ 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;
@@ -1267,10 +1281,10 @@
*
* @api private
*/
-Mocha.prototype.loadFiles = function (fn) {
+Mocha.prototype.loadFiles = function(fn) {
var self = this;
var suite = this.suite;
- this.files.forEach(function (file) {
+ this.files.forEach(function(file) {
file = path.resolve(file);
suite.emit('pre-require', global, file, self);
suite.emit('require', require(file), file, self);
@@ -1284,14 +1298,14 @@
*
* @api private
*/
-Mocha.prototype._growl = function (runner, reporter) {
+Mocha.prototype._growl = function(runner, reporter) {
var notify = require('growl');
- runner.on('end', function () {
+ 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') });
+ notify(msg, {name: 'mocha', title: 'Failed', image: image('error')});
} else {
notify(stats.passes + ' tests passed in ' + stats.duration + 'ms', {
name: 'mocha',
@@ -1305,24 +1319,26 @@
/**
* Escape string and add it to grep as a regexp.
*
+ * @public
* @api public
* @param str
* @returns {Mocha}
*/
-Mocha.prototype.fgrep = function (str) {
+Mocha.prototype.fgrep = function(str) {
return this.grep(new RegExp(escapeRe(str)));
};
/**
* Add regexp to grep, if `re` is a string it is escaped.
*
+ * @public
* @param {RegExp|String} re
* @return {Mocha}
* @api public
* @param {RegExp|string} re
* @return {Mocha}
*/
-Mocha.prototype.grep = function (re) {
+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|)$|.*/);
@@ -1335,10 +1351,11 @@
/**
* Invert `.grep()` matches.
*
+ * @public
* @return {Mocha}
* @api public
*/
-Mocha.prototype.invert = function () {
+Mocha.prototype.invert = function() {
this.options.invert = true;
return this;
};
@@ -1346,13 +1363,14 @@
/**
* Ignore global leaks.
*
+ * @public
* @param {Boolean} ignore
* @return {Mocha}
* @api public
* @param {boolean} ignore
* @return {Mocha}
*/
-Mocha.prototype.ignoreLeaks = function (ignore) {
+Mocha.prototype.ignoreLeaks = function(ignore) {
this.options.ignoreLeaks = Boolean(ignore);
return this;
};
@@ -1362,8 +1380,9 @@
*
* @return {Mocha}
* @api public
+ * @public
*/
-Mocha.prototype.checkLeaks = function () {
+Mocha.prototype.checkLeaks = function() {
this.options.ignoreLeaks = false;
return this;
};
@@ -1373,8 +1392,9 @@
*
* @return {Mocha}
* @api public
+ * @public
*/
-Mocha.prototype.fullTrace = function () {
+Mocha.prototype.fullTrace = function() {
this.options.fullStackTrace = true;
return this;
};
@@ -1384,8 +1404,9 @@
*
* @return {Mocha}
* @api public
+ * @public
*/
-Mocha.prototype.growl = function () {
+Mocha.prototype.growl = function() {
this.options.growl = true;
return this;
};
@@ -1396,10 +1417,11 @@
* @param {Array|String} globals
* @return {Mocha}
* @api public
+ * @public
* @param {Array|string} globals
* @return {Mocha}
*/
-Mocha.prototype.globals = function (globals) {
+Mocha.prototype.globals = function(globals) {
this.options.globals = (this.options.globals || []).concat(globals);
return this;
};
@@ -1410,10 +1432,11 @@
* @param {Boolean} colors
* @return {Mocha}
* @api public
+ * @public
* @param {boolean} colors
* @return {Mocha}
*/
-Mocha.prototype.useColors = function (colors) {
+Mocha.prototype.useColors = function(colors) {
if (colors !== undefined) {
this.options.useColors = colors;
}
@@ -1426,10 +1449,11 @@
* @param {Boolean} inlineDiffs
* @return {Mocha}
* @api public
+ * @public
* @param {boolean} inlineDiffs
* @return {Mocha}
*/
-Mocha.prototype.useInlineDiffs = function (inlineDiffs) {
+Mocha.prototype.useInlineDiffs = function(inlineDiffs) {
this.options.useInlineDiffs = inlineDiffs !== undefined && inlineDiffs;
return this;
};
@@ -1440,10 +1464,11 @@
* @param {Boolean} hideDiff
* @return {Mocha}
* @api public
+ * @public
* @param {boolean} hideDiff
* @return {Mocha}
*/
-Mocha.prototype.hideDiff = function (hideDiff) {
+Mocha.prototype.hideDiff = function(hideDiff) {
this.options.hideDiff = hideDiff !== undefined && hideDiff;
return this;
};
@@ -1454,10 +1479,11 @@
* @param {Number} timeout
* @return {Mocha}
* @api public
+ * @public
* @param {number} timeout
* @return {Mocha}
*/
-Mocha.prototype.timeout = function (timeout) {
+Mocha.prototype.timeout = function(timeout) {
this.suite.timeout(timeout);
return this;
};
@@ -1468,8 +1494,9 @@
* @param {Number} retry times
* @return {Mocha}
* @api public
+ * @public
*/
-Mocha.prototype.retries = function (n) {
+Mocha.prototype.retries = function(n) {
this.suite.retries(n);
return this;
};
@@ -1480,10 +1507,11 @@
* @param {Number} slow
* @return {Mocha}
* @api public
+ * @public
* @param {number} slow
* @return {Mocha}
*/
-Mocha.prototype.slow = function (slow) {
+Mocha.prototype.slow = function(slow) {
this.suite.slow(slow);
return this;
};
@@ -1494,11 +1522,14 @@
* @param {Boolean} enabled
* @return {Mocha}
* @api public
+ * @public
* @param {boolean} enabled
* @return {Mocha}
*/
-Mocha.prototype.enableTimeouts = function (enabled) {
- this.suite.enableTimeouts(arguments.length && enabled !== undefined ? enabled : true);
+Mocha.prototype.enableTimeouts = function(enabled) {
+ this.suite.enableTimeouts(
+ arguments.length && enabled !== undefined ? enabled : true
+ );
return this;
};
@@ -1507,8 +1538,9 @@
*
* @return {Mocha}
* @api public
+ * @public
*/
-Mocha.prototype.asyncOnly = function () {
+Mocha.prototype.asyncOnly = function() {
this.options.asyncOnly = true;
return this;
};
@@ -1517,8 +1549,9 @@
* Disable syntax highlighting (in browser).
*
* @api public
+ * @public
*/
-Mocha.prototype.noHighlighting = function () {
+Mocha.prototype.noHighlighting = function() {
this.options.noHighlighting = true;
return this;
};
@@ -1528,8 +1561,9 @@
*
* @return {Mocha}
* @api public
+ * @public
*/
-Mocha.prototype.allowUncaught = function () {
+Mocha.prototype.allowUncaught = function() {
this.options.allowUncaught = true;
return this;
};
@@ -1538,7 +1572,7 @@
* Delay root suite execution.
* @returns {Mocha}
*/
-Mocha.prototype.delay = function delay () {
+Mocha.prototype.delay = function delay() {
this.options.delay = true;
return this;
};
@@ -1547,7 +1581,7 @@
* Tests marked only fail the suite
* @returns {Mocha}
*/
-Mocha.prototype.forbidOnly = function () {
+Mocha.prototype.forbidOnly = function() {
this.options.forbidOnly = true;
return this;
};
@@ -1556,7 +1590,7 @@
* Pending tests and tests marked skip fail the suite
* @returns {Mocha}
*/
-Mocha.prototype.forbidPending = function () {
+Mocha.prototype.forbidPending = function() {
this.options.forbidPending = true;
return this;
};
@@ -1573,10 +1607,11 @@
* cache first in whichever manner best suits your needs.
*
* @api public
+ * @public
* @param {Function} fn
* @return {Runner}
*/
-Mocha.prototype.run = function (fn) {
+Mocha.prototype.run = function(fn) {
if (this.files.length) {
this.loadFiles();
}
@@ -1606,7 +1641,7 @@
exports.reporters.Base.inlineDiffs = options.useInlineDiffs;
exports.reporters.Base.hideDiff = options.hideDiff;
- function done (failures) {
+ function done(failures) {
if (reporter.done) {
reporter.done(failures, fn);
} else {
@@ -1620,7 +1655,9 @@
}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},"/lib")
},{"./context":5,"./hook":6,"./interfaces":10,"./reporters":20,"./runnable":32,"./runner":33,"./suite":34,"./test":35,"./utils":36,"_process":56,"escape-string-regexp":46,"growl":2,"path":40}],14:[function(require,module,exports){
'use strict';
-
+/**
+ * @module milliseconds
+ */
/**
* Helpers.
*/
@@ -1634,11 +1671,13 @@
/**
* Parse or format the given `val`.
*
+ * @memberof Mocha
+ * @public
* @api public
* @param {string|number} val
* @return {string|number}
*/
-module.exports = function (val) {
+module.exports = function(val) {
if (typeof val === 'string') {
return parse(val);
}
@@ -1652,8 +1691,10 @@
* @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);
+function parse(str) {
+ var match = /^((?:\d+)?\.?\d+) *(ms|seconds?|s|minutes?|m|hours?|h|days?|d|years?|y)?$/i.exec(
+ str
+ );
if (!match) {
return;
}
@@ -1694,7 +1735,7 @@
* @param {number} ms
* @return {string}
*/
-function format (ms) {
+function format(ms) {
if (ms >= d) {
return Math.round(ms / d) + 'd';
}
@@ -1713,10 +1754,6 @@
},{}],15:[function(require,module,exports){
'use strict';
-/**
- * Expose `Pending`.
- */
-
module.exports = Pending;
/**
@@ -1724,14 +1761,16 @@
*
* @param {string} message
*/
-function Pending (message) {
+function Pending(message) {
this.message = message;
}
},{}],16:[function(require,module,exports){
(function (process,global){
'use strict';
-
+/**
+ * @module Base
+ */
/**
* Module dependencies.
*/
@@ -1771,7 +1810,9 @@
* Enable coloring by default, except in the browser interface.
*/
-exports.useColors = !process.browser && (supportsColor || (process.env.MOCHA_COLORS !== undefined));
+exports.useColors =
+ !process.browser &&
+ (supportsColor.stdout || process.env.MOCHA_COLORS !== undefined);
/**
* Inline diffs instead of +/-
@@ -1835,12 +1876,12 @@
* @return {string}
* @api private
*/
-var color = exports.color = function (type, str) {
+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.
@@ -1861,23 +1902,23 @@
*/
exports.cursor = {
- hide: function () {
+ hide: function() {
isatty && process.stdout.write('\u001b[?25l');
},
- show: function () {
+ show: function() {
isatty && process.stdout.write('\u001b[?25h');
},
- deleteLine: function () {
+ deleteLine: function() {
isatty && process.stdout.write('\u001b[2K');
},
- beginningOfLine: function () {
+ beginningOfLine: function() {
isatty && process.stdout.write('\u001b[0G');
},
- CR: function () {
+ CR: function() {
if (isatty) {
exports.cursor.deleteLine();
exports.cursor.beginningOfLine();
@@ -1887,11 +1928,16 @@
}
};
-function showDiff (err) {
- return err && err.showDiff !== false && sameType(err.actual, err.expected) && err.expected !== undefined;
+function showDiff(err) {
+ return (
+ err &&
+ err.showDiff !== false &&
+ sameType(err.actual, err.expected) &&
+ err.expected !== undefined
+ );
}
-function stringifyDiffObjs (err) {
+function stringifyDiffObjs(err) {
if (!utils.isString(err.actual) || !utils.isString(err.expected)) {
err.actual = utils.stringify(err.actual);
err.expected = utils.stringify(err.expected);
@@ -1899,17 +1945,37 @@
}
/**
+ * Returns a diff between 2 strings with coloured ANSI output.
+ *
+ * The diff will be either inline or unified dependant on the value
+ * of `Base.inlineDiff`.
+ *
+ * @param {string} actual
+ * @param {string} expected
+ * @return {string} Diff
+ */
+var generateDiff = (exports.generateDiff = function(actual, expected) {
+ return exports.inlineDiffs
+ ? inlineDiff(actual, expected)
+ : unifiedDiff(actual, expected);
+});
+
+/**
* Output the given `failures` as a list.
*
+ * @public
+ * @memberof Mocha.reporters.Base
+ * @variation 1
* @param {Array} failures
* @api public
*/
-exports.list = function (failures) {
+exports.list = function(failures) {
console.log();
- failures.forEach(function (test, i) {
+ failures.forEach(function(test, i) {
// format
- var fmt = color('error title', ' %s) %s:\n') +
+ var fmt =
+ color('error title', ' %s) %s:\n') +
color('error message', ' %s') +
color('error stack', '\n%s\n');
@@ -1943,15 +2009,12 @@
// explicitly show diff
if (!exports.hideDiff && showDiff(err)) {
stringifyDiffObjs(err);
- fmt = color('error title', ' %s) %s:\n%s') + color('error stack', '\n%s\n');
+ 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);
- } else {
- msg += unifiedDiff(err);
- }
+ msg += generateDiff(err.actual, err.expected);
}
// indent stack trace
@@ -1959,7 +2022,7 @@
// indented test title
var testTitle = '';
- test.titlePath().forEach(function (str, index) {
+ test.titlePath().forEach(function(str, index) {
if (index !== 0) {
testTitle += '\n ';
}
@@ -1969,7 +2032,7 @@
testTitle += str;
});
- console.log(fmt, (i + 1), testTitle, msg, stack);
+ console.log(fmt, i + 1, testTitle, msg, stack);
});
};
@@ -1981,13 +2044,22 @@
* stats such as test duration, number
* of tests passed / failed etc.
*
+ * @memberof Mocha.reporters
+ * @public
+ * @class
* @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 = [];
+function Base(runner) {
+ var stats = (this.stats = {
+ suites: 0,
+ tests: 0,
+ passes: 0,
+ pending: 0,
+ failures: 0
+ });
+ var failures = (this.failures = []);
if (!runner) {
return;
@@ -1996,21 +2068,21 @@
runner.stats = stats;
- runner.on('start', function () {
+ runner.on('start', function() {
stats.start = new Date();
});
- runner.on('suite', function (suite) {
+ runner.on('suite', function(suite) {
stats.suites = stats.suites || 0;
suite.root || stats.suites++;
});
- runner.on('test end', function () {
+ runner.on('test end', function() {
stats.tests = stats.tests || 0;
stats.tests++;
});
- runner.on('pass', function (test) {
+ runner.on('pass', function(test) {
stats.passes = stats.passes || 0;
if (test.duration > test.slow()) {
@@ -2024,7 +2096,7 @@
stats.passes++;
});
- runner.on('fail', function (test, err) {
+ runner.on('fail', function(test, err) {
stats.failures = stats.failures || 0;
stats.failures++;
if (showDiff(err)) {
@@ -2034,12 +2106,12 @@
failures.push(test);
});
- runner.on('end', function () {
+ runner.once('end', function() {
stats.end = new Date();
stats.duration = stats.end - stats.start;
});
- runner.on('pending', function () {
+ runner.on('pending', function() {
stats.pending++;
});
}
@@ -2048,27 +2120,27 @@
* Output common epilogue used by many of
* the bundled reporters.
*
+ * @memberof Mocha.reporters.Base
+ * @public
* @api public
*/
-Base.prototype.epilogue = function () {
+Base.prototype.epilogue = function() {
var stats = this.stats;
var fmt;
console.log();
// passes
- fmt = color('bright pass', ' ') +
+ fmt =
+ color('bright pass', ' ') +
color('green', ' %d passing') +
color('light', ' (%s)');
- console.log(fmt,
- stats.passes || 0,
- ms(stats.duration));
+ console.log(fmt, stats.passes || 0, ms(stats.duration));
// pending
if (stats.pending) {
- fmt = color('pending', ' ') +
- color('pending', ' %d pending');
+ fmt = color('pending', ' ') + color('pending', ' %d pending');
console.log(fmt, stats.pending);
}
@@ -2094,32 +2166,36 @@
* @param {string} len
* @return {string}
*/
-function pad (str, len) {
+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
+ * Returns an inline diff between 2 strings with coloured ANSI output.
*
* @api private
- * @param {Error} err with actual/expected
+ * @param {String} actual
+ * @param {String} expected
* @return {string} Diff
*/
-function inlineDiff (err) {
- var msg = errorDiff(err);
+function inlineDiff(actual, expected) {
+ var msg = errorDiff(actual, expected);
// linenos
var lines = msg.split('\n');
if (lines.length > 4) {
var width = String(lines.length).length;
- msg = lines.map(function (str, i) {
+ msg = lines
+ .map(function(str, i) {
return pad(++i, width) + ' |' + ' ' + str;
- }).join('\n');
+ })
+ .join('\n');
}
// legend
- msg = '\n' +
+ msg =
+ '\n' +
color('diff removed', 'actual') +
' ' +
color('diff added', 'expected') +
@@ -2133,15 +2209,16 @@
}
/**
- * Returns a unified diff between two strings.
+ * Returns a unified diff between two strings with coloured ANSI output.
*
* @api private
- * @param {Error} err with actual/expected
+ * @param {String} actual
+ * @param {String} expected
* @return {string} The diff.
*/
-function unifiedDiff (err) {
+function unifiedDiff(actual, expected) {
var indent = ' ';
- function cleanUp (line) {
+ function cleanUp(line) {
if (line[0] === '+') {
return indent + colorLines('diff added', line);
}
@@ -2156,27 +2233,36 @@
}
return indent + line;
}
- function notBlank (line) {
+ function notBlank(line) {
return typeof line !== 'undefined' && line !== null;
}
- var msg = diff.createPatch('string', err.actual, err.expected);
+ var msg = diff.createPatch('string', actual, expected);
var lines = msg.split('\n').splice(5);
- return '\n ' +
- colorLines('diff added', '+ expected') + ' ' +
+ return (
+ '\n ' +
+ colorLines('diff added', '+ expected') +
+ ' ' +
colorLines('diff removed', '- actual') +
'\n\n' +
- lines.map(cleanUp).filter(notBlank).join('\n');
+ lines
+ .map(cleanUp)
+ .filter(notBlank)
+ .join('\n')
+ );
}
/**
* Return a character diff for `err`.
*
* @api private
- * @param {Error} err
- * @return {string}
- */
-function errorDiff (err) {
- return diff.diffWordsWithSpace(err.actual, err.expected).map(function (str) {
+ * @param {String} actual
+ * @param {String} expected
+ * @return {string} the diff
+ */
+function errorDiff(actual, expected) {
+ return diff
+ .diffWordsWithSpace(actual, expected)
+ .map(function(str) {
if (str.added) {
return colorLines('diff added', str.value);
}
@@ -2184,7 +2270,8 @@
return colorLines('diff removed', str.value);
}
return str.value;
- }).join('');
+ })
+ .join('');
}
/**
@@ -2195,10 +2282,13 @@
* @param {string} str
* @return {string}
*/
-function colorLines (name, str) {
- return str.split('\n').map(function (str) {
+function colorLines(name, str) {
+ return str
+ .split('\n')
+ .map(function(str) {
return color(name, str);
- }).join('\n');
+ })
+ .join('\n');
}
/**
@@ -2214,14 +2304,16 @@
* @param {Object} b
* @return {boolean}
*/
-function sameType (a, b) {
+function sameType(a, b) {
return objToString.call(a) === objToString.call(b);
}
}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{"../ms":14,"../utils":36,"_process":56,"diff":45,"supports-color":40,"tty":4}],17:[function(require,module,exports){
'use strict';
-
+/**
+ * @module Doc
+ */
/**
* Module dependencies.
*/
@@ -2238,19 +2330,23 @@
/**
* Initialize a new `Doc` reporter.
*
+ * @class
+ * @memberof Mocha.reporters
+ * @extends {Base}
+ * @public
* @param {Runner} runner
* @api public
*/
-function Doc (runner) {
+function Doc(runner) {
Base.call(this, runner);
var indents = 2;
- function indent () {
+ function indent() {
return Array(indents).join(' ');
}
- runner.on('suite', function (suite) {
+ runner.on('suite', function(suite) {
if (suite.root) {
return;
}
@@ -2261,7 +2357,7 @@
console.log('%s<dl>', indent());
});
- runner.on('suite end', function (suite) {
+ runner.on('suite end', function(suite) {
if (suite.root) {
return;
}
@@ -2271,16 +2367,24 @@
--indents;
});
- runner.on('pass', function (test) {
+ runner.on('pass', function(test) {
console.log('%s <dt>%s</dt>', indent(), utils.escape(test.title));
var code = utils.escape(utils.clean(test.body));
console.log('%s <dd><pre><code>%s</code></pre></dd>', indent(), code);
});
- runner.on('fail', function (test, err) {
- console.log('%s <dt class="error">%s</dt>', indent(), utils.escape(test.title));
+ runner.on('fail', function(test, err) {
+ console.log(
+ '%s <dt class="error">%s</dt>',
+ indent(),
+ utils.escape(test.title)
+ );
var code = utils.escape(utils.clean(test.body));
- console.log('%s <dd class="error"><pre><code>%s</code></pre></dd>', indent(), code);
+ console.log(
+ '%s <dd class="error"><pre><code>%s</code></pre></dd>',
+ indent(),
+ code
+ );
console.log('%s <dd class="error">%s</dd>', indent(), utils.escape(err));
});
}
@@ -2288,7 +2392,9 @@
},{"../utils":36,"./base":16}],18:[function(require,module,exports){
(function (process){
'use strict';
-
+/**
+ * @module Dot
+ */
/**
* Module dependencies.
*/
@@ -2306,28 +2412,32 @@
/**
* Initialize a new `Dot` matrix test reporter.
*
+ * @class
+ * @memberof Mocha.reporters
+ * @extends Mocha.reporters.Base
+ * @public
* @api public
* @param {Runner} runner
*/
-function Dot (runner) {
+function Dot(runner) {
Base.call(this, runner);
var self = this;
- var width = Base.window.width * 0.75 | 0;
+ var width = (Base.window.width * 0.75) | 0;
var n = -1;
- runner.on('start', function () {
+ runner.on('start', function() {
process.stdout.write('\n');
});
- runner.on('pending', function () {
+ runner.on('pending', function() {
if (++n % width === 0) {
process.stdout.write('\n ');
}
process.stdout.write(color('pending', Base.symbols.comma));
});
- runner.on('pass', function (test) {
+ runner.on('pass', function(test) {
if (++n % width === 0) {
process.stdout.write('\n ');
}
@@ -2338,14 +2448,14 @@
}
});
- runner.on('fail', function () {
+ runner.on('fail', function() {
if (++n % width === 0) {
process.stdout.write('\n ');
}
process.stdout.write(color('fail', Base.symbols.bang));
});
- runner.on('end', function () {
+ runner.once('end', function() {
console.log();
self.epilogue();
});
@@ -2362,7 +2472,9 @@
'use strict';
/* eslint-env browser */
-
+/**
+ * @module HTML
+ */
/**
* Module dependencies.
*/
@@ -2395,7 +2507,8 @@
* Stats template.
*/
-var statsTemplate = '<ul id="mocha-stats">' +
+var statsTemplate =
+ '<ul id="mocha-stats">' +
'<li class="progress"><canvas width="40" height="40"></canvas></li>' +
'<li class="passes"><a href="javascript:void(0);">passes:</a> <em>0</em></li>' +
'<li class="failures"><a href="javascript:void(0);">failures:</a> <em>0</em></li>' +
@@ -2407,10 +2520,14 @@
/**
* Initialize a new `HTML` reporter.
*
+ * @public
+ * @class
+ * @memberof Mocha.reporters
+ * @extends Mocha.reporters.Base
* @api public
* @param {Runner} runner
*/
-function HTML (runner) {
+function HTML(runner) {
Base.call(this, runner);
var self = this;
@@ -2445,10 +2562,10 @@
}
// pass toggle
- on(passesLink, 'click', function (evt) {
+ on(passesLink, 'click', function(evt) {
evt.preventDefault();
unhide();
- var name = (/pass/).test(report.className) ? '' : ' pass';
+ var name = /pass/.test(report.className) ? '' : ' pass';
report.className = report.className.replace(/fail|pass/g, '') + name;
if (report.className.trim()) {
hideSuitesWithout('test pass');
@@ -2456,10 +2573,10 @@
});
// failure toggle
- on(failuresLink, 'click', function (evt) {
+ on(failuresLink, 'click', function(evt) {
evt.preventDefault();
unhide();
- var name = (/fail/).test(report.className) ? '' : ' fail';
+ var name = /fail/.test(report.className) ? '' : ' fail';
report.className = report.className.replace(/fail|pass/g, '') + name;
if (report.className.trim()) {
hideSuitesWithout('test fail');
@@ -2473,14 +2590,18 @@
progress.size(40);
}
- runner.on('suite', function (suite) {
+ runner.on('suite', function(suite) {
if (suite.root) {
return;
}
// suite
var url = self.suiteURL(suite);
- var el = fragment('<li class="suite"><h1><a href="%s">%s</a></h1></li>', url, escape(suite.title));
+ var el = fragment(
+ '<li class="suite"><h1><a href="%s">%s</a></h1></li>',
+ url,
+ escape(suite.title)
+ );
// container
stack[0].appendChild(el);
@@ -2488,7 +2609,7 @@
el.appendChild(stack[0]);
});
- runner.on('suite end', function (suite) {
+ runner.on('suite end', function(suite) {
if (suite.root) {
updateStats();
return;
@@ -2496,19 +2617,27 @@
stack.shift();
});
- runner.on('pass', function (test) {
+ runner.on('pass', function(test) {
var url = self.testURL(test);
- var markup = '<li class="test pass %e"><h2>%e<span class="duration">%ems</span> ' +
- '<a href="%s" class="replay">' + playIcon + '</a></h2></li>';
+ var markup =
+ '<li class="test pass %e"><h2>%e<span class="duration">%ems</span> ' +
+ '<a href="%s" class="replay">' +
+ playIcon +
+ '</a></h2></li>';
var el = fragment(markup, test.speed, test.title, test.duration, url);
self.addCodeToggle(el, test.body);
appendToStack(el);
updateStats();
});
- runner.on('fail', function (test) {
- var el = fragment('<li class="test fail"><h2>%e <a href="%e" class="replay">' + playIcon + '</a></h2></li>',
- test.title, self.testURL(test));
+ runner.on('fail', function(test) {
+ var el = fragment(
+ '<li class="test fail"><h2>%e <a href="%e" class="replay">' +
+ playIcon +
+ '</a></h2></li>',
+ test.title,
+ self.testURL(test)
+ );
var stackString; // Note: Includes leading newline
var message = test.err.toString();
@@ -2523,7 +2652,9 @@
if (indexOfMessage === -1) {
stackString = test.err.stack;
} else {
- stackString = test.err.stack.substr(test.err.message.length + indexOfMessage);
+ stackString = test.err.stack.substr(
+ test.err.message.length + indexOfMessage
+ );
}
} else if (test.err.sourceURL && test.err.line !== undefined) {
// Safari doesn't give you a stack. Let's at least provide a source line.
@@ -2533,12 +2664,21 @@
stackString = stackString || '';
if (test.err.htmlMessage && stackString) {
- el.appendChild(fragment('<div class="html-error">%s\n<pre class="error">%e</pre></div>',
- test.err.htmlMessage, stackString));
+ el.appendChild(
+ fragment(
+ '<div class="html-error">%s\n<pre class="error">%e</pre></div>',
+ test.err.htmlMessage,
+ stackString
+ )
+ );
} else if (test.err.htmlMessage) {
- el.appendChild(fragment('<div class="html-error">%s</div>', test.err.htmlMessage));
+ el.appendChild(
+ fragment('<div class="html-error">%s</div>', test.err.htmlMessage)
+ );
} else {
- el.appendChild(fragment('<pre class="error">%e%e</pre>', message, stackString));
+ el.appendChild(
+ fragment('<pre class="error">%e%e</pre>', message, stackString)
+ );
}
self.addCodeToggle(el, test.body);
@@ -2546,22 +2686,25 @@
updateStats();
});
- runner.on('pending', function (test) {
- var el = fragment('<li class="test pass pending"><h2>%e</h2></li>', test.title);
+ runner.on('pending', function(test) {
+ var el = fragment(
+ '<li class="test pass pending"><h2>%e</h2></li>',
+ test.title
+ );
appendToStack(el);
updateStats();
});
- function appendToStack (el) {
+ function appendToStack(el) {
// Don't call .appendChild if #mocha-report was already .shift()'ed off the stack.
if (stack[0]) {
stack[0].appendChild(el);
}
}
- function updateStats () {
+ function updateStats() {
// TODO: add to stats
- var percent = stats.tests / runner.total * 100 | 0;
+ var percent = (stats.tests / runner.total * 100) | 0;
if (progress) {
progress.update(percent).draw(ctx);
}
@@ -2580,7 +2723,7 @@
* @param {string} s
* @return {string} A new URL.
*/
-function makeUrl (s) {
+function makeUrl(s) {
var search = window.location.search;
// Remove previous grep query parameter if present
@@ -2588,7 +2731,12 @@
search = search.replace(/[?&]grep=[^&\s]*/g, '').replace(/^&/, '?');
}
- return window.location.pathname + (search ? search + '&' : '?') + 'grep=' + encodeURIComponent(escapeRe(s));
+ return (
+ window.location.pathname +
+ (search ? search + '&' : '?') +
+ 'grep=' +
+ encodeURIComponent(escapeRe(s))
+ );
}
/**
@@ -2596,7 +2744,7 @@
*
* @param {Object} [suite]
*/
-HTML.prototype.suiteURL = function (suite) {
+HTML.prototype.suiteURL = function(suite) {
return makeUrl(suite.fullTitle());
};
@@ -2605,7 +2753,7 @@
*
* @param {Object} [test]
*/
-HTML.prototype.testURL = function (test) {
+HTML.prototype.testURL = function(test) {
return makeUrl(test.fullTitle());
};
@@ -2615,10 +2763,10 @@
* @param {HTMLLIElement} el
* @param {string} contents
*/
-HTML.prototype.addCodeToggle = function (el, contents) {
+HTML.prototype.addCodeToggle = function(el, contents) {
var h2 = el.getElementsByTagName('h2')[0];
- on(h2, 'click', function () {
+ on(h2, 'click', function() {
pre.style.display = pre.style.display === 'none' ? 'block' : 'none';
});
@@ -2632,7 +2780,7 @@
*
* @param {string} msg
*/
-function error (msg) {
+function error(msg) {
document.body.appendChild(fragment('<div id="mocha-error">%s</div>', msg));
}
@@ -2641,15 +2789,17 @@
*
* @param {string} html
*/
-function fragment (html) {
+function fragment(html) {
var args = arguments;
var div = document.createElement('div');
var i = 1;
- div.innerHTML = html.replace(/%([se])/g, function (_, type) {
+ div.innerHTML = html.replace(/%([se])/g, function(_, type) {
switch (type) {
- case 's': return String(args[i++]);
- case 'e': return escape(args[i++]);
+ case 's':
+ return String(args[i++]);
+ case 'e':
+ return escape(args[i++]);
// no default
}
});
@@ -2663,7 +2813,7 @@
*
* @param {text} classname
*/
-function hideSuitesWithout (classname) {
+function hideSuitesWithout(classname) {
var suites = document.getElementsByClassName('suite');
for (var i = 0; i < suites.length; i++) {
var els = suites[i].getElementsByClassName(classname);
@@ -2676,7 +2826,7 @@
/**
* Unhide .hidden suites.
*/
-function unhide () {
+function unhide() {
var els = document.getElementsByClassName('suite hidden');
for (var i = 0; i < els.length; ++i) {
els[i].className = els[i].className.replace('suite hidden', 'suite');
@@ -2689,7 +2839,7 @@
* @param {HTMLElement} el
* @param {string} contents
*/
-function text (el, contents) {
+function text(el, contents) {
if (el.textContent) {
el.textContent = contents;
} else {
@@ -2700,7 +2850,7 @@
/**
* Listen on `event` with callback `fn`.
*/
-function on (el, event, fn) {
+function on(el, event, fn) {
if (el.addEventListener) {
el.addEventListener(event, fn, false);
} else {
@@ -2733,7 +2883,9 @@
},{"./base":16,"./doc":17,"./dot":18,"./html":19,"./json":22,"./json-stream":21,"./landing":23,"./list":24,"./markdown":25,"./min":26,"./nyan":27,"./progress":28,"./spec":29,"./tap":30,"./xunit":31}],21:[function(require,module,exports){
(function (process){
'use strict';
-
+/**
+ * @module JSONStream
+ */
/**
* Module dependencies.
*/
@@ -2747,33 +2899,38 @@
exports = module.exports = List;
/**
- * Initialize a new `List` test reporter.
+ * Initialize a new `JSONStream` test reporter.
*
+ * @public
+ * @name JSONStream
+ * @class JSONStream
+ * @memberof Mocha.reporters
+ * @extends Mocha.reporters.Base
* @api public
* @param {Runner} runner
*/
-function List (runner) {
+function List(runner) {
Base.call(this, runner);
var self = this;
var total = runner.total;
- runner.on('start', function () {
- console.log(JSON.stringify(['start', { total: total }]));
+ runner.on('start', function() {
+ console.log(JSON.stringify(['start', {total: total}]));
});
- runner.on('pass', function (test) {
+ runner.on('pass', function(test) {
console.log(JSON.stringify(['pass', clean(test)]));
});
- runner.on('fail', function (test, err) {
+ runner.on('fail', function(test, err) {
test = clean(test);
test.err = err.message;
test.stack = err.stack || null;
console.log(JSON.stringify(['fail', test]));
});
- runner.on('end', function () {
+ runner.once('end', function() {
process.stdout.write(JSON.stringify(['end', self.stats]));
});
}
@@ -2786,7 +2943,7 @@
* @param {Object} test
* @return {Object}
*/
-function clean (test) {
+function clean(test) {
return {
title: test.title,
fullTitle: test.fullTitle(),
@@ -2799,7 +2956,9 @@
},{"./base":16,"_process":56}],22:[function(require,module,exports){
(function (process){
'use strict';
-
+/**
+ * @module JSON
+ */
/**
* Module dependencies.
*/
@@ -2815,10 +2974,14 @@
/**
* Initialize a new `JSON` reporter.
*
+ * @public
+ * @class JSON
+ * @memberof Mocha.reporters
+ * @extends Mocha.reporters.Base
* @api public
* @param {Runner} runner
*/
-function JSONReporter (runner) {
+function JSONReporter(runner) {
Base.call(this, runner);
var self = this;
@@ -2827,23 +2990,23 @@
var failures = [];
var passes = [];
- runner.on('test end', function (test) {
+ runner.on('test end', function(test) {
tests.push(test);
});
- runner.on('pass', function (test) {
+ runner.on('pass', function(test) {
passes.push(test);
});
- runner.on('fail', function (test) {
+ runner.on('fail', function(test) {
failures.push(test);
});
- runner.on('pending', function (test) {
+ runner.on('pending', function(test) {
pending.push(test);
});
- runner.on('end', function () {
+ runner.once('end', function() {
var obj = {
stats: self.stats,
tests: tests.map(clean),
@@ -2866,26 +3029,55 @@
* @param {Object} test
* @return {Object}
*/
-function clean (test) {
+function clean(test) {
+ var err = test.err || {};
+ if (err instanceof Error) {
+ err = errorJSON(err);
+ }
+
return {
title: test.title,
fullTitle: test.fullTitle(),
duration: test.duration,
currentRetry: test.currentRetry(),
- err: errorJSON(test.err || {})
+ err: cleanCycles(err)
};
}
/**
- * Transform `error` into a JSON object.
+ * Replaces any circular references inside `obj` with '[object Object]'
+ *
+ * @api private
+ * @param {Object} obj
+ * @return {Object}
+ */
+function cleanCycles(obj) {
+ var cache = [];
+ return JSON.parse(
+ JSON.stringify(obj, function(key, value) {
+ if (typeof value === 'object' && value !== null) {
+ if (cache.indexOf(value) !== -1) {
+ // Instead of going in a circle, we'll print [object Object]
+ return '' + value;
+ }
+ cache.push(value);
+ }
+
+ return value;
+ })
+ );
+}
+
+/**
+ * Transform an Error object into a JSON object.
*
* @api private
* @param {Error} err
* @return {Object}
*/
-function errorJSON (err) {
+function errorJSON(err) {
var res = {};
- Object.getOwnPropertyNames(err).forEach(function (key) {
+ Object.getOwnPropertyNames(err).forEach(function(key) {
res[key] = err[key];
}, err);
return res;
@@ -2895,7 +3087,9 @@
},{"./base":16,"_process":56}],23:[function(require,module,exports){
(function (process){
'use strict';
-
+/**
+ * @module Landing
+ */
/**
* Module dependencies.
*/
@@ -2932,33 +3126,37 @@
/**
* Initialize a new `Landing` reporter.
*
+ * @public
+ * @class
+ * @memberof Mocha.reporters
+ * @extends Mocha.reporters.Base
* @api public
* @param {Runner} runner
*/
-function Landing (runner) {
+function Landing(runner) {
Base.call(this, runner);
var self = this;
- var width = Base.window.width * 0.75 | 0;
+ var width = (Base.window.width * 0.75) | 0;
var total = runner.total;
var stream = process.stdout;
var plane = color('plane', '✈');
var crashed = -1;
var n = 0;
- function runway () {
+ function runway() {
var buf = Array(width).join('-');
return ' ' + color('runway', buf);
}
- runner.on('start', function () {
+ runner.on('start', function() {
stream.write('\n\n\n ');
cursor.hide();
});
- runner.on('test end', function (test) {
+ runner.on('test end', function(test) {
// check if the plane crashed
- var col = crashed === -1 ? width * ++n / total | 0 : crashed;
+ var col = crashed === -1 ? (width * ++n / total) | 0 : crashed;
// show the crash
if (test.state === 'failed') {
@@ -2977,7 +3175,7 @@
stream.write('\u001b[0m');
});
- runner.on('end', function () {
+ runner.once('end', function() {
cursor.show();
console.log();
self.epilogue();
@@ -2993,7 +3191,9 @@
},{"../utils":36,"./base":16,"_process":56}],24:[function(require,module,exports){
(function (process){
'use strict';
-
+/**
+ * @module List
+ */
/**
* Module dependencies.
*/
@@ -3012,43 +3212,47 @@
/**
* Initialize a new `List` test reporter.
*
+ * @public
+ * @class
+ * @memberof Mocha.reporters
+ * @extends Mocha.reporters.Base
* @api public
* @param {Runner} runner
*/
-function List (runner) {
+function List(runner) {
Base.call(this, runner);
var self = this;
var n = 0;
- runner.on('start', function () {
+ runner.on('start', function() {
console.log();
});
- runner.on('test', function (test) {
+ runner.on('test', function(test) {
process.stdout.write(color('pass', ' ' + test.fullTitle() + ': '));
});
- runner.on('pending', function (test) {
- var fmt = color('checkmark', ' -') +
- color('pending', ' %s');
+ runner.on('pending', function(test) {
+ var fmt = color('checkmark', ' -') + color('pending', ' %s');
console.log(fmt, test.fullTitle());
});
- runner.on('pass', function (test) {
- var fmt = color('checkmark', ' ' + Base.symbols.ok) +
+ runner.on('pass', function(test) {
+ var fmt =
+ color('checkmark', ' ' + Base.symbols.ok) +
color('pass', ' %s: ') +
color(test.speed, '%dms');
cursor.CR();
console.log(fmt, test.fullTitle(), test.duration);
});
- runner.on('fail', function (test) {
+ runner.on('fail', function(test) {
cursor.CR();
console.log(color('fail', ' %d) %s'), ++n, test.fullTitle());
});
- runner.on('end', self.epilogue.bind(self));
+ runner.once('end', self.epilogue.bind(self));
}
/**
@@ -3060,7 +3264,9 @@
},{"../utils":36,"./base":16,"_process":56}],25:[function(require,module,exports){
(function (process){
'use strict';
-
+/**
+ * @module Markdown
+ */
/**
* Module dependencies.
*/
@@ -3083,32 +3289,36 @@
/**
* Initialize a new `Markdown` reporter.
*
+ * @public
+ * @class
+ * @memberof Mocha.reporters
+ * @extends Mocha.reporters.Base
* @api public
* @param {Runner} runner
*/
-function Markdown (runner) {
+function Markdown(runner) {
Base.call(this, runner);
var level = 0;
var buf = '';
- function title (str) {
+ function title(str) {
return Array(level).join('#') + ' ' + str;
}
- function mapTOC (suite, obj) {
+ function mapTOC(suite, obj) {
var ret = obj;
var key = SUITE_PREFIX + suite.title;
- obj = obj[key] = obj[key] || { suite: suite };
- suite.suites.forEach(function (suite) {
+ obj = obj[key] = obj[key] || {suite: suite};
+ suite.suites.forEach(function(suite) {
mapTOC(suite, obj);
});
return ret;
}
- function stringifyTOC (obj, level) {
+ function stringifyTOC(obj, level) {
++level;
var buf = '';
var link;
@@ -3126,25 +3336,25 @@
return buf;
}
- function generateTOC (suite) {
+ function generateTOC(suite) {
var obj = mapTOC(suite, {});
return stringifyTOC(obj, 0);
}
generateTOC(runner.suite);
- runner.on('suite', function (suite) {
+ runner.on('suite', function(suite) {
++level;
var slug = utils.slug(suite.fullTitle());
buf += '<a name="' + slug + '"></a>' + '\n';
buf += title(suite.title) + '\n';
});
- runner.on('suite end', function () {
+ runner.on('suite end', function() {
--level;
});
- runner.on('pass', function (test) {
+ runner.on('pass', function(test) {
var code = utils.clean(test.body);
buf += test.title + '.\n';
buf += '\n```js\n';
@@ -3152,7 +3362,7 @@
buf += '```\n\n';
});
- runner.on('end', function () {
+ runner.once('end', function() {
process.stdout.write('# TOC\n');
process.stdout.write(generateTOC(runner.suite));
process.stdout.write(buf);
@@ -3163,7 +3373,9 @@
},{"../utils":36,"./base":16,"_process":56}],26:[function(require,module,exports){
(function (process){
'use strict';
-
+/**
+ * @module Min
+ */
/**
* Module dependencies.
*/
@@ -3180,20 +3392,24 @@
/**
* Initialize a new `Min` minimal test reporter (best used with --watch).
*
+ * @public
+ * @class
+ * @memberof Mocha.reporters
+ * @extends Mocha.reporters.Base
* @api public
* @param {Runner} runner
*/
-function Min (runner) {
+function Min(runner) {
Base.call(this, runner);
- runner.on('start', function () {
+ runner.on('start', function() {
// clear screen
process.stdout.write('\u001b[2J');
// set cursor position
process.stdout.write('\u001b[1;3H');
});
- runner.on('end', this.epilogue.bind(this));
+ runner.once('end', this.epilogue.bind(this));
}
/**
@@ -3205,7 +3421,9 @@
},{"../utils":36,"./base":16,"_process":56}],27:[function(require,module,exports){
(function (process){
'use strict';
-
+/**
+ * @module Nyan
+ */
/**
* Module dependencies.
*/
@@ -3224,14 +3442,18 @@
*
* @param {Runner} runner
* @api public
+ * @public
+ * @class Nyan
+ * @memberof Mocha.reporters
+ * @extends Mocha.reporters.Base
*/
-function NyanCat (runner) {
+function NyanCat(runner) {
Base.call(this, runner);
var self = this;
- var width = Base.window.width * 0.75 | 0;
- var nyanCatWidth = this.nyanCatWidth = 11;
+ var width = (Base.window.width * 0.75) | 0;
+ var nyanCatWidth = (this.nyanCatWidth = 11);
this.colorIndex = 0;
this.numberOfLines = 4;
@@ -3239,26 +3461,26 @@
this.scoreboardWidth = 5;
this.tick = 0;
this.trajectories = [[], [], [], []];
- this.trajectoryWidthMax = (width - nyanCatWidth);
+ this.trajectoryWidthMax = width - nyanCatWidth;
- runner.on('start', function () {
+ runner.on('start', function() {
Base.cursor.hide();
self.draw();
});
- runner.on('pending', function () {
+ runner.on('pending', function() {
self.draw();
});
- runner.on('pass', function () {
+ runner.on('pass', function() {
self.draw();
});
- runner.on('fail', function () {
+ runner.on('fail', function() {
self.draw();
});
- runner.on('end', function () {
+ runner.once('end', function() {
Base.cursor.show();
for (var i = 0; i < self.numberOfLines; i++) {
write('\n');
@@ -3278,7 +3500,7 @@
* @api private
*/
-NyanCat.prototype.draw = function () {
+NyanCat.prototype.draw = function() {
this.appendRainbow();
this.drawScoreboard();
this.drawRainbow();
@@ -3293,10 +3515,10 @@
* @api private
*/
-NyanCat.prototype.drawScoreboard = function () {
+NyanCat.prototype.drawScoreboard = function() {
var stats = this.stats;
- function draw (type, n) {
+ function draw(type, n) {
write(' ');
write(Base.color(type, n));
write('\n');
@@ -3316,7 +3538,7 @@
* @api private
*/
-NyanCat.prototype.appendRainbow = function () {
+NyanCat.prototype.appendRainbow = function() {
var segment = this.tick ? '_' : '-';
var rainbowified = this.rainbowify(segment);
@@ -3335,10 +3557,10 @@
* @api private
*/
-NyanCat.prototype.drawRainbow = function () {
+NyanCat.prototype.drawRainbow = function() {
var self = this;
- this.trajectories.forEach(function (line) {
+ this.trajectories.forEach(function(line) {
write('\u001b[' + self.scoreboardWidth + 'C');
write(line.join(''));
write('\n');
@@ -3352,7 +3574,7 @@
*
* @api private
*/
-NyanCat.prototype.drawNyanCat = function () {
+NyanCat.prototype.drawNyanCat = function() {
var self = this;
var startWidth = this.scoreboardWidth + this.trajectories[0].length;
var dist = '\u001b[' + startWidth + 'C';
@@ -3388,7 +3610,7 @@
* @return {string}
*/
-NyanCat.prototype.face = function () {
+NyanCat.prototype.face = function() {
var stats = this.stats;
if (stats.failures) {
return '( x .x)';
@@ -3407,7 +3629,7 @@
* @param {number} n
*/
-NyanCat.prototype.cursorUp = function (n) {
+NyanCat.prototype.cursorUp = function(n) {
write('\u001b[' + n + 'A');
};
@@ -3418,7 +3640,7 @@
* @param {number} n
*/
-NyanCat.prototype.cursorDown = function (n) {
+NyanCat.prototype.cursorDown = function(n) {
write('\u001b[' + n + 'B');
};
@@ -3428,12 +3650,12 @@
* @api private
* @return {Array}
*/
-NyanCat.prototype.generateColors = function () {
+NyanCat.prototype.generateColors = function() {
var colors = [];
- for (var i = 0; i < (6 * 7); i++) {
+ for (var i = 0; i < 6 * 7; i++) {
var pi3 = Math.floor(Math.PI / 3);
- var n = (i * (1.0 / 6));
+ var n = i * (1.0 / 6);
var r = Math.floor(3 * Math.sin(n) + 3);
var g = Math.floor(3 * Math.sin(n + 2 * pi3) + 3);
var b = Math.floor(3 * Math.sin(n + 4 * pi3) + 3);
@@ -3450,7 +3672,7 @@
* @param {string} str
* @return {string}
*/
-NyanCat.prototype.rainbowify = function (str) {
+NyanCat.prototype.rainbowify = function(str) {
if (!Base.useColors) {
return str;
}
@@ -3464,7 +3686,7 @@
*
* @param {string} string A message to write to stdout.
*/
-function write (string) {
+function write(string) {
process.stdout.write(string);
}
@@ -3472,7 +3694,9 @@
},{"../utils":36,"./base":16,"_process":56}],28:[function(require,module,exports){
(function (process){
'use strict';
-
+/**
+ * @module Progress
+ */
/**
* Module dependencies.
*/
@@ -3497,15 +3721,19 @@
/**
* Initialize a new `Progress` bar test reporter.
*
+ * @public
+ * @class
+ * @memberof Mocha.reporters
+ * @extends Mocha.reporters.Base
* @api public
* @param {Runner} runner
* @param {Object} options
*/
-function Progress (runner, options) {
+function Progress(runner, options) {
Base.call(this, runner);
var self = this;
- var width = Base.window.width * 0.50 | 0;
+ var width = (Base.window.width * 0.5) | 0;
var total = runner.total;
var complete = 0;
var lastN = -1;
@@ -3521,17 +3749,17 @@
options.verbose = reporterOptions.verbose || false;
// tests started
- runner.on('start', function () {
+ runner.on('start', function() {
console.log();
cursor.hide();
});
// tests complete
- runner.on('test end', function () {
+ runner.on('test end', function() {
complete++;
var percent = complete / total;
- var n = width * percent | 0;
+ var n = (width * percent) | 0;
var i = width - n;
if (n === lastN && !options.verbose) {
@@ -3553,7 +3781,7 @@
// tests are complete, output some stats
// and the failures if any
- runner.on('end', function () {
+ runner.once('end', function() {
cursor.show();
console.log();
self.epilogue();
@@ -3568,7 +3796,9 @@
}).call(this,require('_process'))
},{"../utils":36,"./base":16,"_process":56}],29:[function(require,module,exports){
'use strict';
-
+/**
+ * @module Spec
+ */
/**
* Module dependencies.
*/
@@ -3586,50 +3816,56 @@
/**
* Initialize a new `Spec` test reporter.
*
+ * @public
+ * @class
+ * @memberof Mocha.reporters
+ * @extends Mocha.reporters.Base
* @api public
* @param {Runner} runner
*/
-function Spec (runner) {
+function Spec(runner) {
Base.call(this, runner);
var self = this;
var indents = 0;
var n = 0;
- function indent () {
+ function indent() {
return Array(indents).join(' ');
}
- runner.on('start', function () {
+ runner.on('start', function() {
console.log();
});
- runner.on('suite', function (suite) {
+ runner.on('suite', function(suite) {
++indents;
console.log(color('suite', '%s%s'), indent(), suite.title);
});
- runner.on('suite end', function () {
+ runner.on('suite end', function() {
--indents;
if (indents === 1) {
console.log();
}
});
- runner.on('pending', function (test) {
+ runner.on('pending', function(test) {
var fmt = indent() + color('pending', ' - %s');
console.log(fmt, test.title);
});
- runner.on('pass', function (test) {
+ runner.on('pass', function(test) {
var fmt;
if (test.speed === 'fast') {
- fmt = indent() +
+ fmt =
+ indent() +
color('checkmark', ' ' + Base.symbols.ok) +
color('pass', ' %s');
console.log(fmt, test.title);
} else {
- fmt = indent() +
+ fmt =
+ indent() +
color('checkmark', ' ' + Base.symbols.ok) +
color('pass', ' %s') +
color(test.speed, ' (%dms)');
@@ -3637,11 +3873,11 @@
}
});
- runner.on('fail', function (test) {
+ runner.on('fail', function(test) {
console.log(indent() + color('fail', ' %d) %s'), ++n, test.title);
});
- runner.on('end', self.epilogue.bind(self));
+ runner.once('end', self.epilogue.bind(self));
}
/**
@@ -3651,7 +3887,9 @@
},{"../utils":36,"./base":16}],30:[function(require,module,exports){
'use strict';
-
+/**
+ * @module TAP
+ */
/**
* Module dependencies.
*/
@@ -3667,35 +3905,39 @@
/**
* Initialize a new `TAP` reporter.
*
+ * @public
+ * @class
+ * @memberof Mocha.reporters
+ * @extends Mocha.reporters.Base
* @api public
* @param {Runner} runner
*/
-function TAP (runner) {
+function TAP(runner) {
Base.call(this, runner);
var n = 1;
var passes = 0;
var failures = 0;
- runner.on('start', function () {
+ runner.on('start', function() {
var total = runner.grepTotal(runner.suite);
console.log('%d..%d', 1, total);
});
- runner.on('test end', function () {
+ runner.on('test end', function() {
++n;
});
- runner.on('pending', function (test) {
+ runner.on('pending', function(test) {
console.log('ok %d %s # SKIP -', n, title(test));
});
- runner.on('pass', function (test) {
+ runner.on('pass', function(test) {
passes++;
console.log('ok %d %s', n, title(test));
});
- runner.on('fail', function (test, err) {
+ runner.on('fail', function(test, err) {
failures++;
console.log('not ok %d %s', n, title(test));
if (err.stack) {
@@ -3703,7 +3945,7 @@
}
});
- runner.on('end', function () {
+ runner.once('end', function() {
console.log('# tests ' + (passes + failures));
console.log('# pass ' + passes);
console.log('# fail ' + failures);
@@ -3717,14 +3959,16 @@
* @param {Object} test
* @return {String}
*/
-function title (test) {
+function title(test) {
return test.fullTitle().replace(/#/g, '');
}
},{"./base":16}],31:[function(require,module,exports){
(function (process,global){
'use strict';
-
+/**
+ * @module XUnit
+ */
/**
* Module dependencies.
*/
@@ -3758,10 +4002,14 @@
/**
* Initialize a new `XUnit` reporter.
*
+ * @public
+ * @class
+ * @memberof Mocha.reporters
+ * @extends Mocha.reporters.Base
* @api public
* @param {Runner} runner
*/
-function XUnit (runner, options) {
+function XUnit(runner, options) {
Base.call(this, runner);
var stats = this.stats;
@@ -3791,30 +4039,36 @@
// fall back to the default suite name
suiteName = suiteName || DEFAULT_SUITE_NAME;
- runner.on('pending', function (test) {
+ runner.on('pending', function(test) {
tests.push(test);
});
- runner.on('pass', function (test) {
+ runner.on('pass', function(test) {
tests.push(test);
});
- runner.on('fail', function (test) {
+ runner.on('fail', function(test) {
tests.push(test);
});
- runner.on('end', function () {
- self.write(tag('testsuite', {
+ runner.once('end', function() {
+ self.write(
+ tag(
+ 'testsuite',
+ {
name: suiteName,
tests: stats.tests,
failures: stats.failures,
errors: stats.failures,
skipped: stats.tests - stats.failures - stats.passes,
- timestamp: (new Date()).toUTCString(),
- time: (stats.duration / 1000) || 0
- }, false));
+ timestamp: new Date().toUTCString(),
+ time: stats.duration / 1000 || 0
+ },
+ false
+ )
+ );
- tests.forEach(function (t) {
+ tests.forEach(function(t) {
self.test(t);
});
@@ -3833,9 +4087,9 @@
* @param failures
* @param {Function} fn
*/
-XUnit.prototype.done = function (failures, fn) {
+XUnit.prototype.done = function(failures, fn) {
if (this.fileStream) {
- this.fileStream.end(function () {
+ this.fileStream.end(function() {
fn(failures);
});
} else {
@@ -3848,7 +4102,7 @@
*
* @param {string} line
*/
-XUnit.prototype.write = function (line) {
+XUnit.prototype.write = function(line) {
if (this.fileStream) {
this.fileStream.write(line + '\n');
} else if (typeof process === 'object' && process.stdout) {
@@ -3863,16 +4117,28 @@
*
* @param {Test} test
*/
-XUnit.prototype.test = function (test) {
+XUnit.prototype.test = function(test) {
var attrs = {
classname: test.parent.fullTitle(),
name: test.title,
- time: (test.duration / 1000) || 0
+ time: test.duration / 1000 || 0
};
if (test.state === 'failed') {
var err = test.err;
- this.write(tag('testcase', attrs, false, tag('failure', {}, false, escape(err.message) + '\n' + escape(err.stack))));
+ this.write(
+ tag(
+ 'testcase',
+ attrs,
+ false,
+ tag(
+ 'failure',
+ {},
+ false,
+ escape(err.message) + '\n' + escape(err.stack)
+ )
+ )
+ );
} else if (test.isPending()) {
this.write(tag('testcase', attrs, false, tag('skipped', {}, true)));
} else {
@@ -3889,7 +4155,7 @@
* @param content
* @return {string}
*/
-function tag (name, attrs, close, content) {
+function tag(name, attrs, close, content) {
var end = close ? '/>' : '>';
var pairs = [];
var tag;
@@ -3911,11 +4177,6 @@
},{"../utils":36,"./base":16,"_process":56,"fs":40,"mkdirp":53,"path":40}],32:[function(require,module,exports){
(function (global){
'use strict';
-
-/**
- * Module dependencies.
- */
-
var EventEmitter = require('events').EventEmitter;
var Pending = require('./pending');
var debug = require('debug')('mocha:runnable');
@@ -3934,28 +4195,19 @@
var clearInterval = global.clearInterval;
/* eslint-enable no-unused-vars, no-native-reassign */
-/**
- * Object#toString().
- */
-
var toString = Object.prototype.toString;
-/**
- * Expose `Runnable`.
- */
-
module.exports = Runnable;
/**
- * Initialize a new `Runnable` with the given `title` and callback `fn`.
+ * Initialize a new `Runnable` with the given `title` and callback `fn`. Derived from [EventEmitter](https://nodejs.org/api/events.html#events_class_eventemitter)
*
+ * @class
+ * @extends EventEmitter
* @param {String} title
* @param {Function} fn
- * @api private
- * @param {string} title
- * @param {Function} fn
*/
-function Runnable (title, fn) {
+function Runnable(title, fn) {
this.title = title;
this.fn = fn;
this.body = (fn || '').toString();
@@ -3965,7 +4217,6 @@
this._slow = 75;
this._enableTimeouts = true;
this.timedOut = false;
- this._trace = new Error('done() called multiple times');
this._retries = -1;
this._currentRetry = 0;
this.pending = false;
@@ -3983,7 +4234,7 @@
* @param {number|string} ms
* @return {Runnable|number} ms or Runnable instance.
*/
-Runnable.prototype.timeout = function (ms) {
+Runnable.prototype.timeout = function(ms) {
if (!arguments.length) {
return this._timeout;
}
@@ -4009,14 +4260,14 @@
* @param {number|string} ms
* @return {Runnable|number} ms or Runnable instance.
*/
-Runnable.prototype.slow = function (ms) {
+Runnable.prototype.slow = function(ms) {
if (!arguments.length || typeof ms === 'undefined') {
return this._slow;
}
if (typeof ms === 'string') {
ms = milliseconds(ms);
}
- debug('timeout %d', ms);
+ debug('slow %d', ms);
this._slow = ms;
return this;
};
@@ -4028,7 +4279,7 @@
* @param {boolean} enabled
* @return {Runnable|boolean} enabled or Runnable instance.
*/
-Runnable.prototype.enableTimeouts = function (enabled) {
+Runnable.prototype.enableTimeouts = function(enabled) {
if (!arguments.length) {
return this._enableTimeouts;
}
@@ -4040,9 +4291,11 @@
/**
* Halt and mark as pending.
*
+ * @memberof Mocha.Runnable
+ * @public
* @api public
*/
-Runnable.prototype.skip = function () {
+Runnable.prototype.skip = function() {
throw new Pending('sync skip');
};
@@ -4051,16 +4304,34 @@
*
* @api private
*/
-Runnable.prototype.isPending = function () {
+Runnable.prototype.isPending = function() {
return this.pending || (this.parent && this.parent.isPending());
};
/**
+ * Return `true` if this Runnable has failed.
+ * @return {boolean}
+ * @private
+ */
+Runnable.prototype.isFailed = function() {
+ return !this.isPending() && this.state === 'failed';
+};
+
+/**
+ * Return `true` if this Runnable has passed.
+ * @return {boolean}
+ * @private
+ */
+Runnable.prototype.isPassed = function() {
+ return !this.isPending() && this.state === 'passed';
+};
+
+/**
* Set or get number of retries.
*
* @api private
*/
-Runnable.prototype.retries = function (n) {
+Runnable.prototype.retries = function(n) {
if (!arguments.length) {
return this._retries;
}
@@ -4072,7 +4343,7 @@
*
* @api private
*/
-Runnable.prototype.currentRetry = function (n) {
+Runnable.prototype.currentRetry = function(n) {
if (!arguments.length) {
return this._currentRetry;
}
@@ -4083,20 +4354,24 @@
* Return the full title generated by recursively concatenating the parent's
* full title.
*
+ * @memberof Mocha.Runnable
+ * @public
* @api public
* @return {string}
*/
-Runnable.prototype.fullTitle = function () {
+Runnable.prototype.fullTitle = function() {
return this.titlePath().join(' ');
};
/**
* Return the title path generated by concatenating the parent's title path with the title.
*
+ * @memberof Mocha.Runnable
+ * @public
* @api public
* @return {string}
*/
-Runnable.prototype.titlePath = function () {
+Runnable.prototype.titlePath = function() {
return this.parent.titlePath().concat([this.title]);
};
@@ -4105,7 +4380,7 @@
*
* @api private
*/
-Runnable.prototype.clearTimeout = function () {
+Runnable.prototype.clearTimeout = function() {
clearTimeout(this.timer);
};
@@ -4115,8 +4390,10 @@
* @api private
* @return {string}
*/
-Runnable.prototype.inspect = function () {
- return JSON.stringify(this, function (key, val) {
+Runnable.prototype.inspect = function() {
+ return JSON.stringify(
+ this,
+ function(key, val) {
if (key[0] === '_') {
return;
}
@@ -4127,7 +4404,9 @@
return '#<Context>';
}
return val;
- }, 2);
+ },
+ 2
+ );
};
/**
@@ -4135,7 +4414,7 @@
*
* @api private
*/
-Runnable.prototype.resetTimeout = function () {
+Runnable.prototype.resetTimeout = function() {
var self = this;
var ms = this.timeout() || 1e9;
@@ -4143,12 +4422,11 @@
return;
}
this.clearTimeout();
- this.timer = setTimeout(function () {
+ this.timer = setTimeout(function() {
if (!self._enableTimeouts) {
return;
}
- self.callback(new Error('Timeout of ' + ms +
- 'ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves.'));
+ self.callback(self._timeoutError(ms));
self.timedOut = true;
}, ms);
};
@@ -4159,7 +4437,7 @@
* @api private
* @param {string[]} globals
*/
-Runnable.prototype.globals = function (globals) {
+Runnable.prototype.globals = function(globals) {
if (!arguments.length) {
return this._allowedGlobals;
}
@@ -4172,7 +4450,7 @@
* @param {Function} fn
* @api private
*/
-Runnable.prototype.run = function (fn) {
+Runnable.prototype.run = function(fn) {
var self = this;
var start = new Date();
var ctx = this.ctx;
@@ -4185,16 +4463,22 @@
}
// called multiple times
- function multiple (err) {
+ function multiple(err) {
if (emitted) {
return;
}
emitted = true;
- self.emit('error', err || new Error('done() called multiple times; stacktrace may be inaccurate'));
+ var msg = 'done() called multiple times';
+ if (err && err.message) {
+ err.message += " (and Mocha's " + msg + ')';
+ self.emit('error', err);
+ } else {
+ self.emit('error', new Error(msg));
+ }
}
// finished
- function done (err) {
+ function done(err) {
var ms = self.timeout();
if (self.timedOut) {
return;
@@ -4199,16 +4483,16 @@
if (self.timedOut) {
return;
}
+
if (finished) {
- return multiple(err || self._trace);
+ 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. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves.');
+ err = self._timeoutError(ms);
}
fn(err);
}
@@ -4221,7 +4505,7 @@
this.resetTimeout();
// allows skip() to be used in an explicit async context
- this.skip = function asyncSkip () {
+ this.skip = function asyncSkip() {
done(new Pending('async skip call'));
// halt execution. the Runnable will be marked pending
// by the previous call, and the uncaught handler will ignore
@@ -4262,43 +4546,53 @@
done(utils.getError(err));
}
- function callFn (fn) {
+ function callFn(fn) {
var result = fn.call(ctx);
if (result && typeof result.then === 'function') {
self.resetTimeout();
- result
- .then(function () {
+ result.then(
+ function() {
done();
// Return null so libraries like bluebird do not warn about
// subsequently constructed Promises.
return null;
},
- function (reason) {
+ function(reason) {
done(reason || new Error('Promise rejected with no or falsy reason'));
- });
+ }
+ );
} else {
if (self.asyncOnly) {
- return done(new Error('--async-only option in use without declaring `done()` or returning a promise'));
+ return done(
+ new Error(
+ '--async-only option in use without declaring `done()` or returning a promise'
+ )
+ );
}
done();
}
}
- function callFnAsync (fn) {
- var result = fn.call(ctx, function (err) {
+ function callFnAsync(fn) {
+ var result = fn.call(ctx, function(err) {
if (err instanceof Error || toString.call(err) === '[object Error]') {
return done(err);
}
if (err) {
if (Object.prototype.toString.call(err) === '[object Object]') {
- return done(new Error('done() invoked with non-Error: ' +
- JSON.stringify(err)));
+ return done(
+ new Error('done() invoked with non-Error: ' + JSON.stringify(err))
+ );
}
return done(new Error('done() invoked with non-Error: ' + err));
}
if (result && utils.isPromise(result)) {
- return done(new Error('Resolution method is overspecified. Specify a callback *or* return a Promise; not both.'));
+ return done(
+ new Error(
+ 'Resolution method is overspecified. Specify a callback *or* return a Promise; not both.'
+ )
+ );
}
done();
@@ -4306,15 +4600,35 @@
}
};
+/**
+ * Instantiates a "timeout" error
+ *
+ * @param {number} ms - Timeout (in milliseconds)
+ * @returns {Error} a "timeout" error
+ * @private
+ */
+Runnable.prototype._timeoutError = function(ms) {
+ var msg =
+ 'Timeout of ' +
+ ms +
+ 'ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves.';
+ if (this.file) {
+ msg += ' (' + this.file + ')';
+ }
+ return new Error(msg);
+};
+
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{"./ms":14,"./pending":15,"./utils":36,"debug":43,"events":47}],33:[function(require,module,exports){
(function (process,global){
'use strict';
/**
+ * @module Runner
+ */
+/**
* Module dependencies.
*/
-
var EventEmitter = require('events').EventEmitter;
var Pending = require('./pending');
var utils = require('./utils');
@@ -4348,7 +4662,7 @@
module.exports = Runner;
/**
- * Initialize a `Runner` for the given `suite`.
+ * Initialize a `Runner` for the given `suite`. Derived from [EventEmitter](https://nodejs.org/api/events.html#events_class_eventemitter)
*
* Events:
*
@@ -4364,12 +4678,15 @@
* - `fail` (test, err) test failed
* - `pending` (test) test pending
*
+ * @memberof Mocha
+ * @public
+ * @class
* @api public
- * @param {Suite} suite Root suite
+ * @param {Suite} [suite] Root suite
* @param {boolean} [delay] Whether or not to delay execution of root suite
* until ready.
*/
-function Runner (suite, delay) {
+function Runner(suite, delay) {
var self = this;
this._globals = [];
this._abort = false;
@@ -4378,10 +4695,10 @@
this.started = false;
this.total = suite.total();
this.failures = 0;
- this.on('test end', function (test) {
+ this.on('test end', function(test) {
self.checkGlobals(test);
});
- this.on('hook end', function (hook) {
+ this.on('hook end', function(hook) {
self.checkGlobals(hook);
});
this._defaultGrep = /.*/;
@@ -4406,15 +4723,14 @@
* 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
+ * @public
+ * @memberof Mocha.Runner
* @param {RegExp} re
* @param {boolean} invert
* @return {Runner} Runner instance.
*/
-Runner.prototype.grep = function (re, invert) {
+Runner.prototype.grep = function(re, invert) {
debug('grep %s', re);
this._grep = re;
this._invert = invert;
@@ -4426,17 +4742,17 @@
* Returns the number of tests matching the grep search for the
* given suite.
*
- * @param {Suite} suite
- * @return {Number}
+ * @memberof Mocha.Runner
* @api public
+ * @public
* @param {Suite} suite
* @return {number}
*/
-Runner.prototype.grepTotal = function (suite) {
+Runner.prototype.grepTotal = function(suite) {
var self = this;
var total = 0;
- suite.eachTest(function (test) {
+ suite.eachTest(function(test) {
var match = self._grep.test(test.fullTitle());
if (self._invert) {
match = !match;
@@ -4455,7 +4771,7 @@
* @return {Array}
* @api private
*/
-Runner.prototype.globalProps = function () {
+Runner.prototype.globalProps = function() {
var props = Object.keys(global);
// non-enumerables
@@ -4472,13 +4788,13 @@
/**
* Allow the given `arr` of globals.
*
- * @param {Array} arr
- * @return {Runner} for chaining
* @api public
+ * @public
+ * @memberof Mocha.Runner
* @param {Array} arr
* @return {Runner} Runner instance.
*/
-Runner.prototype.globals = function (arr) {
+Runner.prototype.globals = function(arr) {
if (!arguments.length) {
return this._globals;
}
@@ -4492,7 +4808,7 @@
*
* @api private
*/
-Runner.prototype.checkGlobals = function (test) {
+Runner.prototype.checkGlobals = function(test) {
if (this.ignoreLeaks) {
return;
}
@@ -4514,7 +4830,10 @@
this._globals = this._globals.concat(leaks);
if (leaks.length > 1) {
- this.fail(test, new Error('global leaks detected: ' + leaks.join(', ') + ''));
+ this.fail(
+ test,
+ new Error('global leaks detected: ' + leaks.join(', ') + '')
+ );
} else if (leaks.length) {
this.fail(test, new Error('global leak detected: ' + leaks[0]));
}
@@ -4527,7 +4846,7 @@
* @param {Test} test
* @param {Error} err
*/
-Runner.prototype.fail = function (test, err) {
+Runner.prototype.fail = function(test, err) {
if (test.isPending()) {
return;
}
@@ -4536,18 +4855,26 @@
test.state = 'failed';
if (!(err instanceof Error || (err && typeof err.message === 'string'))) {
- err = new Error('the ' + type(err) + ' ' + stringify(err) + ' was thrown, throw an Error :)');
+ err = new Error(
+ 'the ' +
+ type(err) +
+ ' ' +
+ stringify(err) +
+ ' was thrown, throw an Error :)'
+ );
}
try {
- err.stack = (this.fullStackTrace || !err.stack)
- ? err.stack
- : stackFilter(err.stack);
- } catch (ignored) {
+ err.stack =
+ this.fullStackTrace || !err.stack ? err.stack : stackFilter(err.stack);
+ } catch (ignore) {
// some environments do not take kindly to monkeying with the stack
}
this.emit('fail', test, err);
+ if (this.suite.bail()) {
+ this.emit('end');
+ }
};
/**
@@ -4570,16 +4897,14 @@
* @param {Hook} hook
* @param {Error} err
*/
-Runner.prototype.failHook = function (hook, err) {
+Runner.prototype.failHook = function(hook, err) {
if (hook.ctx && hook.ctx.currentTest) {
hook.originalTitle = hook.originalTitle || hook.title;
- hook.title = hook.originalTitle + ' for "' + hook.ctx.currentTest.title + '"';
+ hook.title =
+ hook.originalTitle + ' for "' + hook.ctx.currentTest.title + '"';
}
this.fail(hook, err);
- if (this.suite.bail()) {
- this.emit('end');
- }
};
/**
@@ -4590,12 +4915,12 @@
* @param {Function} fn
*/
-Runner.prototype.hook = function (name, fn) {
+Runner.prototype.hook = function(name, fn) {
var suite = this.suite;
var hooks = suite['_' + name];
var self = this;
- function next (i) {
+ function next(i) {
var hook = hooks[i];
if (!hook) {
return fn();
@@ -4607,12 +4932,12 @@
self.emit('hook', hook);
if (!hook.listeners('error').length) {
- hook.on('error', function (err) {
+ hook.on('error', function(err) {
self.failHook(hook, err);
});
}
- hook.run(function (err) {
+ hook.run(function(err) {
var testError = hook.error();
if (testError) {
self.fail(self.test, testError);
@@ -4622,7 +4947,7 @@
if (name === 'beforeEach' || name === 'afterEach') {
self.test.pending = true;
} else {
- suite.tests.forEach(function (test) {
+ suite.tests.forEach(function(test) {
test.pending = true;
});
// a pending hook won't be executed twice.
@@ -4641,7 +4966,7 @@
});
}
- Runner.immediately(function () {
+ Runner.immediately(function() {
next(0);
});
};
@@ -4655,11 +4980,11 @@
* @param {Array} suites
* @param {Function} fn
*/
-Runner.prototype.hooks = function (name, suites, fn) {
+Runner.prototype.hooks = function(name, suites, fn) {
var self = this;
var orig = this.suite;
- function next (suite) {
+ function next(suite) {
self.suite = suite;
if (!suite) {
@@ -4667,7 +4992,7 @@
return fn();
}
- self.hook(name, function (err) {
+ self.hook(name, function(err) {
if (err) {
var errSuite = self.suite;
self.suite = orig;
@@ -4688,7 +5013,7 @@
* @param {Function} fn
* @api private
*/
-Runner.prototype.hookUp = function (name, fn) {
+Runner.prototype.hookUp = function(name, fn) {
var suites = [this.suite].concat(this.parents()).reverse();
this.hooks(name, suites, fn);
};
@@ -4700,7 +5025,7 @@
* @param {Function} fn
* @api private
*/
-Runner.prototype.hookDown = function (name, fn) {
+Runner.prototype.hookDown = function(name, fn) {
var suites = [this.suite].concat(this.parents());
this.hooks(name, suites, fn);
};
@@ -4712,7 +5037,7 @@
* @return {Array}
* @api private
*/
-Runner.prototype.parents = function () {
+Runner.prototype.parents = function() {
var suite = this.suite;
var suites = [];
while (suite.parent) {
@@ -4728,7 +5053,7 @@
* @param {Function} fn
* @api private
*/
-Runner.prototype.runTest = function (fn) {
+Runner.prototype.runTest = function(fn) {
var self = this;
var test = this.test;
@@ -4742,7 +5067,7 @@
if (this.asyncOnly) {
test.asyncOnly = true;
}
- test.on('error', function (err) {
+ test.on('error', function(err) {
self.fail(test, err);
});
if (this.allowUncaught) {
@@ -4763,12 +5088,12 @@
* @param {Suite} suite
* @param {Function} fn
*/
-Runner.prototype.runTests = function (suite, fn) {
+Runner.prototype.runTests = function(suite, fn) {
var self = this;
var tests = suite.tests.slice();
var test;
- function hookErr (_, errSuite, after) {
+ function hookErr(_, errSuite, after) {
// before/after Each hook for errSuite failed:
var orig = self.suite;
@@ -4778,7 +5103,7 @@
if (self.suite) {
// call hookUp afterEach
- self.hookUp('afterEach', function (err2, errSuite2) {
+ self.hookUp('afterEach', function(err2, errSuite2) {
self.suite = orig;
// some hooks may fail even now
if (err2) {
@@ -4794,7 +5119,7 @@
}
}
- function next (err, errSuite) {
+ function next(err, errSuite) {
// if we bail after first err
if (self.failures && suite._bail) {
return fn();
@@ -4851,8 +5176,8 @@
}
// execute test and hook(s)
- self.emit('test', self.test = test);
- self.hookDown('beforeEach', function (err, errSuite) {
+ self.emit('test', (self.test = test));
+ self.hookDown('beforeEach', function(err, errSuite) {
if (test.isPending()) {
if (self.forbidPending) {
test.isPending = alwaysFalse;
@@ -4868,7 +5193,7 @@
return hookErr(err, errSuite, false);
}
self.currentRunnable = self.test;
- self.runTest(function (err) {
+ self.runTest(function(err) {
test = self.test;
if (err) {
var retry = test.currentRetry();
@@ -4910,7 +5235,7 @@
next();
};
-function alwaysFalse () {
+function alwaysFalse() {
return false;
}
@@ -4921,7 +5246,7 @@
* @param {Suite} suite
* @param {Function} fn
*/
-Runner.prototype.runSuite = function (suite, fn) {
+Runner.prototype.runSuite = function(suite, fn) {
var i = 0;
var self = this;
var total = this.grepTotal(suite);
@@ -4933,9 +5258,9 @@
return fn();
}
- this.emit('suite', this.suite = suite);
+ this.emit('suite', (this.suite = suite));
- function next (errSuite) {
+ function next(errSuite) {
if (errSuite) {
// current suite failed on a hook from errSuite
if (errSuite === suite) {
@@ -4961,7 +5286,7 @@
// huge recursive loop and thus a maximum call stack error.
// See comment in `this.runTests()` for more information.
if (self._grep !== self._defaultGrep) {
- Runner.immediately(function () {
+ Runner.immediately(function() {
self.runSuite(curr, next);
});
} else {
@@ -4969,7 +5294,7 @@
}
}
- function done (errSuite) {
+ function done(errSuite) {
self.suite = suite;
self.nextSuite = next;
@@ -4983,7 +5308,7 @@
// remove reference to test
delete self.test;
- self.hook('afterAll', function () {
+ self.hook('afterAll', function() {
self.emit('suite end', suite);
fn(errSuite);
});
@@ -4992,7 +5317,7 @@
this.nextSuite = next;
- this.hook('beforeAll', function (err) {
+ this.hook('beforeAll', function(err) {
if (err) {
return done();
}
@@ -5006,11 +5331,17 @@
* @param {Error} err
* @api private
*/
-Runner.prototype.uncaught = function (err) {
+Runner.prototype.uncaught = function(err) {
if (err) {
- debug('uncaught exception %s', err === (function () {
- return this;
- }.call(err)) ? (err.message || err) : err);
+ debug(
+ 'uncaught exception %s',
+ err ===
+ function() {
+ return this;
+ }.call(err)
+ ? err.message || err
+ : err
+ );
} else {
debug('uncaught undefined exception');
err = undefinedError();
@@ -5037,12 +5368,17 @@
runnable.clearTimeout();
- // Ignore errors if complete or pending
- if (runnable.state || runnable.isPending()) {
+ // Ignore errors if already failed or pending
+ // See #3226
+ if (runnable.isFailed() || runnable.isPending()) {
return;
}
+ // we cannot recover gracefully if a Runnable has already passed
+ // then fails asynchronously
+ var alreadyPassed = runnable.isPassed();
+ // this will change the state to "failed" regardless of the current value
this.fail(runnable, err);
-
+ if (!alreadyPassed) {
// recover from test
if (runnable.type === 'test') {
this.emit('test end', runnable);
@@ -5051,7 +5387,6 @@
}
// recover from hooks
- if (runnable.type === 'hook') {
var errSuite = this.suite;
// if hook failure is in afterEach block
if (runnable.fullTitle().indexOf('after each') > -1) {
@@ -5079,8 +5414,8 @@
*
* @param {Suite} suite
*/
-function cleanSuiteReferences (suite) {
- function cleanArrReferences (arr) {
+function cleanSuiteReferences(suite) {
+ function cleanArrReferences(arr) {
for (var i = 0; i < arr.length; i++) {
delete arr[i].fn;
}
@@ -5111,31 +5446,30 @@
* Run the root suite and invoke `fn(failures)`
* on completion.
*
- * @param {Function} fn
- * @return {Runner} for chaining
* @api public
+ * @public
+ * @memberof Mocha.Runner
* @param {Function} fn
* @return {Runner} Runner instance.
*/
-Runner.prototype.run = function (fn) {
+Runner.prototype.run = function(fn) {
var self = this;
var rootSuite = this.suite;
- // If there is an `only` filter
- if (hasOnly(rootSuite)) {
- filterOnly(rootSuite);
- }
+ fn = fn || function() {};
- fn = fn || function () {};
-
- function uncaught (err) {
+ function uncaught(err) {
self.uncaught(err);
}
- function start () {
+ function start() {
+ // If there is an `only` filter
+ if (hasOnly(rootSuite)) {
+ filterOnly(rootSuite);
+ }
self.started = true;
self.emit('start');
- self.runSuite(rootSuite, function () {
+ self.runSuite(rootSuite, function() {
debug('finished running');
self.emit('end');
});
@@ -5147,7 +5481,7 @@
this.on('suite end', cleanSuiteReferences);
// callback
- this.on('end', function () {
+ this.on('end', function() {
debug('end');
process.removeListener('uncaughtException', uncaught);
fn(self.failures);
@@ -5171,10 +5505,12 @@
/**
* Cleanly abort execution.
*
+ * @memberof Mocha.Runner
+ * @public
* @api public
* @return {Runner} Runner instance.
*/
-Runner.prototype.abort = function () {
+Runner.prototype.abort = function() {
debug('aborting');
this._abort = true;
@@ -5188,7 +5524,7 @@
* @returns {Boolean}
* @api private
*/
-function filterOnly (suite) {
+function filterOnly(suite) {
if (suite._onlyTests.length) {
// If the suite contains `only` tests, run those and ignore any nested suites.
suite.tests = suite._onlyTests;
@@ -5196,7 +5532,7 @@
} else {
// Otherwise, do not run any of the tests in this suite.
suite.tests = [];
- suite._onlySuites.forEach(function (onlySuite) {
+ suite._onlySuites.forEach(function(onlySuite) {
// If there are other `only` tests/suites nested in the current `only` suite, then filter that `only` suite.
// Otherwise, all of the tests on this `only` suite should be run, so don't filter it.
if (hasOnly(onlySuite)) {
@@ -5204,8 +5540,10 @@
}
});
// Run the `only` suites, as well as any other suites that have `only` tests/suites as descendants.
- suite.suites = suite.suites.filter(function (childSuite) {
- return suite._onlySuites.indexOf(childSuite) !== -1 || filterOnly(childSuite);
+ suite.suites = suite.suites.filter(function(childSuite) {
+ return (
+ suite._onlySuites.indexOf(childSuite) !== -1 || filterOnly(childSuite)
+ );
});
}
// Keep the suite only if there is something to run
@@ -5219,8 +5557,12 @@
* @returns {Boolean}
* @api private
*/
-function hasOnly (suite) {
- return suite._onlyTests.length || suite._onlySuites.length || suite.suites.some(hasOnly);
+function hasOnly(suite) {
+ return (
+ suite._onlyTests.length ||
+ suite._onlySuites.length ||
+ suite.suites.some(hasOnly)
+ );
}
/**
@@ -5231,8 +5573,8 @@
* @param {Array} globals
* @return {Array}
*/
-function filterLeaks (ok, globals) {
- return globals.filter(function (key) {
+function filterLeaks(ok, globals) {
+ return globals.filter(function(key) {
// Firefox and Chrome exposes iframes as index inside the window object
if (/^\d+/.test(key)) {
return false;
@@ -5241,13 +5583,13 @@
// in firefox
// if runner runs in an iframe, this iframe's window.getInterface method
// not init at first it is assigned in some seconds
- if (global.navigator && (/^getInterface/).test(key)) {
+ if (global.navigator && /^getInterface/.test(key)) {
return false;
}
// an iframe could be approached by window[iframeIndex]
// in ie6,7,8 and opera, iframeIndex is enumerable, this could cause leak
- if (global.navigator && (/^\d+/).test(key)) {
+ if (global.navigator && /^\d+/.test(key)) {
return false;
}
@@ -5256,7 +5598,7 @@
return false;
}
- var matched = ok.filter(function (ok) {
+ var matched = ok.filter(function(ok) {
if (~ok.indexOf('*')) {
return key.indexOf(ok.split('*')[0]) === 0;
}
@@ -5272,16 +5614,16 @@
* @return {Array}
* @api private
*/
-function extraGlobals () {
+function extraGlobals() {
if (typeof process === 'object' && typeof process.version === 'string') {
var parts = process.version.split('.');
- var nodeVersion = parts.reduce(function (a, v) {
- return a << 8 | v;
+ var nodeVersion = parts.reduce(function(a, v) {
+ return (a << 8) | v;
});
// 'errno' was renamed to process._errno in v0.9.11.
- if (nodeVersion < 0x00090B) {
+ if (nodeVersion < 0x00090b) {
return ['errno'];
}
}
@@ -5292,6 +5634,9 @@
}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{"./pending":15,"./runnable":32,"./utils":36,"_process":56,"debug":43,"events":47}],34:[function(require,module,exports){
'use strict';
+/**
+ * @module Suite
+ */
/**
* Module dependencies.
@@ -5315,12 +5659,14 @@
* with the same title is already present, that suite is returned to provide
* nicer reporter and more flexible meta-testing.
*
+ * @memberof Mocha
+ * @public
* @api public
* @param {Suite} parent
* @param {string} title
* @return {Suite}
*/
-exports.create = function (parent, title) {
+exports.create = function(parent, title) {
var suite = new Suite(title, parent.ctx);
suite.parent = parent;
title = suite.fullTitle();
@@ -5329,18 +5675,24 @@
};
/**
- * Initialize a new `Suite` with the given `title` and `ctx`.
+ * Initialize a new `Suite` with the given `title` and `ctx`. Derived from [EventEmitter](https://nodejs.org/api/events.html#events_class_eventemitter)
*
- * @api private
+ * @memberof Mocha
+ * @public
+ * @class
* @param {string} title
* @param {Context} parentContext
*/
-function Suite (title, parentContext) {
+function Suite(title, parentContext) {
if (!utils.isString(title)) {
- throw new Error('Suite `title` should be a "string" but "' + typeof title + '" was given instead.');
+ throw new Error(
+ 'Suite `title` should be a "string" but "' +
+ typeof title +
+ '" was given instead.'
+ );
}
this.title = title;
- function Context () {}
+ function Context() {}
Context.prototype = parentContext;
this.ctx = new Context();
this.suites = [];
@@ -5372,7 +5724,7 @@
* @api private
* @return {Suite}
*/
-Suite.prototype.clone = function () {
+Suite.prototype.clone = function() {
var suite = new Suite(this.title);
debug('clone');
suite.ctx = this.ctx;
@@ -5391,7 +5743,7 @@
* @param {number|string} ms
* @return {Suite|number} for chaining
*/
-Suite.prototype.timeout = function (ms) {
+Suite.prototype.timeout = function(ms) {
if (!arguments.length) {
return this._timeout;
}
@@ -5413,7 +5765,7 @@
* @param {number|string} n
* @return {Suite|number} for chaining
*/
-Suite.prototype.retries = function (n) {
+Suite.prototype.retries = function(n) {
if (!arguments.length) {
return this._retries;
}
@@ -5429,7 +5781,7 @@
* @param {boolean} enabled
* @return {Suite|boolean} self or enabled
*/
-Suite.prototype.enableTimeouts = function (enabled) {
+Suite.prototype.enableTimeouts = function(enabled) {
if (!arguments.length) {
return this._enableTimeouts;
}
@@ -5445,7 +5797,7 @@
* @param {number|string} ms
* @return {Suite|number} for chaining
*/
-Suite.prototype.slow = function (ms) {
+Suite.prototype.slow = function(ms) {
if (!arguments.length) {
return this._slow;
}
@@ -5464,7 +5816,7 @@
* @param {boolean} bail
* @return {Suite|number} for chaining
*/
-Suite.prototype.bail = function (bail) {
+Suite.prototype.bail = function(bail) {
if (!arguments.length) {
return this._bail;
}
@@ -5478,11 +5830,30 @@
*
* @api private
*/
-Suite.prototype.isPending = function () {
+Suite.prototype.isPending = function() {
return this.pending || (this.parent && this.parent.isPending());
};
/**
+ * Generic hook-creator.
+ * @private
+ * @param {string} title - Title of hook
+ * @param {Function} fn - Hook callback
+ * @returns {Hook} A new hook
+ */
+Suite.prototype._createHook = function(title, fn) {
+ var hook = new Hook(title, fn);
+ hook.parent = this;
+ hook.timeout(this.timeout());
+ hook.retries(this.retries());
+ hook.enableTimeouts(this.enableTimeouts());
+ hook.slow(this.slow());
+ hook.ctx = this.ctx;
+ hook.file = this.file;
+ return hook;
+};
+
+/**
* Run `fn(test[, done])` before running tests.
*
* @api private
@@ -5490,7 +5861,7 @@
* @param {Function} fn
* @return {Suite} for chaining
*/
-Suite.prototype.beforeAll = function (title, fn) {
+Suite.prototype.beforeAll = function(title, fn) {
if (this.isPending()) {
return this;
}
@@ -5500,13 +5871,7 @@
}
title = '"before all" hook' + (title ? ': ' + title : '');
- var hook = new Hook(title, fn);
- hook.parent = this;
- hook.timeout(this.timeout());
- hook.retries(this.retries());
- hook.enableTimeouts(this.enableTimeouts());
- hook.slow(this.slow());
- hook.ctx = this.ctx;
+ var hook = this._createHook(title, fn);
this._beforeAll.push(hook);
this.emit('beforeAll', hook);
return this;
@@ -5520,7 +5885,7 @@
* @param {Function} fn
* @return {Suite} for chaining
*/
-Suite.prototype.afterAll = function (title, fn) {
+Suite.prototype.afterAll = function(title, fn) {
if (this.isPending()) {
return this;
}
@@ -5530,13 +5895,7 @@
}
title = '"after all" hook' + (title ? ': ' + title : '');
- var hook = new Hook(title, fn);
- hook.parent = this;
- hook.timeout(this.timeout());
- hook.retries(this.retries());
- hook.enableTimeouts(this.enableTimeouts());
- hook.slow(this.slow());
- hook.ctx = this.ctx;
+ var hook = this._createHook(title, fn);
this._afterAll.push(hook);
this.emit('afterAll', hook);
return this;
@@ -5550,7 +5909,7 @@
* @param {Function} fn
* @return {Suite} for chaining
*/
-Suite.prototype.beforeEach = function (title, fn) {
+Suite.prototype.beforeEach = function(title, fn) {
if (this.isPending()) {
return this;
}
@@ -5560,13 +5919,7 @@
}
title = '"before each" hook' + (title ? ': ' + title : '');
- var hook = new Hook(title, fn);
- hook.parent = this;
- hook.timeout(this.timeout());
- hook.retries(this.retries());
- hook.enableTimeouts(this.enableTimeouts());
- hook.slow(this.slow());
- hook.ctx = this.ctx;
+ var hook = this._createHook(title, fn);
this._beforeEach.push(hook);
this.emit('beforeEach', hook);
return this;
@@ -5580,7 +5933,7 @@
* @param {Function} fn
* @return {Suite} for chaining
*/
-Suite.prototype.afterEach = function (title, fn) {
+Suite.prototype.afterEach = function(title, fn) {
if (this.isPending()) {
return this;
}
@@ -5590,13 +5943,7 @@
}
title = '"after each" hook' + (title ? ': ' + title : '');
- var hook = new Hook(title, fn);
- hook.parent = this;
- hook.timeout(this.timeout());
- hook.retries(this.retries());
- hook.enableTimeouts(this.enableTimeouts());
- hook.slow(this.slow());
- hook.ctx = this.ctx;
+ var hook = this._createHook(title, fn);
this._afterEach.push(hook);
this.emit('afterEach', hook);
return this;
@@ -5609,7 +5956,7 @@
* @param {Suite} suite
* @return {Suite} for chaining
*/
-Suite.prototype.addSuite = function (suite) {
+Suite.prototype.addSuite = function(suite) {
suite.parent = this;
suite.timeout(this.timeout());
suite.retries(this.retries());
@@ -5628,7 +5975,7 @@
* @param {Test} test
* @return {Suite} for chaining
*/
-Suite.prototype.addTest = function (test) {
+Suite.prototype.addTest = function(test) {
test.parent = this;
test.timeout(this.timeout());
test.retries(this.retries());
@@ -5644,10 +5991,12 @@
* Return the full title generated by recursively concatenating the parent's
* full title.
*
+ * @memberof Mocha.Suite
+ * @public
* @api public
* @return {string}
*/
-Suite.prototype.fullTitle = function () {
+Suite.prototype.fullTitle = function() {
return this.titlePath().join(' ');
};
@@ -5655,10 +6004,12 @@
* Return the title path generated by recursively concatenating the parent's
* title path.
*
+ * @memberof Mocha.Suite
+ * @public
* @api public
* @return {string}
*/
-Suite.prototype.titlePath = function () {
+Suite.prototype.titlePath = function() {
var result = [];
if (this.parent) {
result = result.concat(this.parent.titlePath());
@@ -5672,13 +6023,17 @@
/**
* Return the total number of tests.
*
+ * @memberof Mocha.Suite
+ * @public
* @api public
* @return {number}
*/
-Suite.prototype.total = function () {
- return this.suites.reduce(function (sum, suite) {
+Suite.prototype.total = function() {
+ return (
+ this.suites.reduce(function(sum, suite) {
return sum + suite.total();
- }, 0) + this.tests.length;
+ }, 0) + this.tests.length
+ );
};
/**
@@ -5689,9 +6044,9 @@
* @param {Function} fn
* @return {Suite}
*/
-Suite.prototype.eachTest = function (fn) {
+Suite.prototype.eachTest = function(fn) {
this.tests.forEach(fn);
- this.suites.forEach(function (suite) {
+ this.suites.forEach(function(suite) {
suite.eachTest(fn);
});
return this;
@@ -5700,7 +6055,7 @@
/**
* This will run the root suite if we happen to be running in delayed mode.
*/
-Suite.prototype.run = function run () {
+Suite.prototype.run = function run() {
if (this.root) {
this.emit('run');
}
@@ -5708,31 +6063,27 @@
},{"./hook":6,"./ms":14,"./utils":36,"debug":43,"events":47}],35:[function(require,module,exports){
'use strict';
-
-/**
- * Module dependencies.
- */
-
var Runnable = require('./runnable');
var utils = require('./utils');
var isString = utils.isString;
-/**
- * Expose `Test`.
- */
-
module.exports = Test;
/**
* Initialize a new `Test` with the given `title` and callback `fn`.
*
- * @api private
+ * @class
+ * @extends Runnable
* @param {String} title
* @param {Function} fn
*/
-function Test (title, fn) {
+function Test(title, fn) {
if (!isString(title)) {
- throw new Error('Test `title` should be a "string" but "' + typeof title + '" was given instead.');
+ throw new Error(
+ 'Test `title` should be a "string" but "' +
+ typeof title +
+ '" was given instead.'
+ );
}
Runnable.call(this, title, fn);
this.pending = !fn;
@@ -5744,7 +6095,7 @@
*/
utils.inherits(Test, Runnable);
-Test.prototype.clone = function () {
+Test.prototype.clone = function() {
var test = new Test(this.title, this.fn);
test.timeout(this.timeout());
test.slow(this.slow());
@@ -5762,22 +6113,19 @@
(function (process,Buffer){
'use strict';
-/* eslint-env browser */
+/**
+ * @module
+ */
/**
* Module dependencies.
*/
-var basename = require('path').basename;
var debug = require('debug')('mocha:watch');
-var exists = require('fs').existsSync;
+var fs = require('fs');
var glob = require('glob');
var path = require('path');
var join = path.join;
-var readdirSync = require('fs').readdirSync;
-var statSync = require('fs').statSync;
-var watchFile = require('fs').watchFile;
-var lstatSync = require('fs').lstatSync;
var he = require('he');
/**
@@ -5795,8 +6143,8 @@
* @param {string} html
* @return {string}
*/
-exports.escape = function (html) {
- return he.encode(String(html), { useNamedReferences: false });
+exports.escape = function(html) {
+ return he.encode(String(html), {useNamedReferences: false});
};
/**
@@ -5806,7 +6154,7 @@
* @param {Object} obj
* @return {boolean}
*/
-exports.isString = function (obj) {
+exports.isString = function(obj) {
return typeof obj === 'string';
};
@@ -5818,11 +6166,11 @@
* @param {Array} files
* @param {Function} fn
*/
-exports.watch = function (files, fn) {
- var options = { interval: 100 };
- files.forEach(function (file) {
+exports.watch = function(files, fn) {
+ var options = {interval: 100};
+ files.forEach(function(file) {
debug('file %s', file);
- watchFile(file, options, function (curr, prev) {
+ fs.watchFile(file, options, function(curr, prev) {
if (prev.mtime < curr.mtime) {
fn(file);
}
@@ -5837,7 +6185,7 @@
* @param {string} path
* @return {boolean}
*/
-function ignored (path) {
+function ignored(path) {
return !~ignore.indexOf(path);
}
@@ -5850,17 +6198,18 @@
* @param {Array} [ret=[]]
* @return {Array}
*/
-exports.files = function (dir, ext, ret) {
+exports.files = function(dir, ext, ret) {
ret = ret || [];
ext = ext || ['js'];
var re = new RegExp('\\.(' + ext.join('|') + ')$');
- readdirSync(dir)
+ fs
+ .readdirSync(dir)
.filter(ignored)
- .forEach(function (path) {
+ .forEach(function(path) {
path = join(dir, path);
- if (lstatSync(path).isDirectory()) {
+ if (fs.lstatSync(path).isDirectory()) {
exports.files(path, ext, ret);
} else if (path.match(re)) {
ret.push(path);
@@ -5877,7 +6226,7 @@
* @param {string} str
* @return {string}
*/
-exports.slug = function (str) {
+exports.slug = function(str) {
return str
.toLowerCase()
.replace(/ +/g, '-')
@@ -5890,15 +6239,22 @@
* @param {string} str
* @return {string}
*/
-exports.clean = function (str) {
+exports.clean = function(str) {
str = str
- .replace(/\r\n?|[\n\u2028\u2029]/g, '\n').replace(/^\uFEFF/, '')
+ .replace(/\r\n?|[\n\u2028\u2029]/g, '\n')
+ .replace(/^\uFEFF/, '')
// (traditional)-> space/name parameters body (lambda)-> parameters body multi-statement/single keep body content
- .replace(/^function(?:\s*|\s+[^(]*)\([^)]*\)\s*\{((?:.|\n)*?)\s*\}$|^\([^)]*\)\s*=>\s*(?:\{((?:.|\n)*?)\s*\}|((?:.|\n)*))$/, '$1$2$3');
+ .replace(
+ /^function(?:\s*|\s+[^(]*)\([^)]*\)\s*\{((?:.|\n)*?)\s*\}$|^\([^)]*\)\s*=>\s*(?:\{((?:.|\n)*?)\s*\}|((?:.|\n)*))$/,
+ '$1$2$3'
+ );
var spaces = str.match(/^\n?( *)/)[1].length;
var tabs = str.match(/^\n?(\t*)/)[1].length;
- var re = new RegExp('^\n?' + (tabs ? '\t' : ' ') + '{' + (tabs || spaces) + '}', 'gm');
+ var re = new RegExp(
+ '^\n?' + (tabs ? '\t' : ' ') + '{' + (tabs || spaces) + '}',
+ 'gm'
+ );
str = str.replace(re, '');
@@ -5912,8 +6268,11 @@
* @param {string} qs
* @return {Object}
*/
-exports.parseQuery = function (qs) {
- return qs.replace('?', '').split('&').reduce(function (obj, pair) {
+exports.parseQuery = function(qs) {
+ return qs
+ .replace('?', '')
+ .split('&')
+ .reduce(function(obj, pair) {
var i = pair.indexOf('=');
var key = pair.slice(0, i);
var val = pair.slice(++i);
@@ -5932,7 +6291,7 @@
* @param {string} js
* @return {string}
*/
-function highlight (js) {
+function highlight(js) {
return js
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
@@ -5940,8 +6299,14 @@
.replace(/('.*?')/gm, '<span class="string">$1</span>')
.replace(/(\d+\.\d+)/gm, '<span class="number">$1</span>')
.replace(/(\d+)/gm, '<span class="number">$1</span>')
- .replace(/\bnew[ \t]+(\w+)/gm, '<span class="keyword">new</span> <span class="init">$1</span>')
- .replace(/\b(function|new|throw|return|var|if|else)\b/gm, '<span class="keyword">$1</span>');
+ .replace(
+ /\bnew[ \t]+(\w+)/gm,
+ '<span class="keyword">new</span> <span class="init">$1</span>'
+ )
+ .replace(
+ /\b(function|new|throw|return|var|if|else)\b/gm,
+ '<span class="keyword">$1</span>'
+ );
}
/**
@@ -5950,7 +6315,7 @@
* @api private
* @param {string} name
*/
-exports.highlightTags = function (name) {
+exports.highlightTags = function(name) {
var code = document.getElementById('mocha').getElementsByTagName(name);
for (var i = 0, len = code.length; i < len; ++i) {
code[i].innerHTML = highlight(code[i].innerHTML);
@@ -5971,7 +6336,7 @@
* @param {string} typeHint The type of the value
* @returns {string}
*/
-function emptyRepresentation (value, typeHint) {
+function emptyRepresentation(value, typeHint) {
switch (typeHint) {
case 'function':
return '[Function]';
@@ -6005,7 +6370,7 @@
* type(global) // 'global'
* type(new String('foo') // 'object'
*/
-var type = exports.type = function type (value) {
+var type = (exports.type = function type(value) {
if (value === undefined) {
return 'undefined';
} else if (value === null) {
@@ -6013,10 +6378,11 @@
} else if (Buffer.isBuffer(value)) {
return 'buffer';
}
- return Object.prototype.toString.call(value)
+ return Object.prototype.toString
+ .call(value)
.replace(/^\[.+\s(.+?)]$/, '$1')
.toLowerCase();
-};
+});
/**
* Stringify `value`. Different behavior depending on type of value:
@@ -6033,21 +6399,23 @@
* @param {*} value
* @return {string}
*/
-exports.stringify = function (value) {
+exports.stringify = function(value) {
var typeHint = type(value);
if (!~['object', 'array', 'function'].indexOf(typeHint)) {
if (typeHint === 'buffer') {
var json = Buffer.prototype.toJSON.call(value);
// Based on the toJSON result
- return jsonStringify(json.data && json.type ? json.data : json, 2)
- .replace(/,(\n|$)/g, '$1');
+ return jsonStringify(
+ json.data && json.type ? json.data : json,
+ 2
+ ).replace(/,(\n|$)/g, '$1');
}
// IE7/IE8 has a bizarre String constructor; needs to be coerced
// into an array and back to obj.
if (typeHint === 'string' && typeof value === 'object') {
- value = value.split('').reduce(function (acc, char, idx) {
+ value = value.split('').reduce(function(acc, char, idx) {
acc[idx] = char;
return acc;
}, {});
@@ -6059,7 +6427,10 @@
for (var prop in value) {
if (Object.prototype.hasOwnProperty.call(value, prop)) {
- return jsonStringify(exports.canonicalize(value, null, typeHint), 2).replace(/,(\n|$)/g, '$1');
+ return jsonStringify(
+ exports.canonicalize(value, null, typeHint),
+ 2
+ ).replace(/,(\n|$)/g, '$1');
}
}
@@ -6075,7 +6446,7 @@
* @param {number=} depth
* @returns {*}
*/
-function jsonStringify (object, spaces, depth) {
+function jsonStringify(object, spaces, depth) {
if (typeof spaces === 'undefined') {
// primitive types
return _stringify(object);
@@ -6085,13 +6456,16 @@
var space = spaces * depth;
var str = Array.isArray(object) ? '[' : '{';
var end = Array.isArray(object) ? ']' : '}';
- var length = typeof object.length === 'number' ? object.length : Object.keys(object).length;
+ var length =
+ typeof object.length === 'number'
+ ? object.length
+ : Object.keys(object).length;
// `.repeat()` polyfill
- function repeat (s, n) {
+ function repeat(s, n) {
return new Array(n).join(s);
}
- function _stringify (val) {
+ function _stringify(val) {
switch (type(val)) {
case 'null':
case 'undefined':
@@ -6105,7 +6479,8 @@
case 'regexp':
case 'symbol':
case 'number':
- val = val === 0 && (1 / val) === -Infinity // `-0`
+ val =
+ val === 0 && 1 / val === -Infinity // `-0`
? '-0'
: val.toString();
break;
@@ -6120,7 +6495,8 @@
val = '[Buffer: ' + jsonStringify(json, 2, depth + 1) + ']';
break;
default:
- val = (val === '[Function]' || val === '[Circular]')
+ val =
+ val === '[Function]' || val === '[Circular]'
? val
: JSON.stringify(val); // string
}
@@ -6132,15 +6508,19 @@
continue; // not my business
}
--length;
- str += '\n ' + repeat(' ', space) +
+ str +=
+ '\n ' +
+ repeat(' ', space) +
(Array.isArray(object) ? '' : '"' + i + '": ') + // key
_stringify(object[i]) + // value
(length ? ',' : ''); // comma
}
- return str +
+ return (
+ str +
// [], {}
- (str.length !== 1 ? '\n' + repeat(' ', --space) + end : end);
+ (str.length !== 1 ? '\n' + repeat(' ', --space) + end : end)
+ );
}
/**
@@ -6162,13 +6542,13 @@
* @param {string} [typeHint] Type hint
* @return {(Object|Array|Function|string|undefined)}
*/
-exports.canonicalize = function canonicalize (value, stack, typeHint) {
+exports.canonicalize = function canonicalize(value, stack, typeHint) {
var canonicalizedObj;
/* eslint-disable no-unused-vars */
var prop;
/* eslint-enable no-unused-vars */
typeHint = typeHint || type(value);
- function withStack (value, fn) {
+ function withStack(value, fn) {
stack.push(value);
fn();
stack.pop();
@@ -6187,8 +6567,8 @@
canonicalizedObj = value;
break;
case 'array':
- withStack(value, function () {
- canonicalizedObj = value.map(function (item) {
+ withStack(value, function() {
+ canonicalizedObj = value.map(function(item) {
return exports.canonicalize(item, stack);
});
});
@@ -6207,8 +6587,10 @@
/* falls through */
case 'object':
canonicalizedObj = canonicalizedObj || {};
- withStack(value, function () {
- Object.keys(value).sort().forEach(function (key) {
+ withStack(value, function() {
+ Object.keys(value)
+ .sort()
+ .forEach(function(key) {
canonicalizedObj[key] = exports.canonicalize(value[key], stack);
});
});
@@ -6230,41 +6612,43 @@
/**
* Lookup file names at the given `path`.
*
+ * @memberof Mocha.utils
+ * @public
* @api public
- * @param {string} path Base path to start searching from.
+ * @param {string} filepath Base path to start searching from.
* @param {string[]} extensions File extensions to look for.
* @param {boolean} recursive Whether or not to recurse into subdirectories.
* @return {string[]} An array of paths.
*/
-exports.lookupFiles = function lookupFiles (path, extensions, recursive) {
+exports.lookupFiles = function lookupFiles(filepath, extensions, recursive) {
var files = [];
- if (!exists(path)) {
- if (exists(path + '.js')) {
- path += '.js';
+ if (!fs.existsSync(filepath)) {
+ if (fs.existsSync(filepath + '.js')) {
+ filepath += '.js';
} else {
- files = glob.sync(path);
+ files = glob.sync(filepath);
if (!files.length) {
- throw new Error("cannot resolve path (or pattern) '" + path + "'");
+ throw new Error("cannot resolve path (or pattern) '" + filepath + "'");
}
return files;
}
}
try {
- var stat = statSync(path);
+ var stat = fs.statSync(filepath);
if (stat.isFile()) {
- return path;
+ return filepath;
}
} catch (err) {
// ignore error
return;
}
- readdirSync(path).forEach(function (file) {
- file = join(path, file);
+ fs.readdirSync(filepath).forEach(function(file) {
+ file = path.join(filepath, file);
try {
- var stat = statSync(file);
+ var stat = fs.statSync(file);
if (stat.isDirectory()) {
if (recursive) {
files = files.concat(lookupFiles(file, extensions, recursive));
@@ -6275,8 +6659,13 @@
// ignore error
return;
}
+ if (!extensions) {
+ throw new Error(
+ 'extensions parameter required when filepath is a directory'
+ );
+ }
var re = new RegExp('\\.(?:' + extensions.join('|') + ')$');
- if (!stat.isFile() || !re.test(file) || basename(file)[0] === '.') {
+ if (!stat.isFile() || !re.test(file) || path.basename(file)[0] === '.') {
return;
}
files.push(file);
@@ -6291,8 +6680,10 @@
* @return {Error}
*/
-exports.undefinedError = function () {
- return new Error('Caught undefined error, did you throw without specifying what?');
+exports.undefinedError = function() {
+ return new Error(
+ 'Caught undefined error, did you throw without specifying what?'
+ );
};
/**
@@ -6302,7 +6693,7 @@
* @return {Error}
*/
-exports.getError = function (err) {
+exports.getError = function(err) {
return err || exports.undefinedError();
};
@@ -6315,9 +6706,9 @@
* (i.e: strip Mocha and internal node functions from stack trace).
* @returns {Function}
*/
-exports.stackTraceFilter = function () {
+exports.stackTraceFilter = function() {
// TODO: Replace with `process.browser`
- var is = typeof document === 'undefined' ? { node: true } : { browser: true };
+ var is = typeof document === 'undefined' ? {node: true} : {browser: true};
var slash = path.sep;
var cwd;
if (is.node) {
@@ -6325,30 +6716,35 @@
} else {
cwd = (typeof location === 'undefined'
? window.location
- : location).href.replace(/\/[^/]*$/, '/');
+ : location
+ ).href.replace(/\/[^/]*$/, '/');
slash = '/';
}
- function isMochaInternal (line) {
- return (~line.indexOf('node_modules' + slash + 'mocha' + slash)) ||
- (~line.indexOf('node_modules' + slash + 'mocha.js')) ||
- (~line.indexOf('bower_components' + slash + 'mocha.js')) ||
- (~line.indexOf(slash + 'mocha.js'));
- }
-
- function isNodeInternal (line) {
- return (~line.indexOf('(timers.js:')) ||
- (~line.indexOf('(events.js:')) ||
- (~line.indexOf('(node.js:')) ||
- (~line.indexOf('(module.js:')) ||
- (~line.indexOf('GeneratorFunctionPrototype.next (native)')) ||
- false;
+ function isMochaInternal(line) {
+ return (
+ ~line.indexOf('node_modules' + slash + 'mocha' + slash) ||
+ ~line.indexOf('node_modules' + slash + 'mocha.js') ||
+ ~line.indexOf('bower_components' + slash + 'mocha.js') ||
+ ~line.indexOf(slash + 'mocha.js')
+ );
+ }
+
+ function isNodeInternal(line) {
+ return (
+ ~line.indexOf('(timers.js:') ||
+ ~line.indexOf('(events.js:') ||
+ ~line.indexOf('(node.js:') ||
+ ~line.indexOf('(module.js:') ||
+ ~line.indexOf('GeneratorFunctionPrototype.next (native)') ||
+ false
+ );
}
- return function (stack) {
+ return function(stack) {
stack = stack.split('\n');
- stack = stack.reduce(function (list, line) {
+ stack = stack.reduce(function(list, line) {
if (isMochaInternal(line)) {
return list;
}
@@ -6359,7 +6755,7 @@
// Clean up cwd(absolute)
if (/\(?.+:\d+:\d+\)?$/.test(line)) {
- line = line.replace(cwd, '');
+ line = line.replace('(' + cwd, '(');
}
list.push(line);
@@ -6376,7 +6772,7 @@
* @param {*} value
* @returns {boolean} Whether or not `value` is a Promise
*/
-exports.isPromise = function isPromise (value) {
+exports.isPromise = function isPromise(value) {
return typeof value === 'object' && typeof value.then === 'function';
};
@@ -6384,7 +6780,7 @@
* It's a noop.
* @api
*/
-exports.noop = function () {};
+exports.noop = function() {};
}).call(this,require('_process'),require("buffer").Buffer)
},{"_process":56,"buffer":41,"debug":43,"fs":40,"glob":40,"he":48,"path":40,"util":76}],37:[function(require,module,exports){
@@ -6404,68 +6800,102 @@
revLookup[code.charCodeAt(i)] = i
}
+// Support decoding URL-safe base64 strings, as Node.js does.
+// See: https://en.wikipedia.org/wiki/Base64#URL_applications
revLookup['-'.charCodeAt(0)] = 62
revLookup['_'.charCodeAt(0)] = 63
-function placeHoldersCount (b64) {
+function getLens (b64) {
var len = b64.length
+
if (len % 4 > 0) {
throw new Error('Invalid string. Length must be a multiple of 4')
}
- // the number of equal signs (place holders)
- // if there are two placeholders, than the two characters before it
- // represent one byte
- // if there is only one, then the three characters before it represent 2 bytes
- // this is just a cheap hack to not do indexOf twice
- return b64[len - 2] === '=' ? 2 : b64[len - 1] === '=' ? 1 : 0
+ // Trim off extra bytes after placeholder bytes are found
+ // See: https://github.com/beatgammit/base64-js/issues/42
+ var validLen = b64.indexOf('=')
+ if (validLen === -1) validLen = len
+
+ var placeHoldersLen = validLen === len
+ ? 0
+ : 4 - (validLen % 4)
+
+ return [validLen, placeHoldersLen]
}
+// base64 is 4/3 + up to two characters of the original data
function byteLength (b64) {
- // base64 is 4/3 + up to two characters of the original data
- return (b64.length * 3 / 4) - placeHoldersCount(b64)
+ var lens = getLens(b64)
+ var validLen = lens[0]
+ var placeHoldersLen = lens[1]
+ return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen
+}
+
+function _byteLength (b64, validLen, placeHoldersLen) {
+ return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen
}
function toByteArray (b64) {
- var i, l, tmp, placeHolders, arr
- var len = b64.length
- placeHolders = placeHoldersCount(b64)
+ var tmp
+ var lens = getLens(b64)
+ var validLen = lens[0]
+ var placeHoldersLen = lens[1]
- arr = new Arr((len * 3 / 4) - placeHolders)
+ var arr = new Arr(_byteLength(b64, validLen, placeHoldersLen))
- // if there are placeholders, only get up to the last complete 4 chars
- l = placeHolders > 0 ? len - 4 : len
+ var curByte = 0
- var L = 0
+ // if there are placeholders, only get up to the last complete 4 chars
+ var len = placeHoldersLen > 0
+ ? validLen - 4
+ : validLen
- for (i = 0; i < l; i += 4) {
- tmp = (revLookup[b64.charCodeAt(i)] << 18) | (revLookup[b64.charCodeAt(i + 1)] << 12) | (revLookup[b64.charCodeAt(i + 2)] << 6) | revLookup[b64.charCodeAt(i + 3)]
- arr[L++] = (tmp >> 16) & 0xFF
- arr[L++] = (tmp >> 8) & 0xFF
- arr[L++] = tmp & 0xFF
- }
-
- if (placeHolders === 2) {
- tmp = (revLookup[b64.charCodeAt(i)] << 2) | (revLookup[b64.charCodeAt(i + 1)] >> 4)
- arr[L++] = tmp & 0xFF
- } else if (placeHolders === 1) {
- tmp = (revLookup[b64.charCodeAt(i)] << 10) | (revLookup[b64.charCodeAt(i + 1)] << 4) | (revLookup[b64.charCodeAt(i + 2)] >> 2)
- arr[L++] = (tmp >> 8) & 0xFF
- arr[L++] = tmp & 0xFF
+ for (var i = 0; i < len; i += 4) {
+ tmp =
+ (revLookup[b64.charCodeAt(i)] << 18) |
+ (revLookup[b64.charCodeAt(i + 1)] << 12) |
+ (revLookup[b64.charCodeAt(i + 2)] << 6) |
+ revLookup[b64.charCodeAt(i + 3)]
+ arr[curByte++] = (tmp >> 16) & 0xFF
+ arr[curByte++] = (tmp >> 8) & 0xFF
+ arr[curByte++] = tmp & 0xFF
+ }
+
+ if (placeHoldersLen === 2) {
+ tmp =
+ (revLookup[b64.charCodeAt(i)] << 2) |
+ (revLookup[b64.charCodeAt(i + 1)] >> 4)
+ arr[curByte++] = tmp & 0xFF
+ }
+
+ if (placeHoldersLen === 1) {
+ tmp =
+ (revLookup[b64.charCodeAt(i)] << 10) |
+ (revLookup[b64.charCodeAt(i + 1)] << 4) |
+ (revLookup[b64.charCodeAt(i + 2)] >> 2)
+ arr[curByte++] = (tmp >> 8) & 0xFF
+ arr[curByte++] = tmp & 0xFF
}
return arr
}
function tripletToBase64 (num) {
- return lookup[num >> 18 & 0x3F] + lookup[num >> 12 & 0x3F] + lookup[num >> 6 & 0x3F] + lookup[num & 0x3F]
+ return lookup[num >> 18 & 0x3F] +
+ lookup[num >> 12 & 0x3F] +
+ lookup[num >> 6 & 0x3F] +
+ lookup[num & 0x3F]
}
function encodeChunk (uint8, start, end) {
var tmp
var output = []
for (var i = start; i < end; i += 3) {
- tmp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2])
+ tmp =
+ ((uint8[i] << 16) & 0xFF0000) +
+ ((uint8[i + 1] << 8) & 0xFF00) +
+ (uint8[i + 2] & 0xFF)
output.push(tripletToBase64(tmp))
}
return output.join('')
@@ -6475,31 +6905,34 @@
var tmp
var len = uint8.length
var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes
- var output = ''
var parts = []
var maxChunkLength = 16383 // must be multiple of 3
// go through the array every three bytes, we'll deal with trailing stuff later
for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {
- parts.push(encodeChunk(uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength)))
+ parts.push(encodeChunk(
+ uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength)
+ ))
}
// pad the end with zeros, but make sure to not forget the extra bytes
if (extraBytes === 1) {
tmp = uint8[len - 1]
- output += lookup[tmp >> 2]
- output += lookup[(tmp << 4) & 0x3F]
- output += '=='
+ parts.push(
+ lookup[tmp >> 2] +
+ lookup[(tmp << 4) & 0x3F] +
+ '=='
+ )
} else if (extraBytes === 2) {
- tmp = (uint8[len - 2] << 8) + (uint8[len - 1])
- output += lookup[tmp >> 10]
- output += lookup[(tmp >> 4) & 0x3F]
- output += lookup[(tmp << 2) & 0x3F]
- output += '='
+ tmp = (uint8[len - 2] << 8) + uint8[len - 1]
+ parts.push(
+ lookup[tmp >> 10] +
+ lookup[(tmp >> 4) & 0x3F] +
+ lookup[(tmp << 2) & 0x3F] +
+ '='
+ )
}
- parts.push(output)
-
return parts.join('')
}
@@ -6540,7 +6973,7 @@
/*!
* The buffer module from node.js, for the browser.
*
- * @author Feross Aboukhadijeh <feross@feross.org> <http://feross.org>
+ * @author Feross Aboukhadijeh <https://feross.org>
* @license MIT
*/
/* eslint-disable no-proto */
@@ -6592,6 +7025,24 @@
}
}
+Object.defineProperty(Buffer.prototype, 'parent', {
+ get: function () {
+ if (!(this instanceof Buffer)) {
+ return undefined
+ }
+ return this.buffer
+ }
+})
+
+Object.defineProperty(Buffer.prototype, 'offset', {
+ get: function () {
+ if (!(this instanceof Buffer)) {
+ return undefined
+ }
+ return this.byteOffset
+ }
+})
+
function createBuffer (length) {
if (length > K_MAX_LENGTH) {
throw new RangeError('Invalid typed array length')
@@ -6643,7 +7094,7 @@
throw new TypeError('"value" argument must not be a number')
}
- if (isArrayBuffer(value)) {
+ if (isArrayBuffer(value) || (value && isArrayBuffer(value.buffer))) {
return fromArrayBuffer(value, encodingOrOffset, length)
}
@@ -6673,7 +7124,7 @@
function assertSize (size) {
if (typeof size !== 'number') {
- throw new TypeError('"size" argument must be a number')
+ throw new TypeError('"size" argument must be of type number')
} else if (size < 0) {
throw new RangeError('"size" argument must not be negative')
}
@@ -6727,7 +7178,7 @@
}
if (!Buffer.isEncoding(encoding)) {
- throw new TypeError('"encoding" must be a valid string encoding')
+ throw new TypeError('Unknown encoding: ' + encoding)
}
var length = byteLength(string, encoding) | 0
@@ -6756,11 +7207,11 @@
function fromArrayBuffer (array, byteOffset, length) {
if (byteOffset < 0 || array.byteLength < byteOffset) {
- throw new RangeError('\'offset\' is out of bounds')
+ throw new RangeError('"offset" is outside of buffer bounds')
}
if (array.byteLength < byteOffset + (length || 0)) {
- throw new RangeError('\'length\' is out of bounds')
+ throw new RangeError('"length" is outside of buffer bounds')
}
var buf
@@ -6791,7 +7242,7 @@
}
if (obj) {
- if (isArrayBufferView(obj) || 'length' in obj) {
+ if (ArrayBuffer.isView(obj) || 'length' in obj) {
if (typeof obj.length !== 'number' || numberIsNaN(obj.length)) {
return createBuffer(0)
}
@@ -6803,7 +7254,7 @@
}
}
- throw new TypeError('First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.')
+ throw new TypeError('The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object.')
}
function checked (length) {
@@ -6890,6 +7341,9 @@
var pos = 0
for (i = 0; i < list.length; ++i) {
var buf = list[i]
+ if (ArrayBuffer.isView(buf)) {
+ buf = Buffer.from(buf)
+ }
if (!Buffer.isBuffer(buf)) {
throw new TypeError('"list" argument must be an Array of Buffers')
}
@@ -6903,7 +7357,7 @@
if (Buffer.isBuffer(string)) {
return string.length
}
- if (isArrayBufferView(string) || isArrayBuffer(string)) {
+ if (ArrayBuffer.isView(string) || isArrayBuffer(string)) {
return string.byteLength
}
if (typeof string !== 'string') {
@@ -7071,6 +7525,8 @@
return slowToString.apply(this, arguments)
}
+Buffer.prototype.toLocaleString = Buffer.prototype.toString
+
Buffer.prototype.equals = function equals (b) {
if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')
if (this === b) return true
@@ -7291,9 +7747,7 @@
}
}
- // must be an even number of digits
var strLen = string.length
- if (strLen % 2 !== 0) throw new TypeError('Invalid hex string')
if (length > strLen / 2) {
length = strLen / 2
@@ -7986,6 +8440,7 @@
// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)
Buffer.prototype.copy = function copy (target, targetStart, start, end) {
+ if (!Buffer.isBuffer(target)) throw new TypeError('argument should be a Buffer')
if (!start) start = 0
if (!end && end !== 0) end = this.length
if (targetStart >= target.length) targetStart = target.length
@@ -8000,7 +8455,7 @@
if (targetStart < 0) {
throw new RangeError('targetStart out of bounds')
}
- if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds')
+ if (start < 0 || start >= this.length) throw new RangeError('Index out of range')
if (end < 0) throw new RangeError('sourceEnd out of bounds')
// Are we oob?
@@ -8010,22 +8465,19 @@
}
var len = end - start
- var i
- if (this === target && start < targetStart && targetStart < end) {
+ if (this === target && typeof Uint8Array.prototype.copyWithin === 'function') {
+ // Use built-in when available, missing from IE11
+ this.copyWithin(targetStart, start, end)
+ } else if (this === target && start < targetStart && targetStart < end) {
// descending copy from end
- for (i = len - 1; i >= 0; --i) {
- target[i + targetStart] = this[i + start]
- }
- } else if (len < 1000) {
- // ascending copy from start
- for (i = 0; i < len; ++i) {
+ for (var i = len - 1; i >= 0; --i) {
target[i + targetStart] = this[i + start]
}
} else {
Uint8Array.prototype.set.call(
target,
- this.subarray(start, start + len),
+ this.subarray(start, end),
targetStart
)
}
@@ -8048,18 +8500,20 @@
encoding = end
end = this.length
}
- if (val.length === 1) {
- var code = val.charCodeAt(0)
- if (code < 256) {
- val = code
- }
- }
if (encoding !== undefined && typeof encoding !== 'string') {
throw new TypeError('encoding must be a string')
}
if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) {
throw new TypeError('Unknown encoding: ' + encoding)
}
+ if (val.length === 1) {
+ var code = val.charCodeAt(0)
+ if ((encoding === 'utf8' && code < 128) ||
+ encoding === 'latin1') {
+ // Fast path: If `val` fits into a single byte, use that numeric value.
+ val = code
+ }
+ }
} else if (typeof val === 'number') {
val = val & 255
}
@@ -8088,6 +8542,10 @@
? val
: new Buffer(val, encoding)
var len = bytes.length
+ if (len === 0) {
+ throw new TypeError('The value "' + val +
+ '" is invalid for argument "value"')
+ }
for (i = 0; i < end - start; ++i) {
this[i + start] = bytes[i % len]
}
@@ -8102,6 +8560,8 @@
var INVALID_BASE64_RE = /[^+/0-9A-Za-z-_]/g
function base64clean (str) {
+ // Node takes equal signs as end of the Base64 encoding
+ str = str.split('=')[0]
// Node strips out invalid characters like \n and \t from the string, base64-js does not
str = str.trim().replace(INVALID_BASE64_RE, '')
// Node converts strings with length < 2 to ''
@@ -8243,11 +8703,6 @@
typeof obj.byteLength === 'number')
}
-// Node 0.10 supports `ArrayBuffer` but lacks `ArrayBuffer.isView`
-function isArrayBufferView (obj) {
- return (typeof ArrayBuffer.isView === 'function') && ArrayBuffer.isView(obj)
-}
-
function numberIsNaN (obj) {
return obj !== obj // eslint-disable-line no-self-compare
}
@@ -8792,7 +9247,7 @@
},{"ms":54}],45:[function(require,module,exports){
/*!
- diff v3.3.1
+ diff v3.5.0
Software License Agreement (BSD License)
@@ -9115,7 +9570,11 @@
return oldPos;
},
/*istanbul ignore start*/ /*istanbul ignore end*/equals: function equals(left, right) {
+ if (this.options.comparator) {
+ return this.options.comparator(left, right);
+ } else {
return left === right || this.options.ignoreCase && left.toLowerCase() === right.toLowerCase();
+ }
},
/*istanbul ignore start*/ /*istanbul ignore end*/removeEmpty: function removeEmpty(array) {
var ret = [];
@@ -9178,10 +9637,11 @@
}
}
- // Special case handle for when one terminal is ignored. For this case we merge the
- // terminal into the prior string and drop the change.
+ // Special case handle for when one terminal is ignored (i.e. whitespace).
+ // For this case we merge the terminal into the prior string and drop the change.
+ // This is only available for string mode.
var lastComponent = components[componentLen - 1];
- if (componentLen > 1 && (lastComponent.added || lastComponent.removed) && diff.equals('', lastComponent.value)) {
+ if (componentLen > 1 && typeof lastComponent.value === 'string' && (lastComponent.added || lastComponent.removed) && diff.equals('', lastComponent.value)) {
components[componentLen - 2].value += lastComponent.value;
components.pop();
}
@@ -9459,16 +9919,16 @@
jsonDiff.tokenize = /*istanbul ignore start*/_line.lineDiff /*istanbul ignore end*/.tokenize;
jsonDiff.castInput = function (value) {
- /*istanbul ignore start*/var /*istanbul ignore end*/undefinedReplacement = this.options.undefinedReplacement;
-
+ /*istanbul ignore start*/var _options = /*istanbul ignore end*/this.options,
+ undefinedReplacement = _options.undefinedReplacement,
+ _options$stringifyRep = _options.stringifyReplacer,
+ stringifyReplacer = _options$stringifyRep === undefined ? function (k, v) /*istanbul ignore start*/{
+ return (/*istanbul ignore end*/typeof v === 'undefined' ? undefinedReplacement : v
+ );
+ } : _options$stringifyRep;
- return typeof value === 'string' ? value : JSON.stringify(canonicalize(value), function (k, v) {
- if (typeof v === 'undefined') {
- return undefinedReplacement;
- }
- return v;
- }, ' ');
+ return typeof value === 'string' ? value : JSON.stringify(canonicalize(value, null, null, stringifyReplacer), stringifyReplacer, ' ');
};
jsonDiff.equals = function (left, right) {
return (/*istanbul ignore start*/_base2['default'] /*istanbul ignore end*/.prototype.equals.call(jsonDiff, left.replace(/,([\r\n])/g, '$1'), right.replace(/,([\r\n])/g, '$1'))
@@ -9480,11 +9940,15 @@
}
// This function handles the presence of circular references by bailing out when encountering an
- // object that is already on the "stack" of items being processed.
- function canonicalize(obj, stack, replacementStack) {
+ // object that is already on the "stack" of items being processed. Accepts an optional replacer
+ function canonicalize(obj, stack, replacementStack, replacer, key) {
stack = stack || [];
replacementStack = replacementStack || [];
+ if (replacer) {
+ obj = replacer(key, obj);
+ }
+
var i = /*istanbul ignore start*/void 0 /*istanbul ignore end*/;
for (i = 0; i < stack.length; i += 1) {
@@ -9500,7 +9964,7 @@
canonicalizedObj = new Array(obj.length);
replacementStack.push(canonicalizedObj);
for (i = 0; i < obj.length; i += 1) {
- canonicalizedObj[i] = canonicalize(obj[i], stack, replacementStack);
+ canonicalizedObj[i] = canonicalize(obj[i], stack, replacementStack, replacer, key);
}
stack.pop();
replacementStack.pop();
@@ -9516,17 +9980,17 @@
canonicalizedObj = {};
replacementStack.push(canonicalizedObj);
var sortedKeys = [],
- key = /*istanbul ignore start*/void 0 /*istanbul ignore end*/;
- for (key in obj) {
+ _key = /*istanbul ignore start*/void 0 /*istanbul ignore end*/;
+ for (_key in obj) {
/* istanbul ignore else */
- if (obj.hasOwnProperty(key)) {
- sortedKeys.push(key);
+ if (obj.hasOwnProperty(_key)) {
+ sortedKeys.push(_key);
}
}
sortedKeys.sort();
for (i = 0; i < sortedKeys.length; i += 1) {
- key = sortedKeys[i];
- canonicalizedObj[key] = canonicalize(obj[key], stack, replacementStack);
+ _key = sortedKeys[i];
+ canonicalizedObj[_key] = canonicalize(obj[_key], stack, replacementStack, replacer, _key);
}
stack.pop();
replacementStack.pop();
@@ -9555,9 +10019,12 @@
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
/*istanbul ignore end*/var arrayDiff = /*istanbul ignore start*/exports. /*istanbul ignore end*/arrayDiff = new /*istanbul ignore start*/_base2['default'] /*istanbul ignore end*/();
- arrayDiff.tokenize = arrayDiff.join = function (value) {
+ arrayDiff.tokenize = function (value) {
return value.slice();
};
+ arrayDiff.join = arrayDiff.removeEmpty = function (value) {
+ return value;
+ };
function diffArrays(oldArr, newArr, callback) {
return arrayDiff.diff(oldArr, newArr, callback);
@@ -9619,8 +10086,8 @@
function hunkFits(hunk, toPos) {
for (var j = 0; j < hunk.lines.length; j++) {
var line = hunk.lines[j],
- operation = line[0],
- content = line.substr(1);
+ operation = line.length > 0 ? line[0] : ' ',
+ content = line.length > 0 ? line.substr(1) : line;
if (operation === ' ' || operation === '-') {
// Context sanity check
@@ -9677,8 +10144,8 @@
for (var j = 0; j < _hunk.lines.length; j++) {
var line = _hunk.lines[j],
- operation = line[0],
- content = line.substr(1),
+ operation = line.length > 0 ? line[0] : ' ',
+ content = line.length > 0 ? line.substr(1) : line,
delimiter = _hunk.linedelimiters[j];
if (operation === ' ') {
@@ -9816,16 +10283,16 @@
// Parses the --- and +++ headers, if none are found, no lines
// are consumed.
function parseFileHeader(index) {
- var headerPattern = /^(---|\+\+\+)\s+([\S ]*)(?:\t(.*?)\s*)?$/;
- var fileHeader = headerPattern.exec(diffstr[i]);
+ var fileHeader = /^(---|\+\+\+)\s+(.*)$/.exec(diffstr[i]);
if (fileHeader) {
var keyPrefix = fileHeader[1] === '---' ? 'old' : 'new';
- var fileName = fileHeader[2].replace(/\\\\/g, '\\');
+ var data = fileHeader[2].split('\t', 2);
+ var fileName = data[0].replace(/\\\\/g, '\\');
if (/^".*"$/.test(fileName)) {
fileName = fileName.substr(1, fileName.length - 2);
}
index[keyPrefix + 'FileName'] = fileName;
- index[keyPrefix + 'Header'] = fileHeader[3];
+ index[keyPrefix + 'Header'] = (data[1] || '').trim();
i++;
}
@@ -9855,7 +10322,7 @@
if (diffstr[i].indexOf('--- ') === 0 && i + 2 < diffstr.length && diffstr[i + 1].indexOf('+++ ') === 0 && diffstr[i + 2].indexOf('@@') === 0) {
break;
}
- var operation = diffstr[i][0];
+ var operation = diffstr[i].length == 0 && i != diffstr.length - 1 ? ' ' : diffstr[i][0];
if (operation === '+' || operation === '-' || operation === ' ' || operation === '\\') {
hunk.lines.push(diffstr[i]);
@@ -9976,27 +10443,19 @@
/*istanbul ignore start*/function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
/*istanbul ignore end*/function calcLineCount(hunk) {
- var conflicted = false;
-
- hunk.oldLines = 0;
- hunk.newLines = 0;
-
- hunk.lines.forEach(function (line) {
- if (typeof line !== 'string') {
- conflicted = true;
- return;
- }
+ /*istanbul ignore start*/var _calcOldNewLineCount = /*istanbul ignore end*/calcOldNewLineCount(hunk.lines),
+ oldLines = _calcOldNewLineCount.oldLines,
+ newLines = _calcOldNewLineCount.newLines;
- if (line[0] === '+' || line[0] === ' ') {
- hunk.newLines++;
- }
- if (line[0] === '-' || line[0] === ' ') {
- hunk.oldLines++;
+ if (oldLines !== undefined) {
+ hunk.oldLines = oldLines;
+ } else {
+ delete hunk.oldLines;
}
- });
- if (conflicted) {
- delete hunk.oldLines;
+ if (newLines !== undefined) {
+ hunk.newLines = newLines;
+ } else {
delete hunk.newLines;
}
}
@@ -10328,6 +10787,43 @@
return true;
}
+ function calcOldNewLineCount(lines) {
+ var oldLines = 0;
+ var newLines = 0;
+
+ lines.forEach(function (line) {
+ if (typeof line !== 'string') {
+ var myCount = calcOldNewLineCount(line.mine);
+ var theirCount = calcOldNewLineCount(line.theirs);
+
+ if (oldLines !== undefined) {
+ if (myCount.oldLines === theirCount.oldLines) {
+ oldLines += myCount.oldLines;
+ } else {
+ oldLines = undefined;
+ }
+ }
+
+ if (newLines !== undefined) {
+ if (myCount.newLines === theirCount.newLines) {
+ newLines += myCount.newLines;
+ } else {
+ newLines = undefined;
+ }
+ }
+ } else {
+ if (newLines !== undefined && (line[0] === '+' || line[0] === ' ')) {
+ newLines++;
+ }
+ if (oldLines !== undefined && (line[0] === '-' || line[0] === ' ')) {
+ oldLines++;
+ }
+ }
+ });
+
+ return { oldLines: oldLines, newLines: newLines };
+ }
+
/***/ }),
@@ -10627,8 +11123,16 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
+var objectCreate = Object.create || objectCreatePolyfill
+var objectKeys = Object.keys || objectKeysPolyfill
+var bind = Function.prototype.bind || functionBindPolyfill
+
function EventEmitter() {
- this._events = this._events || {};
+ if (!this._events || !Object.prototype.hasOwnProperty.call(this, '_events')) {
+ this._events = objectCreate(null);
+ this._eventsCount = 0;
+ }
+
this._maxListeners = this._maxListeners || undefined;
}
module.exports = EventEmitter;
@@ -10641,169 +11145,319 @@
// By default EventEmitters will print a warning if more than 10 listeners are
// added to it. This is a useful default which helps finding memory leaks.
-EventEmitter.defaultMaxListeners = 10;
+var defaultMaxListeners = 10;
+
+var hasDefineProperty;
+try {
+ var o = {};
+ if (Object.defineProperty) Object.defineProperty(o, 'x', { value: 0 });
+ hasDefineProperty = o.x === 0;
+} catch (err) { hasDefineProperty = false }
+if (hasDefineProperty) {
+ Object.defineProperty(EventEmitter, 'defaultMaxListeners', {
+ enumerable: true,
+ get: function() {
+ return defaultMaxListeners;
+ },
+ set: function(arg) {
+ // check whether the input is a positive number (whose value is zero or
+ // greater and not a NaN).
+ if (typeof arg !== 'number' || arg < 0 || arg !== arg)
+ throw new TypeError('"defaultMaxListeners" must be a positive number');
+ defaultMaxListeners = arg;
+ }
+ });
+} else {
+ EventEmitter.defaultMaxListeners = defaultMaxListeners;
+}
// Obviously not all Emitters should be limited to 10. This function allows
// that to be increased. Set to zero for unlimited.
-EventEmitter.prototype.setMaxListeners = function(n) {
- if (!isNumber(n) || n < 0 || isNaN(n))
- throw TypeError('n must be a positive number');
+EventEmitter.prototype.setMaxListeners = function setMaxListeners(n) {
+ if (typeof n !== 'number' || n < 0 || isNaN(n))
+ throw new TypeError('"n" argument must be a positive number');
this._maxListeners = n;
return this;
};
-EventEmitter.prototype.emit = function(type) {
- var er, handler, len, args, i, listeners;
-
- if (!this._events)
- this._events = {};
+function $getMaxListeners(that) {
+ if (that._maxListeners === undefined)
+ return EventEmitter.defaultMaxListeners;
+ return that._maxListeners;
+}
+
+EventEmitter.prototype.getMaxListeners = function getMaxListeners() {
+ return $getMaxListeners(this);
+};
+
+// These standalone emit* functions are used to optimize calling of event
+// handlers for fast cases because emit() itself often has a variable number of
+// arguments and can be deoptimized because of that. These functions always have
+// the same number of arguments and thus do not get deoptimized, so the code
+// inside them can execute faster.
+function emitNone(handler, isFn, self) {
+ if (isFn)
+ handler.call(self);
+ else {
+ var len = handler.length;
+ var listeners = arrayClone(handler, len);
+ for (var i = 0; i < len; ++i)
+ listeners[i].call(self);
+ }
+}
+function emitOne(handler, isFn, self, arg1) {
+ if (isFn)
+ handler.call(self, arg1);
+ else {
+ var len = handler.length;
+ var listeners = arrayClone(handler, len);
+ for (var i = 0; i < len; ++i)
+ listeners[i].call(self, arg1);
+ }
+}
+function emitTwo(handler, isFn, self, arg1, arg2) {
+ if (isFn)
+ handler.call(self, arg1, arg2);
+ else {
+ var len = handler.length;
+ var listeners = arrayClone(handler, len);
+ for (var i = 0; i < len; ++i)
+ listeners[i].call(self, arg1, arg2);
+ }
+}
+function emitThree(handler, isFn, self, arg1, arg2, arg3) {
+ if (isFn)
+ handler.call(self, arg1, arg2, arg3);
+ else {
+ var len = handler.length;
+ var listeners = arrayClone(handler, len);
+ for (var i = 0; i < len; ++i)
+ listeners[i].call(self, arg1, arg2, arg3);
+ }
+}
+
+function emitMany(handler, isFn, self, args) {
+ if (isFn)
+ handler.apply(self, args);
+ else {
+ var len = handler.length;
+ var listeners = arrayClone(handler, len);
+ for (var i = 0; i < len; ++i)
+ listeners[i].apply(self, args);
+ }
+}
+
+EventEmitter.prototype.emit = function emit(type) {
+ var er, handler, len, args, i, events;
+ var doError = (type === 'error');
+
+ events = this._events;
+ if (events)
+ doError = (doError && events.error == null);
+ else if (!doError)
+ return false;
// If there is no 'error' event listener then throw.
- if (type === 'error') {
- if (!this._events.error ||
- (isObject(this._events.error) && !this._events.error.length)) {
+ if (doError) {
+ if (arguments.length > 1)
er = arguments[1];
if (er instanceof Error) {
throw er; // Unhandled 'error' event
} else {
// At least give some kind of context to the user
- var err = new Error('Uncaught, unspecified "error" event. (' + er + ')');
+ var err = new Error('Unhandled "error" event. (' + er + ')');
err.context = er;
throw err;
}
- }
+ return false;
}
- handler = this._events[type];
+ handler = events[type];
- if (isUndefined(handler))
+ if (!handler)
return false;
- if (isFunction(handler)) {
- switch (arguments.length) {
+ var isFn = typeof handler === 'function';
+ len = arguments.length;
+ switch (len) {
// fast cases
case 1:
- handler.call(this);
+ emitNone(handler, isFn, this);
break;
case 2:
- handler.call(this, arguments[1]);
+ emitOne(handler, isFn, this, arguments[1]);
break;
case 3:
- handler.call(this, arguments[1], arguments[2]);
+ emitTwo(handler, isFn, this, arguments[1], arguments[2]);
+ break;
+ case 4:
+ emitThree(handler, isFn, this, arguments[1], arguments[2], arguments[3]);
break;
// slower
default:
- args = Array.prototype.slice.call(arguments, 1);
- handler.apply(this, args);
- }
- } else if (isObject(handler)) {
- args = Array.prototype.slice.call(arguments, 1);
- listeners = handler.slice();
- len = listeners.length;
- for (i = 0; i < len; i++)
- listeners[i].apply(this, args);
+ args = new Array(len - 1);
+ for (i = 1; i < len; i++)
+ args[i - 1] = arguments[i];
+ emitMany(handler, isFn, this, args);
}
return true;
};
-EventEmitter.prototype.addListener = function(type, listener) {
+function _addListener(target, type, listener, prepend) {
var m;
+ var events;
+ var existing;
- if (!isFunction(listener))
- throw TypeError('listener must be a function');
-
- if (!this._events)
- this._events = {};
+ if (typeof listener !== 'function')
+ throw new TypeError('"listener" argument must be a function');
+ events = target._events;
+ if (!events) {
+ events = target._events = objectCreate(null);
+ target._eventsCount = 0;
+ } else {
// To avoid recursion in the case that type === "newListener"! Before
// adding it to the listeners, first emit "newListener".
- if (this._events.newListener)
- this.emit('newListener', type,
- isFunction(listener.listener) ?
- listener.listener : listener);
+ if (events.newListener) {
+ target.emit('newListener', type,
+ listener.listener ? listener.listener : listener);
- if (!this._events[type])
+ // Re-assign `events` because a newListener handler could have caused the
+ // this._events to be assigned to a new object
+ events = target._events;
+ }
+ existing = events[type];
+ }
+
+ if (!existing) {
// Optimize the case of one listener. Don't need the extra array object.
- this._events[type] = listener;
- else if (isObject(this._events[type]))
- // If we've already got an array, just append.
- this._events[type].push(listener);
- else
+ existing = events[type] = listener;
+ ++target._eventsCount;
+ } else {
+ if (typeof existing === 'function') {
// Adding the second element, need to change to array.
- this._events[type] = [this._events[type], listener];
+ existing = events[type] =
+ prepend ? [listener, existing] : [existing, listener];
+ } else {
+ // If we've already got an array, just append.
+ if (prepend) {
+ existing.unshift(listener);
+ } else {
+ existing.push(listener);
+ }
+ }
// Check for listener leak
- if (isObject(this._events[type]) && !this._events[type].warned) {
- if (!isUndefined(this._maxListeners)) {
- m = this._maxListeners;
- } else {
- m = EventEmitter.defaultMaxListeners;
- }
-
- if (m && m > 0 && this._events[type].length > m) {
- this._events[type].warned = true;
- console.error('(node) warning: possible EventEmitter memory ' +
- 'leak detected. %d listeners added. ' +
- 'Use emitter.setMaxListeners() to increase limit.',
- this._events[type].length);
- if (typeof console.trace === 'function') {
- // not supported in IE 10
- console.trace();
+ if (!existing.warned) {
+ m = $getMaxListeners(target);
+ if (m && m > 0 && existing.length > m) {
+ existing.warned = true;
+ var w = new Error('Possible EventEmitter memory leak detected. ' +
+ existing.length + ' "' + String(type) + '" listeners ' +
+ 'added. Use emitter.setMaxListeners() to ' +
+ 'increase limit.');
+ w.name = 'MaxListenersExceededWarning';
+ w.emitter = target;
+ w.type = type;
+ w.count = existing.length;
+ if (typeof console === 'object' && console.warn) {
+ console.warn('%s: %s', w.name, w.message);
+ }
}
}
}
- return this;
+ return target;
+}
+
+EventEmitter.prototype.addListener = function addListener(type, listener) {
+ return _addListener(this, type, listener, false);
};
EventEmitter.prototype.on = EventEmitter.prototype.addListener;
-EventEmitter.prototype.once = function(type, listener) {
- if (!isFunction(listener))
- throw TypeError('listener must be a function');
-
- var fired = false;
-
- function g() {
- this.removeListener(type, g);
+EventEmitter.prototype.prependListener =
+ function prependListener(type, listener) {
+ return _addListener(this, type, listener, true);
+ };
- if (!fired) {
- fired = true;
- listener.apply(this, arguments);
+function onceWrapper() {
+ if (!this.fired) {
+ this.target.removeListener(this.type, this.wrapFn);
+ this.fired = true;
+ switch (arguments.length) {
+ case 0:
+ return this.listener.call(this.target);
+ case 1:
+ return this.listener.call(this.target, arguments[0]);
+ case 2:
+ return this.listener.call(this.target, arguments[0], arguments[1]);
+ case 3:
+ return this.listener.call(this.target, arguments[0], arguments[1],
+ arguments[2]);
+ default:
+ var args = new Array(arguments.length);
+ for (var i = 0; i < args.length; ++i)
+ args[i] = arguments[i];
+ this.listener.apply(this.target, args);
}
}
+}
- g.listener = listener;
- this.on(type, g);
+function _onceWrap(target, type, listener) {
+ var state = { fired: false, wrapFn: undefined, target: target, type: type, listener: listener };
+ var wrapped = bind.call(onceWrapper, state);
+ wrapped.listener = listener;
+ state.wrapFn = wrapped;
+ return wrapped;
+}
+EventEmitter.prototype.once = function once(type, listener) {
+ if (typeof listener !== 'function')
+ throw new TypeError('"listener" argument must be a function');
+ this.on(type, _onceWrap(this, type, listener));
return this;
};
-// emits a 'removeListener' event iff the listener was removed
-EventEmitter.prototype.removeListener = function(type, listener) {
- var list, position, length, i;
+EventEmitter.prototype.prependOnceListener =
+ function prependOnceListener(type, listener) {
+ if (typeof listener !== 'function')
+ throw new TypeError('"listener" argument must be a function');
+ this.prependListener(type, _onceWrap(this, type, listener));
+ return this;
+ };
+
+// Emits a 'removeListener' event if and only if the listener was removed.
+EventEmitter.prototype.removeListener =
+ function removeListener(type, listener) {
+ var list, events, position, i, originalListener;
- if (!isFunction(listener))
- throw TypeError('listener must be a function');
+ if (typeof listener !== 'function')
+ throw new TypeError('"listener" argument must be a function');
- if (!this._events || !this._events[type])
+ events = this._events;
+ if (!events)
return this;
- list = this._events[type];
- length = list.length;
+ list = events[type];
+ if (!list)
+ return this;
+
+ if (list === listener || list.listener === listener) {
+ if (--this._eventsCount === 0)
+ this._events = objectCreate(null);
+ else {
+ delete events[type];
+ if (events.removeListener)
+ this.emit('removeListener', type, list.listener || listener);
+ }
+ } else if (typeof list !== 'function') {
position = -1;
- if (list === listener ||
- (isFunction(list.listener) && list.listener === listener)) {
- delete this._events[type];
- if (this._events.removeListener)
- this.emit('removeListener', type, listener);
-
- } else if (isObject(list)) {
- for (i = length; i-- > 0;) {
- if (list[i] === listener ||
- (list[i].listener && list[i].listener === listener)) {
+ for (i = list.length - 1; i >= 0; i--) {
+ if (list[i] === listener || list[i].listener === listener) {
+ originalListener = list[i].listener;
position = i;
break;
}
@@ -10812,101 +11466,160 @@
if (position < 0)
return this;
- if (list.length === 1) {
- list.length = 0;
- delete this._events[type];
- } else {
- list.splice(position, 1);
- }
+ if (position === 0)
+ list.shift();
+ else
+ spliceOne(list, position);
- if (this._events.removeListener)
- this.emit('removeListener', type, listener);
+ if (list.length === 1)
+ events[type] = list[0];
+
+ if (events.removeListener)
+ this.emit('removeListener', type, originalListener || listener);
}
return this;
-};
+ };
-EventEmitter.prototype.removeAllListeners = function(type) {
- var key, listeners;
+EventEmitter.prototype.removeAllListeners =
+ function removeAllListeners(type) {
+ var listeners, events, i;
- if (!this._events)
+ events = this._events;
+ if (!events)
return this;
// not listening for removeListener, no need to emit
- if (!this._events.removeListener) {
- if (arguments.length === 0)
- this._events = {};
- else if (this._events[type])
- delete this._events[type];
+ if (!events.removeListener) {
+ if (arguments.length === 0) {
+ this._events = objectCreate(null);
+ this._eventsCount = 0;
+ } else if (events[type]) {
+ if (--this._eventsCount === 0)
+ this._events = objectCreate(null);
+ else
+ delete events[type];
+ }
return this;
}
// emit removeListener for all listeners on all events
if (arguments.length === 0) {
- for (key in this._events) {
+ var keys = objectKeys(events);
+ var key;
+ for (i = 0; i < keys.length; ++i) {
+ key = keys[i];
if (key === 'removeListener') continue;
this.removeAllListeners(key);
}
this.removeAllListeners('removeListener');
- this._events = {};
+ this._events = objectCreate(null);
+ this._eventsCount = 0;
return this;
}
- listeners = this._events[type];
+ listeners = events[type];
- if (isFunction(listeners)) {
+ if (typeof listeners === 'function') {
this.removeListener(type, listeners);
} else if (listeners) {
// LIFO order
- while (listeners.length)
- this.removeListener(type, listeners[listeners.length - 1]);
+ for (i = listeners.length - 1; i >= 0; i--) {
+ this.removeListener(type, listeners[i]);
+ }
}
- delete this._events[type];
return this;
-};
+ };
-EventEmitter.prototype.listeners = function(type) {
+EventEmitter.prototype.listeners = function listeners(type) {
+ var evlistener;
var ret;
- if (!this._events || !this._events[type])
+ var events = this._events;
+
+ if (!events)
ret = [];
- else if (isFunction(this._events[type]))
- ret = [this._events[type]];
+ else {
+ evlistener = events[type];
+ if (!evlistener)
+ ret = [];
+ else if (typeof evlistener === 'function')
+ ret = [evlistener.listener || evlistener];
else
- ret = this._events[type].slice();
+ ret = unwrapListeners(evlistener);
+ }
+
return ret;
};
-EventEmitter.prototype.listenerCount = function(type) {
- if (this._events) {
- var evlistener = this._events[type];
+EventEmitter.listenerCount = function(emitter, type) {
+ if (typeof emitter.listenerCount === 'function') {
+ return emitter.listenerCount(type);
+ } else {
+ return listenerCount.call(emitter, type);
+ }
+};
+
+EventEmitter.prototype.listenerCount = listenerCount;
+function listenerCount(type) {
+ var events = this._events;
+
+ if (events) {
+ var evlistener = events[type];
- if (isFunction(evlistener))
+ if (typeof evlistener === 'function') {
return 1;
- else if (evlistener)
+ } else if (evlistener) {
return evlistener.length;
}
+ }
+
return 0;
-};
+}
-EventEmitter.listenerCount = function(emitter, type) {
- return emitter.listenerCount(type);
+EventEmitter.prototype.eventNames = function eventNames() {
+ return this._eventsCount > 0 ? Reflect.ownKeys(this._events) : [];
};
-function isFunction(arg) {
- return typeof arg === 'function';
+// About 1.5x faster than the two-arg version of Array#splice().
+function spliceOne(list, index) {
+ for (var i = index, k = i + 1, n = list.length; k < n; i += 1, k += 1)
+ list[i] = list[k];
+ list.pop();
}
-function isNumber(arg) {
- return typeof arg === 'number';
+function arrayClone(arr, n) {
+ var copy = new Array(n);
+ for (var i = 0; i < n; ++i)
+ copy[i] = arr[i];
+ return copy;
}
-function isObject(arg) {
- return typeof arg === 'object' && arg !== null;
+function unwrapListeners(arr) {
+ var ret = new Array(arr.length);
+ for (var i = 0; i < ret.length; ++i) {
+ ret[i] = arr[i].listener || arr[i];
+ }
+ return ret;
}
-function isUndefined(arg) {
- return arg === void 0;
+function objectCreatePolyfill(proto) {
+ var F = function() {};
+ F.prototype = proto;
+ return new F;
+}
+function objectKeysPolyfill(obj) {
+ var keys = [];
+ for (var k in obj) if (Object.prototype.hasOwnProperty.call(obj, k)) {
+ keys.push(k);
+ }
+ return k;
+}
+function functionBindPolyfill(context) {
+ var fn = this;
+ return function () {
+ return fn.apply(context, arguments);
+ };
}
},{}],48:[function(require,module,exports){
@@ -11256,7 +11969,7 @@
},{}],49:[function(require,module,exports){
exports.read = function (buffer, offset, isLE, mLen, nBytes) {
var e, m
- var eLen = nBytes * 8 - mLen - 1
+ var eLen = (nBytes * 8) - mLen - 1
var eMax = (1 << eLen) - 1
var eBias = eMax >> 1
var nBits = -7
@@ -11269,12 +11982,12 @@
e = s & ((1 << (-nBits)) - 1)
s >>= (-nBits)
nBits += eLen
- for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {}
+ for (; nBits > 0; e = (e * 256) + buffer[offset + i], i += d, nBits -= 8) {}
m = e & ((1 << (-nBits)) - 1)
e >>= (-nBits)
nBits += mLen
- for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {}
+ for (; nBits > 0; m = (m * 256) + buffer[offset + i], i += d, nBits -= 8) {}
if (e === 0) {
e = 1 - eBias
@@ -11289,7 +12002,7 @@
exports.write = function (buffer, value, offset, isLE, mLen, nBytes) {
var e, m, c
- var eLen = nBytes * 8 - mLen - 1
+ var eLen = (nBytes * 8) - mLen - 1
var eMax = (1 << eLen) - 1
var eBias = eMax >> 1
var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0)
@@ -11322,7 +12035,7 @@
m = 0
e = eMax
} else if (e + eBias >= 1) {
- m = (value * c - 1) * Math.pow(2, mLen)
+ m = ((value * c) - 1) * Math.pow(2, mLen)
e = e + eBias
} else {
m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen)
@@ -11368,7 +12081,7 @@
/*!
* Determine if an object is a Buffer
*
- * @author Feross Aboukhadijeh <feross@feross.org> <http://feross.org>
+ * @author Feross Aboukhadijeh <https://feross.org>
* @license MIT
*/
@@ -11657,9 +12370,9 @@
if (!process.version ||
process.version.indexOf('v0.') === 0 ||
process.version.indexOf('v1.') === 0 && process.version.indexOf('v1.8.') !== 0) {
- module.exports = nextTick;
+ module.exports = { nextTick: nextTick };
} else {
- module.exports = process.nextTick;
+ module.exports = process
}
function nextTick(fn, arg1, arg2, arg3) {
@@ -11917,7 +12631,7 @@
/*<replacement>*/
-var processNextTick = require('process-nextick-args');
+var pna = require('process-nextick-args');
/*</replacement>*/
/*<replacement>*/
@@ -11941,10 +12655,13 @@
util.inherits(Duplex, Readable);
-var keys = objectKeys(Writable.prototype);
-for (var v = 0; v < keys.length; v++) {
+{
+ // avoid scope creep, the keys array can then be collected
+ var keys = objectKeys(Writable.prototype);
+ for (var v = 0; v < keys.length; v++) {
var method = keys[v];
if (!Duplex.prototype[method]) Duplex.prototype[method] = Writable.prototype[method];
+ }
}
function Duplex(options) {
@@ -11963,6 +12680,16 @@
this.once('end', onend);
}
+Object.defineProperty(Duplex.prototype, 'writableHighWaterMark', {
+ // making it explicit this property is not enumerable
+ // because otherwise some prototype manipulation in
+ // userland will fail
+ enumerable: false,
+ get: function () {
+ return this._writableState.highWaterMark;
+ }
+});
+
// the no-half-open enforcer
function onend() {
// if we allow half-open state, or if the writable side ended,
@@ -11971,7 +12698,7 @@
// no more data can be written.
// But allow more writes to happen in this tick.
- processNextTick(onEndNT, this);
+ pna.nextTick(onEndNT, this);
}
function onEndNT(self) {
@@ -12003,14 +12730,8 @@
this.push(null);
this.end();
- processNextTick(cb, err);
+ pna.nextTick(cb, err);
};
-
-function forEach(xs, f) {
- for (var i = 0, l = xs.length; i < l; i++) {
- f(xs[i], i);
- }
-}
},{"./_stream_readable":60,"./_stream_writable":62,"core-util-is":42,"inherits":50,"process-nextick-args":55}],59:[function(require,module,exports){
// Copyright Joyent, Inc. and other Node contributors.
//
@@ -12086,7 +12807,7 @@
/*<replacement>*/
-var processNextTick = require('process-nextick-args');
+var pna = require('process-nextick-args');
/*</replacement>*/
module.exports = Readable;
@@ -12113,9 +12834,8 @@
var Stream = require('./internal/streams/stream');
/*</replacement>*/
-// TODO(bmeurer): Change this back to const once hole checks are
-// properly optimized away early in Ignition+TurboFan.
/*<replacement>*/
+
var Buffer = require('safe-buffer').Buffer;
var OurUint8Array = global.Uint8Array || function () {};
function _uint8ArrayToBuffer(chunk) {
@@ -12152,15 +12873,13 @@
function prependListener(emitter, event, fn) {
// Sadly this is not cacheable as some libraries bundle their own
// event emitter implementation with them.
- if (typeof emitter.prependListener === 'function') {
- return emitter.prependListener(event, fn);
- } else {
+ if (typeof emitter.prependListener === 'function') return emitter.prependListener(event, fn);
+
// This is a hack to make sure that our error handler is attached before any
// userland ones. NEVER DO THIS. This is here only because this code needs
// to continue to work with older versions of Node.js that do not include
// the prependListener() method. The goal is to eventually remove this hack.
if (!emitter._events || !emitter._events[event]) emitter.on(event, fn);else if (isArray(emitter._events[event])) emitter._events[event].unshift(fn);else emitter._events[event] = [fn, emitter._events[event]];
- }
}
function ReadableState(options, stream) {
@@ -12168,17 +12887,26 @@
options = options || {};
+ // Duplex streams are both readable and writable, but share
+ // the same options object.
+ // However, some cases require setting options to different
+ // values for the readable and the writable sides of the duplex stream.
+ // These options can be provided separately as readableXXX and writableXXX.
+ var isDuplex = stream instanceof Duplex;
+
// object stream flag. Used to make read(n) ignore n and to
// make all the buffer merging and length checks go away
this.objectMode = !!options.objectMode;
- if (stream instanceof Duplex) this.objectMode = this.objectMode || !!options.readableObjectMode;
+ if (isDuplex) this.objectMode = this.objectMode || !!options.readableObjectMode;
// the point at which it stops calling _read() to fill the buffer
// Note: 0 is a valid value, means "don't call _read preemptively ever"
var hwm = options.highWaterMark;
+ var readableHwm = options.readableHighWaterMark;
var defaultHwm = this.objectMode ? 16 : 16 * 1024;
- this.highWaterMark = hwm || hwm === 0 ? hwm : defaultHwm;
+
+ if (hwm || hwm === 0) this.highWaterMark = hwm;else if (isDuplex && (readableHwm || readableHwm === 0)) this.highWaterMark = readableHwm;else this.highWaterMark = defaultHwm;
// cast to ints.
this.highWaterMark = Math.floor(this.highWaterMark);
@@ -12551,7 +13279,7 @@
if (!state.emittedReadable) {
debug('emitReadable', state.flowing);
state.emittedReadable = true;
- if (state.sync) processNextTick(emitReadable_, stream);else emitReadable_(stream);
+ if (state.sync) pna.nextTick(emitReadable_, stream);else emitReadable_(stream);
}
}
@@ -12570,7 +13298,7 @@
function maybeReadMore(stream, state) {
if (!state.readingMore) {
state.readingMore = true;
- processNextTick(maybeReadMore_, stream, state);
+ pna.nextTick(maybeReadMore_, stream, state);
}
}
@@ -12615,7 +13343,7 @@
var doEnd = (!pipeOpts || pipeOpts.end !== false) && dest !== process.stdout && dest !== process.stderr;
var endFn = doEnd ? onend : unpipe;
- if (state.endEmitted) processNextTick(endFn);else src.once('end', endFn);
+ if (state.endEmitted) pna.nextTick(endFn);else src.once('end', endFn);
dest.on('unpipe', onunpipe);
function onunpipe(readable, unpipeInfo) {
@@ -12805,7 +13533,7 @@
state.readableListening = state.needReadable = true;
state.emittedReadable = false;
if (!state.reading) {
- processNextTick(nReadingNextTick, this);
+ pna.nextTick(nReadingNextTick, this);
} else if (state.length) {
emitReadable(this);
}
@@ -12836,7 +13564,7 @@
function resume(stream, state) {
if (!state.resumeScheduled) {
state.resumeScheduled = true;
- processNextTick(resume_, stream, state);
+ pna.nextTick(resume_, stream, state);
}
}
@@ -12873,18 +13601,19 @@
// This is *not* part of the readable stream interface.
// It is an ugly unfortunate mess of history.
Readable.prototype.wrap = function (stream) {
+ var _this = this;
+
var state = this._readableState;
var paused = false;
- var self = this;
stream.on('end', function () {
debug('wrapped end');
if (state.decoder && !state.ended) {
var chunk = state.decoder.end();
- if (chunk && chunk.length) self.push(chunk);
+ if (chunk && chunk.length) _this.push(chunk);
}
- self.push(null);
+ _this.push(null);
});
stream.on('data', function (chunk) {
@@ -12894,7 +13623,7 @@
// don't skip over falsy values in objectMode
if (state.objectMode && (chunk === null || chunk === undefined)) return;else if (!state.objectMode && (!chunk || !chunk.length)) return;
- var ret = self.push(chunk);
+ var ret = _this.push(chunk);
if (!ret) {
paused = true;
stream.pause();
@@ -12915,12 +13644,12 @@
// proxy certain important events.
for (var n = 0; n < kProxyEvents.length; n++) {
- stream.on(kProxyEvents[n], self.emit.bind(self, kProxyEvents[n]));
+ stream.on(kProxyEvents[n], this.emit.bind(this, kProxyEvents[n]));
}
// when we try to consume some more bytes, simply unpause the
// underlying stream.
- self._read = function (n) {
+ this._read = function (n) {
debug('wrapped _read', n);
if (paused) {
paused = false;
@@ -12928,9 +13657,19 @@
}
};
- return self;
+ return this;
};
+Object.defineProperty(Readable.prototype, 'readableHighWaterMark', {
+ // making it explicit this property is not enumerable
+ // because otherwise some prototype manipulation in
+ // userland will fail
+ enumerable: false,
+ get: function () {
+ return this._readableState.highWaterMark;
+ }
+});
+
// exposed for testing purposes only.
Readable._fromList = fromList;
@@ -13043,7 +13782,7 @@
if (!state.endEmitted) {
state.ended = true;
- processNextTick(endReadableNT, state, stream);
+ pna.nextTick(endReadableNT, state, stream);
}
}
@@ -13056,12 +13795,6 @@
}
}
-function forEach(xs, f) {
- for (var i = 0, l = xs.length; i < l; i++) {
- f(xs[i], i);
- }
-}
-
function indexOf(xs, x) {
for (var i = 0, l = xs.length; i < l; i++) {
if (xs[i] === x) return i;
@@ -13146,39 +13879,28 @@
util.inherits(Transform, Duplex);
-function TransformState(stream) {
- this.afterTransform = function (er, data) {
- return afterTransform(stream, er, data);
- };
-
- this.needTransform = false;
- this.transforming = false;
- this.writecb = null;
- this.writechunk = null;
- this.writeencoding = null;
-}
-
-function afterTransform(stream, er, data) {
- var ts = stream._transformState;
+function afterTransform(er, data) {
+ var ts = this._transformState;
ts.transforming = false;
var cb = ts.writecb;
if (!cb) {
- return stream.emit('error', new Error('write callback called multiple times'));
+ return this.emit('error', new Error('write callback called multiple times'));
}
ts.writechunk = null;
ts.writecb = null;
- if (data !== null && data !== undefined) stream.push(data);
+ if (data != null) // single equals check for both `null` and `undefined`
+ this.push(data);
cb(er);
- var rs = stream._readableState;
+ var rs = this._readableState;
rs.reading = false;
if (rs.needReadable || rs.length < rs.highWaterMark) {
- stream._read(rs.highWaterMark);
+ this._read(rs.highWaterMark);
}
}
@@ -13187,9 +13909,14 @@
Duplex.call(this, options);
- this._transformState = new TransformState(this);
-
- var stream = this;
+ this._transformState = {
+ afterTransform: afterTransform.bind(this),
+ needTransform: false,
+ transforming: false,
+ writecb: null,
+ writechunk: null,
+ writeencoding: null
+ };
// start out asking for a readable event once data is transformed.
this._readableState.needReadable = true;
@@ -13206,11 +13933,19 @@
}
// When the writable side finishes, then flush out anything remaining.
- this.once('prefinish', function () {
- if (typeof this._flush === 'function') this._flush(function (er, data) {
- done(stream, er, data);
- });else done(stream);
+ this.on('prefinish', prefinish);
+}
+
+function prefinish() {
+ var _this = this;
+
+ if (typeof this._flush === 'function') {
+ this._flush(function (er, data) {
+ done(_this, er, data);
});
+ } else {
+ done(this, null, null);
+ }
}
Transform.prototype.push = function (chunk, encoding) {
@@ -13260,27 +13995,25 @@
};
Transform.prototype._destroy = function (err, cb) {
- var _this = this;
+ var _this2 = this;
Duplex.prototype._destroy.call(this, err, function (err2) {
cb(err2);
- _this.emit('close');
+ _this2.emit('close');
});
};
function done(stream, er, data) {
if (er) return stream.emit('error', er);
- if (data !== null && data !== undefined) stream.push(data);
+ if (data != null) // single equals check for both `null` and `undefined`
+ stream.push(data);
// if there's nothing in the write buffer, then that means
// that nothing more will ever be provided
- var ws = stream._writableState;
- var ts = stream._transformState;
-
- if (ws.length) throw new Error('Calling transform done when ws.length != 0');
+ if (stream._writableState.length) throw new Error('Calling transform done when ws.length != 0');
- if (ts.transforming) throw new Error('Calling transform done when still transforming');
+ if (stream._transformState.transforming) throw new Error('Calling transform done when still transforming');
return stream.push(null);
}
@@ -13315,7 +14048,7 @@
/*<replacement>*/
-var processNextTick = require('process-nextick-args');
+var pna = require('process-nextick-args');
/*</replacement>*/
module.exports = Writable;
@@ -13342,7 +14075,7 @@
/* </replacement> */
/*<replacement>*/
-var asyncWrite = !process.browser && ['v0.10', 'v0.9.'].indexOf(process.version.slice(0, 5)) > -1 ? setImmediate : processNextTick;
+var asyncWrite = !process.browser && ['v0.10', 'v0.9.'].indexOf(process.version.slice(0, 5)) > -1 ? setImmediate : pna.nextTick;
/*</replacement>*/
/*<replacement>*/
@@ -13388,18 +14123,27 @@
options = options || {};
+ // Duplex streams are both readable and writable, but share
+ // the same options object.
+ // However, some cases require setting options to different
+ // values for the readable and the writable sides of the duplex stream.
+ // These options can be provided separately as readableXXX and writableXXX.
+ var isDuplex = stream instanceof Duplex;
+
// object stream flag to indicate whether or not this stream
// contains buffers or objects.
this.objectMode = !!options.objectMode;
- if (stream instanceof Duplex) this.objectMode = this.objectMode || !!options.writableObjectMode;
+ if (isDuplex) this.objectMode = this.objectMode || !!options.writableObjectMode;
// the point at which write() starts returning false
// Note: 0 is a valid value, means that we always return false if
// the entire buffer is not flushed immediately on write()
var hwm = options.highWaterMark;
+ var writableHwm = options.writableHighWaterMark;
var defaultHwm = this.objectMode ? 16 : 16 * 1024;
- this.highWaterMark = hwm || hwm === 0 ? hwm : defaultHwm;
+
+ if (hwm || hwm === 0) this.highWaterMark = hwm;else if (isDuplex && (writableHwm || writableHwm === 0)) this.highWaterMark = writableHwm;else this.highWaterMark = defaultHwm;
// cast to ints.
this.highWaterMark = Math.floor(this.highWaterMark);
@@ -13513,6 +14257,7 @@
Object.defineProperty(Writable, Symbol.hasInstance, {
value: function (object) {
if (realHasInstance.call(this, object)) return true;
+ if (this !== Writable) return false;
return object && object._writableState instanceof WritableState;
}
@@ -13564,7 +14309,7 @@
var er = new Error('write after end');
// TODO: defer error events consistently everywhere, not just the cb
stream.emit('error', er);
- processNextTick(cb, er);
+ pna.nextTick(cb, er);
}
// Checks that a user-supplied chunk is valid, especially for the particular
@@ -13581,7 +14326,7 @@
}
if (er) {
stream.emit('error', er);
- processNextTick(cb, er);
+ pna.nextTick(cb, er);
valid = false;
}
return valid;
@@ -13590,7 +14335,7 @@
Writable.prototype.write = function (chunk, encoding, cb) {
var state = this._writableState;
var ret = false;
- var isBuf = _isUint8Array(chunk) && !state.objectMode;
+ var isBuf = !state.objectMode && _isUint8Array(chunk);
if (isBuf && !Buffer.isBuffer(chunk)) {
chunk = _uint8ArrayToBuffer(chunk);
@@ -13644,6 +14389,16 @@
return chunk;
}
+Object.defineProperty(Writable.prototype, 'writableHighWaterMark', {
+ // making it explicit this property is not enumerable
+ // because otherwise some prototype manipulation in
+ // userland will fail
+ enumerable: false,
+ get: function () {
+ return this._writableState.highWaterMark;
+ }
+});
+
// if we're already writing something, then just put this
// in the queue, and wait our turn. Otherwise, call _write
// If we return false, then we need a drain event, so set that flag.
@@ -13701,10 +14456,10 @@
if (sync) {
// defer the callback if we are being called synchronously
// to avoid piling up things on the stack
- processNextTick(cb, er);
+ pna.nextTick(cb, er);
// this can emit finish, and it will always happen
// after error
- processNextTick(finishMaybe, stream, state);
+ pna.nextTick(finishMaybe, stream, state);
stream._writableState.errorEmitted = true;
stream.emit('error', er);
} else {
@@ -13802,6 +14557,7 @@
} else {
state.corkedRequestsFree = new CorkedRequest(state);
}
+ state.bufferedRequestCount = 0;
} else {
// Slow case, write chunks one-by-one
while (entry) {
@@ -13812,6 +14568,7 @@
doWrite(stream, state, false, len, chunk, encoding, cb);
entry = entry.next;
+ state.bufferedRequestCount--;
// if we didn't call the onwrite immediately, then
// it means that we need to wait until it does.
// also, that means that the chunk and cb are currently
@@ -13824,7 +14581,6 @@
if (entry === null) state.lastBufferedRequest = null;
}
- state.bufferedRequestCount = 0;
state.bufferedRequest = entry;
state.bufferProcessing = false;
}
@@ -13878,7 +14634,7 @@
if (typeof stream._final === 'function') {
state.pendingcb++;
state.finalCalled = true;
- processNextTick(callFinal, stream, state);
+ pna.nextTick(callFinal, stream, state);
} else {
state.prefinished = true;
stream.emit('prefinish');
@@ -13902,7 +14658,7 @@
state.ending = true;
finishMaybe(stream, state);
if (cb) {
- if (state.finished) processNextTick(cb);else stream.once('finish', cb);
+ if (state.finished) pna.nextTick(cb);else stream.once('finish', cb);
}
state.ended = true;
stream.writable = false;
@@ -13954,12 +14710,10 @@
},{"./_stream_duplex":58,"./internal/streams/destroy":64,"./internal/streams/stream":65,"_process":56,"core-util-is":42,"inherits":50,"process-nextick-args":55,"safe-buffer":70,"util-deprecate":73}],63:[function(require,module,exports){
'use strict';
-/*<replacement>*/
-
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var Buffer = require('safe-buffer').Buffer;
-/*</replacement>*/
+var util = require('util');
function copyBuffer(src, target, offset) {
src.copy(target, offset);
@@ -14026,12 +14780,19 @@
return BufferList;
}();
-},{"safe-buffer":70}],64:[function(require,module,exports){
+
+if (util && util.inspect && util.inspect.custom) {
+ module.exports.prototype[util.inspect.custom] = function () {
+ var obj = util.inspect({ length: this.length });
+ return this.constructor.name + ' ' + obj;
+ };
+}
+},{"safe-buffer":70,"util":38}],64:[function(require,module,exports){
'use strict';
/*<replacement>*/
-var processNextTick = require('process-nextick-args');
+var pna = require('process-nextick-args');
/*</replacement>*/
// undocumented cb() API, needed for core, not for public API
@@ -14045,9 +14806,9 @@
if (cb) {
cb(err);
} else if (err && (!this._writableState || !this._writableState.errorEmitted)) {
- processNextTick(emitErrorNT, this, err);
+ pna.nextTick(emitErrorNT, this, err);
}
- return;
+ return this;
}
// we set destroyed to true before firing error callbacks in order
@@ -14064,7 +14825,7 @@
this._destroy(err || null, function (err) {
if (!cb && err) {
- processNextTick(emitErrorNT, _this, err);
+ pna.nextTick(emitErrorNT, _this, err);
if (_this._writableState) {
_this._writableState.errorEmitted = true;
}
@@ -14072,6 +14833,8 @@
cb(err);
}
});
+
+ return this;
}
function undestroy() {
@@ -14314,9 +15077,33 @@
};
},{"events":47,"inherits":50,"readable-stream/duplex.js":57,"readable-stream/passthrough.js":66,"readable-stream/readable.js":67,"readable-stream/transform.js":68,"readable-stream/writable.js":69}],72:[function(require,module,exports){
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
'use strict';
+/*<replacement>*/
+
var Buffer = require('safe-buffer').Buffer;
+/*</replacement>*/
var isEncoding = Buffer.isEncoding || function (encoding) {
encoding = '' + encoding;
@@ -14428,10 +15215,10 @@
};
// Checks the type of a UTF-8 byte, whether it's ASCII, a leading byte, or a
-// continuation byte.
+// continuation byte. If an invalid byte is detected, -2 is returned.
function utf8CheckByte(byte) {
if (byte <= 0x7F) return 0;else if (byte >> 5 === 0x06) return 2;else if (byte >> 4 === 0x0E) return 3;else if (byte >> 3 === 0x1E) return 4;
- return -1;
+ return byte >> 6 === 0x02 ? -1 : -2;
}
// Checks at most 3 bytes at the end of a Buffer in order to detect an
@@ -14445,13 +15232,13 @@
if (nb > 0) self.lastNeed = nb - 1;
return nb;
}
- if (--j < i) return 0;
+ if (--j < i || nb === -2) return 0;
nb = utf8CheckByte(buf[j]);
if (nb >= 0) {
if (nb > 0) self.lastNeed = nb - 2;
return nb;
}
- if (--j < i) return 0;
+ if (--j < i || nb === -2) return 0;
nb = utf8CheckByte(buf[j]);
if (nb >= 0) {
if (nb > 0) {
@@ -14465,7 +15252,7 @@
// Validates as many continuation bytes for a multi-byte UTF-8 character as
// needed or are available. If we see a non-continuation byte where we expect
// one, we "replace" the validated continuation bytes we've seen so far with
-// UTF-8 replacement characters ('\ufffd'), to match v8's UTF-8 decoding
+// a single UTF-8 replacement character ('\ufffd'), to match v8's UTF-8 decoding
// behavior. The continuation byte check is included three times in the case
// where all of the continuation bytes for a character exist in the same buffer.
// It is also done this way as a slight performance increase instead of using a
@@ -14473,17 +15260,17 @@
function utf8CheckExtraBytes(self, buf, p) {
if ((buf[0] & 0xC0) !== 0x80) {
self.lastNeed = 0;
- return '\ufffd'.repeat(p);
+ return '\ufffd';
}
if (self.lastNeed > 1 && buf.length > 1) {
if ((buf[1] & 0xC0) !== 0x80) {
self.lastNeed = 1;
- return '\ufffd'.repeat(p + 1);
+ return '\ufffd';
}
if (self.lastNeed > 2 && buf.length > 2) {
if ((buf[2] & 0xC0) !== 0x80) {
self.lastNeed = 2;
- return '\ufffd'.repeat(p + 2);
+ return '\ufffd';
}
}
}
@@ -14514,11 +15301,11 @@
return buf.toString('utf8', i, end);
}
-// For UTF-8, a replacement character for each buffered byte of a (partial)
-// character needs to be added to the output.
+// For UTF-8, a replacement character is added when ending on a partial
+// character.
function utf8End(buf) {
var r = buf && buf.length ? this.write(buf) : '';
- if (this.lastNeed) return r + '\ufffd'.repeat(this.lastTotal - this.lastNeed);
+ if (this.lastNeed) return r + '\ufffd';
return r;
}

package.json

@@ -1,6 +1,6 @@
{
"name": "mocha",
- "version": "5.0.0",
+ "version": "5.2.0",
"description": "simple, flexible, fun test framework",
"keywords": [
"mocha",
@@ -11,282 +11,433 @@
],
"author": "TJ Holowaychuk <tj@vision-media.ca>",
"contributors": [
- "aaroncrows (https://github.com/aaroncrows)",
- "Aaron Hamid <aaron@incsw.com> (https://github.com/ahamid)",
- "Aaron Heckmann <aaron.heckmann+github@gmail.com> (https://github.com/aheckmann)",
- "Adam Crabtree (CrabDude's alias) (https://github.com/CrabBot)",
- "Adam Gruber (https://github.com/adamgruber)",
- "Adrian Ludwig (https://github.com/adrian-ludwig)",
- "Ainthe Kitchen <a.in.the.k@gmail.com> (https://github.com/ainthek)",
- "ajaykodali (https://github.com/ajaykodali)",
- "Alex Early (https://github.com/aearly)",
- "Alex Pham <thedark1337@thedark1337.com> (https://github.com/thedark1337)",
- "amsul (https://github.com/amsul)",
- "Andreas Brekken <andreas@brekken.com> (https://github.com/abrkn)",
- "Andreas Lind <andreas@one.com> (https://github.com/papandreou)",
- "Andrew Krawchyk <akrawchyk@gmail.com> (https://github.com/akrawchyk)",
- "Andrew Miller <vnikitin@live.com> (https://github.com/vnikiti)",
- "Andrew Nesbitt <andrewnez@gmail.com> (https://github.com/andrew)",
- "Andrey Popp <8mayday@gmail.com> (https://github.com/andreypopp)",
- "Andrii Shumada <eagleeyes91@gmail.com> (https://github.com/eagleeye)",
- "Anis Safine (https://github.com/anis)",
- "Arian Stolwijk <stolwijk.arian@gmail.com> (https://github.com/arian)",
- "Ariel Mashraki <ariel@mashraki.co.il> (https://github.com/a8m)",
- "Arnaud Brousseau (https://github.com/ArnaudBrousseau)",
- "Atsuya Takagi <atsuya.takagi@gmail.com> (https://github.com/atsuya)",
- "Attila Domokos (https://github.com/adomokos)",
- "Austin Birch (https://github.com/austinbirch)",
- "Avi Vahl (https://github.com/AviVahl)",
- "Ben Bradley (https://github.com/ben-bradley)",
- "beneidel (https://github.com/beneidel)",
- "Benjie Gillam (https://github.com/benjie)",
- "Ben Noordhuis <info@bnoordhuis.nl> (https://github.com/bnoordhuis)",
- "Benoit Larroque (https://github.com/zetaben)",
- "Benoît Zugmeyer (https://github.com/BenoitZugmeyer)",
- "Ben Vinegar (https://github.com/benvinegar)",
- "Berker Peksag <berker.peksag@gmail.com> (https://github.com/berkerpeksag)",
- "Bjørge Næss (https://github.com/bjoerge)",
- "Brendan Nee <brendan@blinktag.com> (https://github.com/brendannee)",
- "Brian Beck <exogen@gmail.com> (https://github.com/exogen)",
- "Brian C <brian.m.carlson@gmail.com> (https://github.com/brianc)",
- "Brian Lalor <blalor@bravo5.org> (https://github.com/blalor)",
- "Brian Moore (https://github.com/bionicbrian)",
- "Bryan Donovan (https://github.com/BryanDonovan)",
- "Buck Doyle (https://github.com/backspace)",
- "C. Scott Ananian <cscott@cscott.net> (https://github.com/cscott)",
- "Casey Foster (https://github.com/caseywebdev)",
- "Charles Lowell <cowboyd@frontside.io> (https://github.com/cowboyd)",
- "Chris Buckley <chris@cmbuckley.co.uk> (https://github.com/cmbuckley)",
- "Christopher Hiller <boneskull@boneskull.com> (https://github.com/boneskull)",
- "Chris Wren <chriswrendev@gmail.com> (https://github.com/ChrisWren)",
- "Clemens Stolle (https://github.com/klaemo)",
- "Connor Dunn (https://github.com/Connorhd)",
- "Corey Butler (https://github.com/coreybutler)",
- "Cory Thomas (https://github.com/dump247)",
- "cybertk (https://github.com/cybertk)",
- "Daniel Ericsson (https://github.com/monowerker)",
- "Daniel Ruf (https://github.com/danielruf)",
- "Daniel St. Jules <danielst.jules@gmail.com> (https://github.com/danielstjules)",
- "Daniel Stockman <daniel.stockman@gmail.com> (https://github.com/evocateur)",
- "Dave McKenna <davemckenna01@gmail.com> (https://github.com/davemckenna01)",
- "David da Silva <yo@dasilvacont.in> (https://github.com/dasilvacontin)",
- "David Henderson (https://github.com/dhendo)",
- "Denis Bardadym <bardadymchik@gmail.com> (https://github.com/btd)",
- "Devin Weaver <suki@tritarget.org> (https://github.com/sukima)",
- "Diogo Monteiro <diogo.gmt@gmail.com> (https://github.com/diogogmt)",
- "Dmitry Shirokov <deadrunk@gmail.com> (https://github.com/runk)",
- "Domenic Denicola <d@domenic.me> (https://github.com/domenic)",
- "Dominic Barnes <dominic@dbarnes.info> (https://github.com/dominicbarnes)",
- "domq (https://github.com/domq)",
- "Douglas Wilson <doug@somethingdoug.com> (https://github.com/dougwilson)",
- "Duncan Beevers <duncan@dweebd.com> (https://github.com/duncanbeevers)",
- "Duncan Wong (https://github.com/badunk)",
- "eiji.ienaga (https://github.com/haru01)",
- "Fabio Crisci <piuccio@gmail.com> (https://github.com/piuccio)",
- "Fede Ramirez <i@2fd.me> (https://github.com/2fd)",
- "Fedor Indutny <fedor@indutny.com> (https://github.com/indutny)",
- "fengmk2 <m@fengmk2.com> (https://github.com/fengmk2)",
- "Florian Margaine <florian@margaine.com> (https://github.com/ralt)",
- "Forbes Lindesay (https://github.com/ForbesLindesay)",
- "Frederico Silva (https://github.com/fredericosilva)",
- "Fredrik Enestad <fredrik.enestad@soundtrackyourbrand.com> (https://github.com/fredr)",
- "Fredrik Lindin (https://github.com/Cowboy-coder)",
- "Gabriel Silk (https://github.com/gsilk)",
- "Gareth Aye <gareth.aye@gmail.com> (https://github.com/gaye)",
- "Gavin Mogan <gavin@gavinmogan.com> (https://github.com/halkeye)",
- "gigadude (https://github.com/gigadude)",
- "Giovanni Bassi (https://github.com/giggio)",
- "Glen Huang <curvedmark@gmail.com> (https://github.com/curvedmark)",
- "Glen Mailer <glen@stainlessed.co.uk> (https://github.com/glenjamin)",
- "Greg Perkins <gregperkins@alum.mit.edu> (https://github.com/gregrperkins)",
- "Guillermo Rauch <rauchg@gmail.com> (https://github.com/rauchg)",
- "Guy Arye (https://github.com/aryeguy)",
- "Gyandeep Singh <gyandeeps@gmail.com> (https://github.com/gyandeeps)",
- "Harish <hyeluri@gmail.com> (https://github.com/hyeluri)",
- "Harry Brundage <harry.brundage@gmail.com> (https://github.com/airhorns)",
- "Ian Remmel <design@ianwremmel.com> (https://github.com/ianwremmel)",
- "Ian Storm Taylor (https://github.com/ianstormtaylor)",
- "Ian Young <ian@iangreenleaf.com> (https://github.com/iangreenleaf)",
- "Ivan (https://github.com/ivanstoyanov)",
- "Jaakko Salonen (https://github.com/jsalonen)",
- "Jacob Wejendorp <jacob@wejendorp.dk> (https://github.com/wejendorp)",
- "Jake Craige (https://github.com/jakecraige)",
- "Jake Marsh (https://github.com/jakemmarsh)",
- "Jake Mc <jake.mc@icloud.com> (https://github.com/startswithaj)",
- "Jake Verbaten <raynos2@gmail.com> (https://github.com/Raynos)",
- "Jakub Nešetřil <jakub@apiary.io> (https://github.com/zzen)",
- "James Bowes (https://github.com/jbowes)",
- "James Carr <james.r.carr@gmail.com> (https://github.com/jamescarr)",
- "James G. Kim <jgkim@jayg.org> (https://github.com/jgkim)",
- "James Lal <james@lightsofapollo.com> (https://github.com/lightsofapollo)",
- "James Nylen <jnylen@gmail.com> (https://github.com/nylen)",
- "Jason (https://github.com/jlai)",
- "Jason Barry <jay@jcbarry.com> (https://github.com/JCBarry)",
- "Javier Aranda <javier.aranda.varo@gmail.com> (https://github.com/javierav)",
- "jcreamer898 (https://github.com/jcreamer898)",
- "Jean Ponchon (https://github.com/nopnop)",
- "Jeff Kunkle (https://github.com/kunklejr)",
- "Jeff Schilling <jeff@manicwave.com> (https://github.com/jschilli)",
- "JeongHoon Byun (aka Outsider) <outsideris@gmail.com> (https://github.com/outsideris)",
- "Jeremy Martin (https://github.com/jmar777)",
- "jimenglish81 (https://github.com/jimenglish81)",
- "Jimmy Cuadra (https://github.com/jimmycuadra)",
- "jldailey (https://github.com/jldailey)",
- "jleyba (https://github.com/jleyba)",
- "Joey Cozza <joeycozza@gmail.com> (https://github.com/joeycozza)",
- "Johnathon Sanders (https://github.com/outdooricon)",
- "John Doty <jrhdoty@gmail.com> (https://github.com/jrhdoty)",
- "John Firebaugh <john.firebaugh@gmail.com> (https://github.com/jfirebaugh)",
- "John Reeves (https://github.com/jonnyreeves)",
- "Jo Liss <joliss42@gmail.com> (https://github.com/joliss)",
- "Jonas Dohse (https://github.com/dohse)",
- "Jonathan Kim <hello@jkimbo.co.uk> (https://github.com/jkimbo)",
- "Jonathan Park <jonathan.daniel.park@gmail.com> (https://github.com/park9140)",
- "jongleberry <me@jongleberry.com> (https://github.com/jonathanong)",
- "Jordan Sexton <jordan@jordansexton.com> (https://github.com/jordansexton)",
- "Joseph Spencer (https://github.com/jsdevel)",
- "Josh Lory (https://github.com/joshlory)",
- "Joshua Appelman <joshua@jbna.nl> (https://github.com/jbnicolai)",
- "Joshua Krall <joshuakrall@pobox.com> (https://github.com/jkrall)",
- "João Moreno (https://github.com/joaomoreno)",
- "João Paulo Bochi <jpbochi@gmail.com> (https://github.com/jpbochi)",
- "jugglinmike (https://github.com/jugglinmike)",
- "Julien Wajsberg (https://github.com/julienw)",
- "Jussi Virtanen <contact@jvirtanen.org> (https://github.com/jvirtanen)",
- "Justin DuJardin (https://github.com/justindujardin)",
- "Juzer Ali <juzerali@live.com> (https://github.com/juzerali)",
- "Jérémie Astori (https://github.com/astorije)",
- "Katie Gengler (https://github.com/kategengler)",
- "Kazuhito Hokamura (https://github.com/hokaccha)",
- "Keith Cirkel (https://github.com/keithamus)",
- "Kent C. Dodds <kent+github@doddsfamily.us> (https://github.com/kentcdodds)",
- "Kevin Burke <kev@inburke.com> (https://github.com/kevinburke)",
- "Kevin Conway <kevinjacobconway@gmail.com> (https://github.com/kevinconway)",
- "Kevin Kirsche <Kev.Kirsche@gmail.com> (https://github.com/kkirsche)",
- "Kirill Korolyov <kirill.korolyov@gmail.com> (https://github.com/Dremora)",
- "Koen Punt <mail@koen.pt> (https://github.com/koenpunt)",
- "Konstantin Käfer <mail@kkaefer.com> (https://github.com/kkaefer)",
- "Kris Rasmussen (https://github.com/krisr)",
- "Kyle Mitchell <kyle@kemitchell.com> (https://github.com/kemitchell)",
- "lakmeer (https://github.com/lakmeer)",
- "Liam Newman <bitwiseman@gmail.com> (https://github.com/bitwiseman)",
- "Linus Unnebäck <linus@folkdatorn.se> (https://github.com/LinusU)",
- "Long Ho <holevietlong@gmail.com> (https://github.com/longlho)",
- "László Bácsi <lackac@lackac.hu> (https://github.com/lackac)",
- "Maciej Małecki <me@mmalecki.com> (https://github.com/mmalecki)",
- "Mal Graty (https://github.com/mal)",
- "Marcello Bastéa-Forte <marcello@cellosoft.com> (https://github.com/marcello3d)",
- "Marc Kuo <marc@routific.com> (https://github.com/mck-)",
- "Mark Banner (https://github.com/Standard8)",
- "Matija Marohnić <matija.marohnic@gmail.com> (https://github.com/silvenon)",
- "Matthew Shanley <matthewshanley@littlesecretsrecords.com> (https://github.com/arkadyan)",
- "mattias-lw (https://github.com/mattias-lw)",
- "Matt Robenolt <m@robenolt.com> (https://github.com/mattrobenolt)",
- "Matt Smith <matt@twobitfool.com> (https://github.com/twobitfool)",
- "Max Goodman <c@chromako.de> (https://github.com/chromakode)",
- "Maximilian Antoni <mail@maxantoni.de> (https://github.com/mantoni)",
- "Merrick Christensen <merrick.christensen@gmail.com> (https://github.com/iammerrick)",
- "michael-adsk (https://github.com/michael-adsk)",
- "Michael Demmer (https://github.com/demmer)",
- "Michael Jackson <mjijackson@gmail.com> (https://github.com/mjackson)",
- "Michael Schoonmaker <michael.r.schoonmaker@gmail.com> (https://github.com/Schoonology)",
- "Michal Charemza (https://github.com/michalc)",
- "Mike Olson (https://github.com/mwolson)",
- "Mislav Marohnić <mislav.marohnic@gmail.com> (https://github.com/mislav)",
- "mrShturman (https://github.com/mrShturman)",
- "Nathan Alderson <nathan@nathanalderson.com> (https://github.com/nathanalderson)",
- "Nathan Black <nathan@nathanblack.org> (https://github.com/nathanboktae)",
- "Nathan Bowser <nbowser@gmail.com> (https://github.com/nathanbowser)",
- "Nathan Houle <nathan+github@nathanhoule.com> (https://github.com/ndhoule)",
- "Nathan Rajlich <nathan@tootallnate.net> (https://github.com/TooTallNate)",
- "Nick Fitzgerald (https://github.com/fitzgen)",
- "Nikolaos Georgiou (https://github.com/ngeor)",
- "noirlab (https://github.com/noirlab)",
- "Noshir Patel <nosh@blackpiano.com> (https://github.com/noshir-patel)",
- "OlegTsyba <oleg.tsyba.ua@gmail.com> (https://github.com/OlegTsyba)",
- "omar (https://github.com/omardelarosa)",
- "Panu Horsmalahti <panu.horsmalahti@iki.fi> (https://github.com/panuhorsmalahti)",
- "Parker Moore <email@byparker.com> (https://github.com/parkr)",
- "Paul Armstrong (https://github.com/paularmstrong)",
- "Paul Miller <paul+gh@paulmillr.com> (https://github.com/paulmillr)",
- "Pavel Zubkou (https://github.com/irnc)",
- "Pete Hawkins (https://github.com/phawk)",
- "Phil Sung <philbert@gmail.com> (https://github.com/psung)",
- "Prayag Verma <prayag.verma@gmail.com> (https://github.com/pra85)",
- "qiu zuhui <qiuzuhui@gmail.com> (https://github.com/qiuzuhui)",
- "Quang Van <quang@boldapps.io> (https://github.com/quangv)",
- "Rauno (https://github.com/Rauno56)",
- "Refael Ackermann <me@refack.com> (https://github.com/refack)",
- "Richard Dingwall <rdingwall@gmail.com> (https://github.com/rdingwall)",
- "Richard Knop (https://github.com/RichardKnop)",
- "Rico Sta. Cruz <hi@ricostacruz.com> (https://github.com/rstacruz)",
- "Robert Rossmann (https://github.com/Alaneor)",
- "Rob Wu <rob@robwu.nl> (https://github.com/Rob--W)",
- "Romain (https://github.com/rprieto)",
- "Roman Neuhauser <rneuhauser@sigpipe.cz> (https://github.com/roman-neuhauser)",
- "Roman Shtylman (https://github.com/defunctzombie)",
- "Russ Bradberry <devdazed@me.com> (https://github.com/devdazed)",
- "Russell Munson (https://github.com/rmunson)",
- "Rustem Mustafin <mustafin.rustem@gmail.com> (https://github.com/rulikkk)",
- "Ryan <ryan.shaw@min.vc> (https://github.com/ryan-shaw)",
- "Ryan Hubbard (https://github.com/ryedog)",
- "Ryunosuke Sato <tricknotes.rs@gmail.com> (https://github.com/tricknotes)",
- "ryym (https://github.com/ryym)",
- "Salehen Shovon Rahman <sal@linux.com> (https://github.com/shovon)",
- "Salvador de la Puente González <salva@unoyunodiez.com> (https://github.com/delapuente)",
- "Sam Mussell (https://github.com/smussell)",
- "Samuel Goldszmidt <samuel.goldszmidt@gmail.com> (https://github.com/ouhouhsami)",
- "Sasha Koss <kossnocorp@gmail.com> (https://github.com/kossnocorp)",
- "Scott Santucci <ScottFreeCode@gmail.com> (https://github.com/ScottFreeCode)",
- "Sean Lang <slang800@gmail.com> (https://github.com/slang800)",
- "seb vincent <seb.vincent@gmail.com> (https://github.com/sebv)",
- "Seiya Konno <nulltask@gmail.com> (https://github.com/nulltask)",
- "Sergey Simonchik (https://github.com/segrey)",
- "Sergio Santoro (https://github.com/taueres)",
- "Shahar Soel (https://github.com/bd82)",
- "Shaine Hatch (https://github.com/shaine)",
- "Shiwei Wang (https://github.com/wsw0108)",
- "Simon Gaeremynck (https://github.com/simong)",
- "Simon Goumaz (https://github.com/sgoumaz)",
- "Sindre Sorhus <sindresorhus@gmail.com> (https://github.com/sindresorhus)",
- "slientcloud <rjmuqiang@gmail.com> (https://github.com/silentcloud)",
- "Sorin Iclanzan (https://github.com/iclanzan)",
- "Standa Opichal <opichals@gmail.com> (https://github.com/opichals)",
- "Stephen Mathieson <me@stephenmathieson.com> (https://github.com/stephenmathieson)",
- "Steve Mason (https://github.com/spmason)",
- "Stewart Taylor <stewart@taylore.net> (https://github.com/Stewart-Taylor)",
- "Sune Simonsen <sune@we-knowhow.dk> (https://github.com/sunesimonsen)",
- "Sylvain Faucherand (https://github.com/slyg)",
- "Takuya Nishigori <nishigori.tak@gmail.com> (https://github.com/nishigori)",
- "Taylor Gautier (https://github.com/tsgautier)",
- "Teddy Zeenny (https://github.com/teddyzeenny)",
- "Thomas Grainger <https//@graingert.co.uk> (https://github.com/graingert)",
- "Tim Ehat (https://github.com/timehat)",
- "Timothy Gu <timothygu99@gmail.com> (https://github.com/TimothyGu)",
- "Timo Tijhof <krinklemail@gmail.com> (https://github.com/Krinkle)",
- "Tingan Ho <tingan87@gmail.com> (https://github.com/tinganho)",
- "TJ Holowaychuk <tj@vision-media.ca> (https://github.com/tj)",
- "Tobias Bieniek <tobias.bieniek@gmail.com> (https://github.com/Turbo87)",
- "Toby Ho <airportyh@gmail.com> (https://github.com/airportyh)",
- "Todd Agulnick (https://github.com/tawdle)",
- "Tom Hughes (https://github.com/tomhughes)",
- "Tommy Montgomery (https://github.com/tmont)",
- "traleig1 (https://github.com/traleig1)",
- "Travis Jeffery <tj@travisjeffery.com> (https://github.com/travisjeffery)",
- "Tyson Tate <tyson@tysontate.com> (https://github.com/tysontate)",
- "Valentin Agachi (https://github.com/avaly)",
- "Victor Costan <victor@costan.us> (https://github.com/pwnall)",
- "Vladimir Chernis (https://github.com/vlazzle)",
- "Vlad Magdalin <vlad@webflow.com> (https://github.com/callmevlad)",
- "Will Langstroth (https://github.com/wlangstroth)",
- "Wil Moore III <wil.moore@wilmoore.com> (https://github.com/wilmoore)",
- "Xavier Antoviaque <xavier@opencraft.com> (https://github.com/antoviaque)",
- "Xavier Damman <xdamman@gmail.com> (https://github.com/xdamman)",
- "Yanis Wang <yanis.wang@gmail.com> (https://github.com/yaniswang)",
- "yuitest <developer.yuitest+github@cjhat.net> (https://github.com/yuitest)",
- "Zhiye Li <github@zhiye.li> (https://github.com/zhiyelee)",
- "Zhouxuan Yang <fool2fish@gmail.com> (https://github.com/fool2fish)",
- "Zsolt Takács <firstname at lastname dot cc> (https://github.com/oker1)"
+ "38elements <mh19820223@gmail.com>",
+ "Aaron Brady <aaron@mori.com>",
+ "Aaron Hamid <aaron.hamid@gmail.com>",
+ "Aaron Heckmann <aaron.heckmann+github@gmail.com>",
+ "Aaron Krause <aaronjkrause@gmail.com>",
+ "Aaron Petcoff <hello@aaronpetcoff.me>",
+ "abrkn <a@abrkn.com>",
+ "Adam Crabtree <adam.crabtree@redrobotlabs.com>",
+ "Adam Gruber <talknmime@gmail.com>",
+ "Adrian Ludwig <me@adrianludwig.pl>",
+ "Ahmad Bamieh <ahmadbamieh@gmail.com>",
+ "airportyh <airportyh@gmail.com>",
+ "Ajay Kodali <ajay.kodali@citrix.com>",
+ "Al Scott <al.scott@atomicobject.com>",
+ "Alex Bainter <metalex9@users.noreply.github.com>",
+ "Alexander Early <alexander.early@gmail.com>",
+ "Alexander Shepelin <Brightcor@gmail.com>",
+ "Alhadis <gardnerjohng@gmail.com>",
+ "amsul <reach@amsul.ca>",
+ "Anders Olsen Sandvik <Andersos@users.noreply.github.com>",
+ "Andreas Brekken <andreas@opuno.com>",
+ "Andreas Lind Petersen <andreas@one.com>",
+ "Andrew Krawchyk <903716+akrawchyk@users.noreply.github.com>",
+ "Andrew Nesbitt <andrewnez@gmail.com>",
+ "Andrey Popp <8mayday@gmail.com>",
+ "Andrii Shumada <eagleeyes91@gmail.com>",
+ "andy matthews <andy@commadelimited.com>",
+ "Angelica Valenta <angelicavalenta@gmail.com>",
+ "Anis Safine <anis.safine.ext@francetv.fr>",
+ "Anish Karandikar <anishkny@gmail.com>",
+ "Anthony <keppi@o2.pl>",
+ "Anton <anton.redfox@gmail.com>",
+ "anton <anton.valickij@gmail.com>",
+ "APerson <danielhglus@gmail.com>",
+ "Arian Stolwijk <arian@aryweb.nl>",
+ "Ariel Mashraki <ariel@mashraki.co.il>",
+ "Arnaud Brousseau <arnaud.brousseau@gmail.com>",
+ "Artem Govorov <artem.govorov@gmail.com>",
+ "Atsuya Takagi <asoftonight@gmail.com>",
+ "Attila Domokos <adomokos@gmail.com>",
+ "Austin Birch <mraustinbirch@gmail.com>",
+ "Avi Vahl <avi.vahl@wix.com>",
+ "badunk <baduncaduncan@gmail.com>",
+ "Bamieh <ahmadbamieh@gmail.com>",
+ "Ben Bradley <ben@bradleyit.com>",
+ "Ben Harris <benhdev@gmail.com>",
+ "Ben Hutchison <ben@aldaviva.com>",
+ "Ben Lindsey <ben.lindsey@vungle.com>",
+ "Ben Noordhuis <info@bnoordhuis.nl>",
+ "Ben Vinegar <ben@benv.ca>",
+ "Benjamin Eidelman <beneidel@gmail.com>",
+ "Benjie Gillam <benjie@jemjie.com>",
+ "Benoit Larroque <zeta.ben@gmail.com>",
+ "Benoît Zugmeyer <bzugmeyer@gmail.com>",
+ "Benson Trent <bensontrent@gmail.com>",
+ "Berker Peksag <berker.peksag@gmail.com>",
+ "berni <berni@extensa.pl>",
+ "Bjørge Næss <bjoerge@origo.no>",
+ "Brendan Nee <brendan.nee@gmail.com>",
+ "Brian Beck <exogen@gmail.com>",
+ "Brian Lalor <blalor@bravo5.org>",
+ "Brian M. Carlson <brian.m.carlson@gmail.com>",
+ "Brian Moore <guardbionic-github@yahoo.com>",
+ "Bryan Donovan <bdondo@gmail.com>",
+ "Buck Doyle <b@chromatin.ca>",
+ "C. Scott Ananian <cscott@cscott.net>",
+ "Callum Macrae <callum@macr.ae>",
+ "Can Oztokmak <can@zeplin.io>",
+ "Capacitor Set <CapacitorSet@users.noreply.github.com>",
+ "Casey Foster <casey@caseywebdev.com>",
+ "Charles Lowell <cowboyd@frontside.io>",
+ "Charles Merriam <charles.merriam@gmail.com>",
+ "Charlie Rudolph <charles.w.rudolph@gmail.com>",
+ "Chris <chrisleck@users.noreply.github.com>",
+ "Chris Buckley <chris@cmbuckley.co.uk>",
+ "Chris Lamb <chris@chris-lamb.co.uk>",
+ "Christian <me@rndm.de>",
+ "Christoffer Hallas <christoffer.hallas@gmail.com>",
+ "Christoph Neuroth <christoph.neuroth@gmail.com>",
+ "Christopher Hiller <boneskull@boneskull.com>",
+ "ChrisWren <cthewren@gmail.com>",
+ "claudyus <claudyus@HEX.(none)>",
+ "Connor Dunn <connorhd@gmail.com>",
+ "Corey Butler <corey@coreybutler.com>",
+ "Cory Thomas <cory.thomas@bazaarvoice.com>",
+ "Craig Taub <craigtaub@gmail.com>",
+ "Cube <maty21@gmail.com>",
+ "Daniel Ruf <daniel@daniel-ruf.de>",
+ "Daniel St. Jules <danielst.jules@gmail.com>",
+ "Daniel Stockman <daniel.stockman@gmail.com>",
+ "Darryl Pogue <dvpdiner2@gmail.com>",
+ "Dave McKenna <davemckenna01@gmail.com>",
+ "David da Silva Contín <dasilvacontin@gmail.com>",
+ "David Henderson <david.henderson@triggeredmessaging.com>",
+ "David M. Lee <leedm777@yahoo.com>",
+ "David Neubauer <davidneub@gmail.com>",
+ "DavNej <davnej.dev@gmail.com>",
+ "Denis Bardadym <bardadymchik@gmail.com>",
+ "Devin Weaver <suki@tritarget.org>",
+ "dfberry <dinaberry@outlook.com>",
+ "Di Wu <dwu@palantir.com>",
+ "Dina Berry <dfberry@users.noreply.github.com>",
+ "Diogo Monteiro <diogo.gmt@gmail.com>",
+ "Dmitriy Simushev <simushevds@gmail.com>",
+ "Dmitry Shirokov <deadrunk@gmail.com>",
+ "Dmitry Sorin <info@staypositive.ru>",
+ "Domenic Denicola <domenic@domenicdenicola.com>",
+ "Dominic Barnes <dominic@dbarnes.info>",
+ "Dominique Quatravaux <dominique@quatravaux.org>",
+ "Douglas Christopher Wilson <doug@somethingdoug.com>",
+ "Duncan Beevers <duncan@dweebd.com>",
+ "eiji.ienaga <eiji.ienaga@gmail.com>",
+ "elergy <elergy@yandex-team.ru>",
+ "Eli Skeggs <skeggse@users.noreply.github.com>",
+ "ELLIOTTCABLE <me@ell.io>",
+ "Emanuele <my.burning@gmail.com>",
+ "Enric Pallerols <enric@pallerols.cat>",
+ "Erik Eng <mail@ptz0n.se>",
+ "Eugene Tiutiunnyk <eugene.tiutiunnyk@lookout.com>",
+ "Fabio M. Costa <fabiomcosta@gmail.com>",
+ "Fagner Brack <github3@fagnermartins.com>",
+ "FARKAS Máté <mate.farkas@virtual-call-center.eu>",
+ "fcrisci <fabio.crisci@amadeus.com>",
+ "Fede Ramirez <i@2fd.me>",
+ "Fedor Indutny <fedor.indutny@gmail.com>",
+ "fengmk2 <fengmk2@gmail.com>",
+ "Florian Margaine <florian@margaine.com>",
+ "FND <FND@users.noreply.github.com>",
+ "fool2fish <fool2fish@gmail.com>",
+ "Forbes Lindesay <forbes@lindesay.co.uk>",
+ "Frank Leon Rose <frankleonrose@gmail.com>",
+ "Frederico Silva <frederico.silva@gmail.com>",
+ "Fredrik Enestad <fredrik@devloop.se>",
+ "Fredrik Lindin <fredriklindin@gmail.com>",
+ "Fumiaki MATSUSHIMA <mtsmfm@gmail.com>",
+ "Gabriel Silk <gabesilk@gmail.com>",
+ "Gareth Aye <gaye@mozilla.com>",
+ "Gareth Murphy <gareth.cpm@gmail.com>",
+ "Gavin Mogan <GavinM@airg.com>",
+ "gaye <gaye@mozilla.com>",
+ "gigadude <gigadude@users.noreply.github.com>",
+ "Giovanni Bassi <giggio@giggio.net>",
+ "Glen Huang <curvedmark@gmail.com>",
+ "Glen Mailer <glenjamin@gmail.com>",
+ "grasGendarme <me@grasgendar.me>",
+ "Greg Perkins <gregperkins@alum.mit.edu>",
+ "Guangcong Luo <guangcongluo@gmail.com>",
+ "Guillermo Rauch <rauchg@gmail.com>",
+ "Guy Arye <arye.guy@gmail.com>",
+ "Gyandeep Singh <gyandeeps@gmail.com>",
+ "Harish <hyeluri@gmail.com>",
+ "Harry Brundage <harry.brundage@gmail.com>",
+ "Harry Sarson <harry.sarson@hotmail.co.uk>",
+ "Harry Wolff <hswolff@users.noreply.github.com>",
+ "Herman Junge <herman@geekli.st>",
+ "hokaccha <k.hokamura@gmail.com>",
+ "Honza Javorek <mail@honzajavorek.cz>",
+ "Hugo Giraudel <hugo.giraudel@gmail.com>",
+ "Ian Storm Taylor <ian@ianstormtaylor.com>",
+ "Ian W. Remmel <design@ianwremmel.com>",
+ "Ian Young <ian.greenleaf@gmail.com>",
+ "Ian Zamojc <ian@thesecretlocation.net>",
+ "Igwe Kalu <igwe.kalu@live.com>",
+ "ImgBot <31427850+ImgBotApp@users.noreply.github.com>",
+ "inxorable <inxorable@codewren.ch>",
+ "Ivan <ivan@kinvey.com>",
+ "Jaakko Salonen <jaakko.salonen@iki.fi>",
+ "Jacob Wejendorp <jacob@wejendorp.dk>",
+ "Jake Craige <james.craige@gmail.com>",
+ "Jake Marsh <jakemmarsh@gmail.com>",
+ "Jakob Krigovsky <jakob@krigovsky.com>",
+ "Jakub Nešetřil <jakub@apiary.io>",
+ "James Bowes <jbowes@repl.ca>",
+ "James Carr <james.r.carr@gmail.com>",
+ "James G. Kim <jgkim@jayg.org>",
+ "James Lal <james@lightsofapollo.com>",
+ "James Nylen <jnylen@gmail.com>",
+ "Jan Kopriva <jan.kopriva@gooddata.com>",
+ "Jan Krems <jan.krems@groupon.com>",
+ "Jan Lehnardt <jan@apache.org>",
+ "Jason Barry <jay@jcbarry.com>",
+ "Jason Lai <jason@getpebble.com>",
+ "Jason Leyba <jmleyba@gmail.com>",
+ "Javier Aranda <javierav@javierav.com>",
+ "Jean Ponchon <gelule@gmail.com>",
+ "Jeff Kunkle <jeff.kunkle@nearinfinity.com>",
+ "Jeff Schilling <jeff.schilling@q2ebanking.com>",
+ "JeongHoon Byun (aka Outsider) <outsideris@gmail.com>",
+ "Jérémie Astori <jeremie@astori.fr>",
+ "Jeremy Martin <jmar777@gmail.com>",
+ "Jerry Muzsik <jerrymuzsik@icloud.com>",
+ "Jesse Dailey <jesse.dailey@gmail.com>",
+ "jimenglish81 <jimenglish81@gmail.com>",
+ "Jimmy Cuadra <jimmy@jimmycuadra.com>",
+ "Jo Liss <joliss42@gmail.com>",
+ "Joao Moreno <mail@joaomoreno.com>",
+ "Joel Kemp <mrjoelkemp@gmail.com>",
+ "Joey Cozza <joey@grow.com>",
+ "John Doty <jrhdoty@gmail.com>",
+ "John Firebaugh <john.firebaugh@gmail.com>",
+ "John Reeves <github@jonnyreeves.co.uk>",
+ "Johnathon Sanders <outdooricon@gmail.com>",
+ "Jon Surrell <jon.surrell@automattic.com>",
+ "Jonas Dohse <jonas@mbr-targeting.com>",
+ "Jonas Westerlund <jonas.westerlund@me.com>",
+ "Jonathan Creamer <matrixhasyou2k4@gmail.com>",
+ "Jonathan Delgado <jdelgado@rewip.com>",
+ "Jonathan Kim <jkimbo@gmail.com>",
+ "Jonathan Ong <jonathanrichardong@gmail.com>",
+ "Jonathan Park <jpark@daptiv.com>",
+ "Jonathan Rajavuori <jrajav@gmail.com>",
+ "Jordan Sexton <jordan@jordansexton.com>",
+ "Joseph Lin <josephlin55555@gmail.com>",
+ "Josh Eversmann <josh.eversmann@gmail.com>",
+ "Josh Lory <josh.lory@code.org>",
+ "Josh Soref <jsoref@users.noreply.github.com>",
+ "Joshua Appelman <jappelman@xebia.com>",
+ "Joshua Krall <joshuakrall@pobox.com>",
+ "JP Bochi <jpbochi@gmail.com>",
+ "jsdevel <js.developer.undefined@gmail.com>",
+ "Julien Wajsberg <felash@gmail.com>",
+ "Jupp Müller <jupp0r@gmail.com>",
+ "Jussi Virtanen <jussi.k.virtanen@gmail.com>",
+ "Justin DuJardin <justin.dujardin@sococo.com>",
+ "Juzer Ali <er.juzerali@gmail.com>",
+ "Katie Gengler <katiegengler@gmail.com>",
+ "kavun <kevin.a.reed@gmail.com>",
+ "Kazuhito Hokamura <k.hokamura@gmail.com>",
+ "Keith Cirkel <github@keithcirkel.co.uk>",
+ "Kelong Wang <buaawkl@gmail.com>",
+ "Kent C. Dodds <kent+github@doddsfamily.us>",
+ "Kevin Burke <kev@inburke.com>",
+ "Kevin Conway <kevinjacobconway@gmail.com>",
+ "Kevin Kirsche <Kev.Kirsche+GitHub@gmail.com>",
+ "Kevin Partington <platinum.azure@kernelpanicstudios.com>",
+ "Kevin Wang <kevin@fossa.io>",
+ "Kirill Korolyov <kirill.korolyov@gmail.com>",
+ "klaemo <klaemo@fastmail.fm>",
+ "Koen Punt <koen@koenpunt.nl>",
+ "Konstantin Käfer <github@kkaefer.com>",
+ "Kris Rasmussen <kristopher.rasmussen@gmail.com>",
+ "Kunal Nagpal <kunagpal@users.noreply.github.com>",
+ "Kyle Mitchell <kyle@kemitchell.com>",
+ "lakmeer <lakmeerkravid@gmail.com>",
+ "Lane Kelly <lanekelly16@gmail.com>",
+ "László Bácsi <lackac@lackac.hu>",
+ "Laurence Rowe <lrowe@netflix.com>",
+ "Liam Newman <bitwiseman@gmail.com>",
+ "Linus Unnebäck <linus@folkdatorn.se>",
+ "lodr <salva@unoyunodiez.com>",
+ "Long Ho <longlho@users.noreply.github.com>",
+ "Maciej Małecki <maciej.malecki@notimplemented.org>",
+ "Mal Graty <mal.graty@googlemail.com>",
+ "Marais Rossouw <me@maraisr.com>",
+ "Marc Kuo <kuomarc2@gmail.com>",
+ "Marcello Bastea-Forte <marcello@cellosoft.com>",
+ "Mark Banner <standard8@mozilla.com>",
+ "Markus Tacker <m@coderbyheart.com>",
+ "Martin Marko <marcus@gratex.com>",
+ "Mathieu Desvé <mathieudesve@MacBook-Pro-de-Mathieu.local>",
+ "Matija Marohnić <matija.marohnic@gmail.com>",
+ "Matt Bierner <mattbierner@gmail.com>",
+ "Matt Giles <matt.giles@cerner.com>",
+ "Matt Robenolt <matt@ydekproductions.com>",
+ "Matt Smith <matthewgarysmith@gmail.com>",
+ "Matthew Shanley <matthewshanley@littlesecretsrecords.com>",
+ "Mattias Tidlund <mattias.tidlund@learningwell.se>",
+ "Max Goodman <c@chromakode.com>",
+ "Maximilian Antoni <mail@maxantoni.de>",
+ "Merrick Christensen <merrick.christensen@gmail.com>",
+ "Michael Demmer <demmer@jut.io>",
+ "Michael Jackson <mjijackson@gmail.com>",
+ "Michael Olson <mwolson@member.fsf.org>",
+ "Michael Riley <michael.riley@autodesk.com>",
+ "Michael Schoonmaker <michael.r.schoonmaker@gmail.com>",
+ "Michal Charemza <michalcharemza@gmail.com>",
+ "Michiel de Jong <michiel@unhosted.org>",
+ "Mick Brooks <mick.brooks@sinking.in>",
+ "Mike Pennisi <mike@mikepennisi.com>",
+ "Mislav Marohnić <mislav.marohnic@gmail.com>",
+ "monowerker <monowerker@gmail.com>",
+ "Moshe Kolodny <mkolodny@integralads.com>",
+ "mrShturman <mrshturman@gmail.com>",
+ "Nathan Alderson <nathan.alderson@adtran.com>",
+ "Nathan Black <nathan@nathanblack.org>",
+ "Nathan Bowser <nathan.bowser@spiderstrategies.com>",
+ "Nathan Houle <nathan@nathanhoule.com>",
+ "Nathan Rajlich <nathan@tootallnate.net>",
+ "nexdrew <andrew.goode@nextraq.com>",
+ "Nick Fitzgerald <fitzgen@gmail.com>",
+ "Nicolas Girault <nic.girault@gmail.com>",
+ "Nicolo Taddei <taddei.uk@gmail.com>",
+ "Nik Nyby <nnyby@columbia.edu>",
+ "Nikolaos Georgiou <Nikolaos.Georgiou@gmail.com>",
+ "nishigori <Takuya_Nishigori@voyagegroup.com>",
+ "Noshir Patel <nosh@blackpiano.com>",
+ "not-an-aardvark <not-an-aardvark@users.noreply.github.com>",
+ "OlegTsyba <oleg.tsyba.ua@gmail.com>",
+ "olsonpm <olsonpm@users.noreply.github.com>",
+ "omardelarosa <thedelarosa@gmail.com>",
+ "Oscar Godson <oscargodson@outlook.com>",
+ "Outsider <outsideris@gmail.com>",
+ "oveddan <stangogh@gmail.com>",
+ "Panu Horsmalahti <panu.horsmalahti@iki.fi>",
+ "Parker Moore <parkrmoore@gmail.com>",
+ "Pat Finnigan <patrick.k.finnigan@gmail.com>",
+ "Paul Armstrong <paul@paularmstrongdesigns.com>",
+ "Paul Miller <paul@paulmillr.com>",
+ "Pavel Zubkou <pavel.zubkou@gmail.com>",
+ "Pete Hawkins <pete@petes-imac.frontinternal.net>",
+ "Peter Müller <munter@fumle.dk>",
+ "Peter Rust <peter@cornerstonenw.com>",
+ "Phil Sung <psung@dnanexus.com>",
+ "Philip M. White <philip@mailworks.org>",
+ "PoppinL <poppinlp@gmail.com>",
+ "Poprádi Árpád <popradi.arpad11@gmail.com>",
+ "Prayag Verma <prayag.verma@gmail.com>",
+ "qiuzuhui <qiuzuhui@users.noreply.github.com>",
+ "Quang Van <quangvvv@gmail.com>",
+ "Quanlong He <kyan.ql.he@gmail.com>",
+ "R56 <rviskus@gmail.com>",
+ "Raynos <raynos2@gmail.com>",
+ "Refael Ackermann <refael@empeeric.com>",
+ "Rich Trott <rtrott@gmail.com>",
+ "Richard Dingwall <rdingwall@gmail.com>",
+ "Richard Knop <RichardKnop@users.noreply.github.com>",
+ "Rico Sta. Cruz <rstacruz@users.noreply.github.com>",
+ "rmacklin <richard.github@nrm.com>",
+ "Rob Loach <robloach@gmail.com>",
+ "Rob Raux <rraux@peachworks.com>",
+ "Rob Wu <rob@robwu.nl>",
+ "Robert Rossmann <rr.rossmann@me.com>",
+ "Romain Prieto <romain.prieto@gmail.com>",
+ "Roman Neuhauser <rneuhauser@suse.cz>",
+ "Roman Shtylman <shtylman@gmail.com>",
+ "Ross Warren <rosswarren4@gmail.com>",
+ "rotemdan <rotemdan@gmail.com>",
+ "Russ Bradberry <devdazed@me.com>",
+ "Russell Munson <rmunson@github.com>",
+ "Rustem Mustafin <mustafin.rustem@gmail.com>",
+ "Ryan Hubbard <ryanmhubbard@gmail.com>",
+ "Ryan Shaw <ryan.shaw@min.vc>",
+ "Ryan Tablada <ryan.tablada@gmail.com>",
+ "Ryunosuke SATO <tricknotes.rs@gmail.com>",
+ "ryym <ryym.64@gmail.com>",
+ "Salehen Shovon Rahman <salehen.rahman@gmail.com>",
+ "Sam Mussell <smussell@gmail.com>",
+ "samuel goldszmidt <samuel.goldszmidt@gmail.com>",
+ "sarehag <joakim.sarehag@gmail.com>",
+ "Sasha Koss <koss@nocorp.me>",
+ "Scott Kao <Scottkao85@users.noreply.github.com>",
+ "Scott Santucci <ScottFreeCode@users.noreply.github.com>",
+ "ScottFreeCode <ScottFreeCode@users.noreply.github.com>",
+ "Sean Lang <slang800@gmail.com>",
+ "Sebastian Van Sande <sebastian@vansande.org>",
+ "sebv <seb.vincent@gmail.com>",
+ "Seiya Konno <nulltask@gmail.com>",
+ "Sergey Simonchik <sergey.simonchik@jetbrains.com>",
+ "Sergio Santoro <santoro.srg@gmail.com>",
+ "Shaine Hatch <shaine@squidtree.com>",
+ "Shawn Krisman <telaviv@github>",
+ "Shinnosuke Watanabe <snnskwtnb@gmail.com>",
+ "silentcloud <rjmuqiang@gmail.com>",
+ "Silvio Massari <silvio.massari@auth0.com>",
+ "Simon Gaeremynck <gaeremyncks@gmail.com>",
+ "Simon Goumaz <simon@attentif.ch>",
+ "simov <simeonvelichkov@gmail.com>",
+ "Sindre Sorhus <sindresorhus@gmail.com>",
+ "Slobodan Mišković <slobodan@miskovic.ca>",
+ "slyg <syl.faucherand@gmail.com>",
+ "Soel <shachar.soel@sap.com>",
+ "solodynamo <bittuf3@gmail.com>",
+ "Sorin Iclanzan <sorin@iclanzan.com>",
+ "Standa Opichal <opichals@gmail.com>",
+ "startswithaj <jake.mc@icloud.com>",
+ "Stephen Mathieson <smath23@gmail.com>",
+ "Steve Mason <stevem@brandwatch.com>",
+ "Stewart Taylor <stewart.taylor1@gmail.com>",
+ "Stone <baoshi.li@adleida.com>",
+ "Sulabh Bista <sul4bh@gmail.com>",
+ "Sune Simonsen <sune@we-knowhow.dk>",
+ "Tapiwa Kelvin <tapiwa@munzwa.tk>",
+ "Ted Yavuzkurt <hello@TedY.io>",
+ "Teddy Zeenny <teddyzeenny@gmail.com>",
+ "tgautier@yahoo.com <tgautier@gmail.com>",
+ "Thedark1337 <thedark1337@thedark1337.com>",
+ "Thomas Broadley <buriedunderbooks@hotmail.com>",
+ "Thomas Grainger <tagrain@gmail.com>",
+ "Thomas Vantuycom <thomasvantuycom@protonmail.com>",
+ "Tim Ehat <timehat@gmail.com>",
+ "Timo Tijhof <krinklemail@gmail.com>",
+ "Timothy Gu <timothygu99@gmail.com>",
+ "Tingan Ho <tingan87@gmail.com>",
+ "tmont <tommy.mont@gmail.com>",
+ "Tobias Bieniek <tobias.bieniek@gmail.com>",
+ "Todd Agulnick <tagulnick@onjack.com>",
+ "Tom Coquereau <tom@thau.me>",
+ "Tom Hughes <tom@compton.nu>",
+ "Tomer Eskenazi <tomer.eskenazi@ironsrc.com>",
+ "traleig1 <darkphoenix739@gmail.com>",
+ "Travis Jeffery <tj@travisjeffery.com>",
+ "tripu <t@tripu.info>",
+ "Tyson Tate <tyson@tysontate.com>",
+ "Vadim Nikitin <vnikiti@ncsu.edu>",
+ "Valentin Agachi <github-com@agachi.name>",
+ "Valeri Karpov <val@karpov.io>",
+ "Victor <victor@turo.com>",
+ "Victor Costan <costan@gmail.com>",
+ "Ville Saukkonen <villesau@users.noreply.github.com>",
+ "Vivek Ganesan <caliberoviv@gmail.com>",
+ "vlad <iamvlad@gmail.com>",
+ "Vlad Magdalin <vlad@webflow.com>",
+ "Volker Buzek <volker.buzek@sap.com>",
+ "Wil Moore III <wil.moore@wilmoore.com>",
+ "Will Langstroth <will@langstroth.com>",
+ "wsw <wsw0108@gmail.com>",
+ "Xavier Antoviaque <xavier@antoviaque.org>",
+ "Xavier Damman <xdamman@gmail.com>",
+ "XhmikosR <xhmikosr@users.sourceforge.net>",
+ "Yanis Wang <yanis.wang@gmail.com>",
+ "yehiyam <yehiyam@users.noreply.github.com>",
+ "Yoshiya Hinosawa <hinosawa@waku-2.com>",
+ "Yuest Wang <yuestwang@gmail.com>",
+ "yuitest <yuitest@cjhat.net>",
+ "zhiyelee <zhiyelee@gmail.com>",
+ "Zsolt Takács <zsolt@takacs.cc>",
+ "现充 <qixiang.cqx@alibaba-inc.com>"
],
"license": "MIT",
"repository": {
@@ -303,49 +454,57 @@
"scripts": {
"prepublishOnly": "nps test clean build",
"start": "nps",
- "test": "nps test"
+ "test": "nps test",
+ "precommit": "lint-staged"
},
"dependencies": {
- "browser-stdout": "1.3.0",
- "commander": "2.11.0",
+ "browser-stdout": "1.3.1",
+ "commander": "2.15.1",
"debug": "3.1.0",
- "diff": "3.3.1",
+ "diff": "3.5.0",
"escape-string-regexp": "1.0.5",
"glob": "7.1.2",
- "growl": "1.10.3",
+ "growl": "1.10.5",
"he": "1.1.1",
+ "minimatch": "3.0.4",
"mkdirp": "0.5.1",
- "supports-color": "4.4.0"
+ "supports-color": "5.4.0"
},
"devDependencies": {
- "assert": "^1.4.1",
- "assetgraph-builder": "^5.6.4",
- "browserify": "^14.4.0",
+ "@mocha/docdash": "^1.0.1",
+ "assetgraph-builder": "^6.2.0",
+ "browserify": "^16.2.2",
+ "chai": "^4.1.2",
"coffee-script": "^1.10.0",
- "coveralls": "^3.0.0",
- "cross-spawn": "^5.1.0",
- "eslint": "^4.8.0",
- "eslint-config-semistandard": "^11.0.0",
- "eslint-config-standard": "^10.2.1",
- "eslint-plugin-import": "^2.7.0",
- "eslint-plugin-node": "^5.2.0",
- "eslint-plugin-promise": "^3.4.0",
+ "coveralls": "^3.0.1",
+ "cross-spawn": "^6.0.5",
+ "eslint": "^4.19.1",
+ "eslint-config-prettier": "^2.9.0",
+ "eslint-config-semistandard": "^12.0.1",
+ "eslint-config-standard": "^11.0.0",
+ "eslint-plugin-import": "^2.11.0",
+ "eslint-plugin-node": "^6.0.1",
+ "eslint-plugin-prettier": "^2.6.0",
+ "eslint-plugin-promise": "^3.7.0",
"eslint-plugin-standard": "^3.0.1",
- "expect.js": "^0.3.1",
- "karma": "^1.7.1",
+ "husky": "^0.14.3",
+ "jsdoc": "^3.5.5",
+ "karma": "^2.0.2",
"karma-browserify": "^5.0.5",
"karma-chrome-launcher": "^2.0.0",
- "karma-expect": "^1.1.2",
"karma-mocha": "^1.3.0",
"karma-mocha-reporter": "^2.2.4",
"karma-sauce-launcher": "^1.2.0",
+ "lint-staged": "^7.1.0",
"markdown-toc": "^1.2.0",
- "markdownlint-cli": "^0.6.0",
+ "markdownlint-cli": "^0.8.1",
"nps": "^5.7.1",
- "nyc": "^11.2.1",
+ "nyc": "^11.7.3",
+ "prettier-eslint-cli": "^4.7.1",
"rimraf": "^2.5.2",
- "svgo": "^0.7.2",
+ "svgo": "^1.0.5",
"through2": "^2.0.1",
+ "unexpected": "^10.37.7",
"watchify": "^3.7.0"
},
"files": [
@@ -367,5 +526,9 @@
"supports-color": false
},
"homepage": "https://mochajs.org",
- "logo": "https://cldup.com/S9uQ-cOLYz.svg"
+ "logo": "https://cldup.com/S9uQ-cOLYz.svg",
+ "prettier": {
+ "singleQuote": true,
+ "bracketSpacing": false
+ }
}

README.md

@@ -1,39 +1,3 @@
-# Mocha needs YOU!
-
-*Did you know* Mocha [is a dependency of over 100,000 projects](https://libraries.io/npm/mocha) published to npm alone?
-
-**Despite this, we're currently unable to merge most pull requests due to lack of maintenance resources.**
-
-**Are you interested in triaging issues or reviewing open PRs? Have some time to hack on its codebase?** If you would like to help maintain Mocha, please contact `@boneskull` on [Gitter](https://gitter.im/mochajs/mocha).
-
-*Thank you* :kissing_heart: to all of you interested in helping. These are Mocha's immediate needs:
-
-1. Increase test coverage on Node.js and browser
- - Increase integration coverage for all reporters
- - `html` reporter must be tested in browser
- - ~~Basic console reporters (*not* `nyan`, `landing`, etc.) must be tested in **both** browser and Node.js contexts~~
- - ~~Filesystem-based reporters must be tested in Node.js context~~
- - **UPDATE - May 24 2017**: Thanks to [community contributions](https://github.com/mochajs/mocha/blob/master/CHANGELOG.md#mag-coverage), the coverage on most reporters has increased dramatically! The `html` reporter is still in [dire need of coverage](https://coveralls.io/builds/11674428/source?filename=lib%2Freporters%2Fhtml.js).
- - Increase coverage against all interfaces (`exports` in particular). Ideally this becomes a "matrix" where we repeat sets of integration tests across all interfaces.
- - Refactor non-Node.js-specific tests to allow them to run in a browser context. Node.js-specific tests include those which *require* the CLI or filesystem. Most everything else is fair game.
-1. Review current open pull requests
- - We need individuals familiar with Mocha's codebase. Got questions? Ask them in [our chat room](https://gitter.im/mochajs/mocha).
- - Pull requests **must** have supporting tests. The only exceptions are pure cosmetic or non-functional changes.
- - Pull request contributors must sign [the CLA](https://cla.js.foundation/mochajs/mocha).
-1. Close old, inactive issues and pull requests
- - ~~A bot should do this. We need a bot. Got a bot?~~ We now use GitHub's own [probot-stale](https://www.npmjs.com/package/probot-stale).
-1. Triage issues
- - If we run into "critical" bugs, they need fixing.
- - "Critical" means Mocha is broken w/o workarounds for a *large percentage* of users
- - Otherwise: respond to issues, close new dupe issues, confirm bugs, ask for more info, etc.
-
-Once we gain ground on the above items, we can work together formalize our contribution guidelines and governance. For further info & ideas, please see our [projects](https://github.com/mochajs/mocha/projects/).
-
-*You needn't be a maintainer to submit a pull request for test coverage!*
-
-
-<br><br>
<p align="center">
<img src="https://cldup.com/xFVFxOioAU.svg" alt="Mocha test framework"/>
</p>
@@ -47,11 +11,12 @@
## Links
-- [Documentation](http://mochajs.org)
-- [Changelog](https://github.com/mochajs/mocha/blob/master/CHANGELOG.md)
-- [Google Group](http://groups.google.com/group/mochajs)
-- [Wiki](https://github.com/mochajs/mocha/wiki)
-- Mocha [Extensions and reporters](https://github.com/mochajs/mocha/wiki)
+- **[Documentation](https://mochajs.org)**
+- **[Release Notes / History / Changes](https://github.com/mochajs/mocha/blob/master/CHANGELOG.md)**
+- [Code of Conduct](https://github.com/mochajs/mocha/blob/master/.github/CODE_OF_CONDUCT.md)
+- [Gitter Chatroom](https://gitter.im/mochajs/mocha) (ask questions here!)
+- [Google Group](https://groups.google.com/group/mochajs)
+- [Issue Tracker](https://github.com/mochajs/mocha/issues)
## Backers
@@ -113,6 +78,25 @@
[![MochaJS Backer](https://opencollective.com/mochajs/sponsor/18/avatar)](https://opencollective.com/mochajs/sponsor/18/website)
[![MochaJS Backer](https://opencollective.com/mochajs/sponsor/19/avatar)](https://opencollective.com/mochajs/sponsor/19/website)
+## Development
+
+You might want to know that:
+
+- Mocha is the *most-depended-upon* module on npm (source: [libraries.io](https://libraries.io/search?order=desc&platforms=NPM&sort=dependents_count)), and
+- Mocha is an *independent* open-source project, maintained exclusively by volunteers.
+
+You might want to help:
+
+- New to contributing to Mocha? Check out this list of [good first issues](https://github.com/mochajs/mocha/issues?q=is%3Aissue+is%3Aopen+label%3Agood-first-issue)
+- Mocha could use a hand with [these issues](https://github.com/mochajs/mocha/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22)
+- The [maintainer's handbook](https://github.com/mochajs/mocha/blob/master/MAINTAINERS.md) explains how things get done
+
+Finally, come [chat with the maintainers](https://gitter.im/mochajs/contributors) on Gitter if you want to help with:
+
+- Triaging issues, answering questions
+- Review, merging, and closing pull requests
+- Other project-maintenance-y things
+
## License
[MIT](LICENSE)

README.md.orig

@@ -1,132 +0,0 @@
-# Mocha needs YOU!
-
-*Did you know* Mocha [is a dependency of over 100,000 projects](https://libraries.io/npm/mocha) published to npm alone?
-
-**Despite this, we're currently unable to merge most pull requests due to lack of maintenance resources.**
-
-**Are you interested in triaging issues or reviewing open PRs? Have some time to hack on its codebase?** If you would like to help maintain Mocha, please contact `@boneskull` on [Gitter](https://gitter.im/mochajs/mocha).
-
-*Thank you* :kissing_heart: to all of you interested in helping. These are Mocha's immediate needs:
-
-1. Increase test coverage on Node.js and browser
- - Increase integration coverage for all reporters
- - `html` reporter must be tested in browser
- - ~~Basic console reporters (*not* `nyan`, `landing`, etc.) must be tested in **both** browser and Node.js contexts; PhantomJS can consume all console reporters~~
- - ~~Filesystem-based reporters must be tested in Node.js context~~
- - **UPDATE - May 24 2017**: Thanks to [community contributions](https://github.com/mochajs/mocha/blob/master/CHANGELOG.md#mag-coverage), the coverage on most reporters has increased dramatically! The `html` reporter is still in [dire need of coverage](https://coveralls.io/builds/11674428/source?filename=lib%2Freporters%2Fhtml.js).
- - Increase coverage against all interfaces (`exports` in particular). Ideally this becomes a "matrix" where we repeat sets of integration tests across all interfaces.
- - Refactor non-Node.js-specific tests to allow them to run in a browser context. Node.js-specific tests include those which *require* the CLI or filesystem. Most everything else is fair game.
-1. Review current open pull requests
- - We need individuals familiar with Mocha's codebase. Got questions? Ask them in [our chat room](https://gitter.im/mochajs/mocha).
- - Pull requests **must** have supporting tests. The only exceptions are pure cosmetic or non-functional changes.
- - Pull request contributors must sign [the CLA](https://cla.js.foundation/mochajs/mocha).
-1. Close old, inactive issues and pull requests
- - ~~A bot should do this. We need a bot. Got a bot?~~ We now use GitHub's own [probot-stale](https://www.npmjs.com/package/probot-stale).
-1. Triage issues
- - If we run into "critical" bugs, they need fixing.
- - "Critical" means Mocha is broken w/o workarounds for a *large percentage* of users
- - Otherwise: respond to issues, close new dupe issues, confirm bugs, ask for more info, etc.
-
-Once we gain ground on the above items, we can work together formalize our contribution guidelines and governance. For further info & ideas, please see our [projects](https://github.com/mochajs/mocha/projects/).
-
-*You needn't be a maintainer to submit a pull request for test coverage!*
-
-
-<br><br>
-<p align="center">
- <img src="https://cldup.com/xFVFxOioAU.svg" alt="Mocha test framework"/>
-</p>
-
-<p align="center">:coffee: Simple, flexible, fun JavaScript test framework for Node.js & The Browser :coffee:</p>
-
-<<<<<<< HEAD
-<p align="center"><a href="http://travis-ci.org/mochajs/mocha"><img src="https://api.travis-ci.org/mochajs/mocha.svg?branch=master" alt="Build Status"></a> <a href="https://coveralls.io/github/mochajs/mocha"><img src="https://coveralls.io/repos/github/mochajs/mocha/badge.svg" alt="Coverage Status"></a> <a href="https://app.fossa.io/projects/git%2Bhttps%3A%2F%2Fgithub.com%2Fmochajs%2Fmocha?ref=badge_shield"><img src="https://app.fossa.io/api/projects/git%2Bhttps%3A%2F%2Fgithub.com%2Fmochajs%2Fmocha.svg?type=shield" alt="FOSSA Status"></a> <a href="https://gitter.im/mochajs/mocha?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge"><img src="https://badges.gitter.im/Join%20Chat.svg" alt="Gitter"></a> <a href="https://github.com/mochajs/mocha#backers"><img src="https://opencollective.com/mochajs/backers/badge.svg" alt="OpenCollective"></a> <a href="https://github.com/mochajs/mocha#sponsors"><img src="https://opencollective.com/mochajs/sponsors/badge.svg" alt="OpenCollective"></a>
-</p>
-
-<p align="center"><br><img alt="Mocha Browser Support h/t SauceLabs" src="https://saucelabs.com/browser-matrix/mochajs.svg" width="354"></p>
-
-## Links
-
- - [Documentation](http://mochajs.org)
- - [Changelog](https://github.com/mochajs/mocha/blob/master/CHANGELOG.md)
- - [Google Group](http://groups.google.com/group/mochajs)
- - [Wiki](https://github.com/mochajs/mocha/wiki)
- - Mocha [Extensions and reporters](https://github.com/mochajs/mocha/wiki)
-
-=======
-Mocha is a simple, flexible, fun JavaScript test framework for node.js and the browser. For more information view the [documentation](http://mochajs.org).
-
-## Links
-
-- [Changelog](https://github.com/mochajs/mocha/blob/master/CHANGELOG.md)
-- [Google Group](http://groups.google.com/group/mochajs)
-- [Wiki](https://github.com/mochajs/mocha/wiki)
-- Mocha [Extensions and reporters](https://github.com/mochajs/mocha/wiki)
->>>>>>> lint all markdown files [ci skip]
-
-## Backers
-
-[Become a backer](https://opencollective.com/mochajs#backer) and show your support to our open source project.
-
-[![MochaJS Backer](https://opencollective.com/mochajs/backer/0/avatar)](https://opencollective.com/mochajs/backer/0/website)
-[![MochaJS Backer](https://opencollective.com/mochajs/backer/1/avatar)](https://opencollective.com/mochajs/backer/1/website)
-[![MochaJS Backer](https://opencollective.com/mochajs/backer/2/avatar)](https://opencollective.com/mochajs/backer/2/website)
-[![MochaJS Backer](https://opencollective.com/mochajs/backer/3/avatar)](https://opencollective.com/mochajs/backer/3/website)
-[![MochaJS Backer](https://opencollective.com/mochajs/backer/4/avatar)](https://opencollective.com/mochajs/backer/4/website)
-[![MochaJS Backer](https://opencollective.com/mochajs/backer/5/avatar)](https://opencollective.com/mochajs/backer/5/website)
-[![MochaJS Backer](https://opencollective.com/mochajs/backer/6/avatar)](https://opencollective.com/mochajs/backer/6/website)
-[![MochaJS Backer](https://opencollective.com/mochajs/backer/7/avatar)](https://opencollective.com/mochajs/backer/7/website)
-[![MochaJS Backer](https://opencollective.com/mochajs/backer/8/avatar)](https://opencollective.com/mochajs/backer/8/website)
-[![MochaJS Backer](https://opencollective.com/mochajs/backer/9/avatar)](https://opencollective.com/mochajs/backer/9/website)
-[![MochaJS Backer](https://opencollective.com/mochajs/backer/10/avatar)](https://opencollective.com/mochajs/backer/10/website)
-[![MochaJS Backer](https://opencollective.com/mochajs/backer/11/avatar)](https://opencollective.com/mochajs/backer/11/website)
-[![MochaJS Backer](https://opencollective.com/mochajs/backer/12/avatar)](https://opencollective.com/mochajs/backer/12/website)
-[![MochaJS Backer](https://opencollective.com/mochajs/backer/13/avatar)](https://opencollective.com/mochajs/backer/13/website)
-[![MochaJS Backer](https://opencollective.com/mochajs/backer/14/avatar)](https://opencollective.com/mochajs/backer/14/website)
-[![MochaJS Backer](https://opencollective.com/mochajs/backer/15/avatar)](https://opencollective.com/mochajs/backer/15/website)
-[![MochaJS Backer](https://opencollective.com/mochajs/backer/16/avatar)](https://opencollective.com/mochajs/backer/16/website)
-[![MochaJS Backer](https://opencollective.com/mochajs/backer/17/avatar)](https://opencollective.com/mochajs/backer/17/website)
-[![MochaJS Backer](https://opencollective.com/mochajs/backer/18/avatar)](https://opencollective.com/mochajs/backer/18/website)
-[![MochaJS Backer](https://opencollective.com/mochajs/backer/19/avatar)](https://opencollective.com/mochajs/backer/19/website)
-[![MochaJS Backer](https://opencollective.com/mochajs/backer/20/avatar)](https://opencollective.com/mochajs/backer/20/website)
-[![MochaJS Backer](https://opencollective.com/mochajs/backer/21/avatar)](https://opencollective.com/mochajs/backer/21/website)
-[![MochaJS Backer](https://opencollective.com/mochajs/backer/22/avatar)](https://opencollective.com/mochajs/backer/22/website)
-[![MochaJS Backer](https://opencollective.com/mochajs/backer/23/avatar)](https://opencollective.com/mochajs/backer/23/website)
-[![MochaJS Backer](https://opencollective.com/mochajs/backer/24/avatar)](https://opencollective.com/mochajs/backer/24/website)
-[![MochaJS Backer](https://opencollective.com/mochajs/backer/25/avatar)](https://opencollective.com/mochajs/backer/25/website)
-[![MochaJS Backer](https://opencollective.com/mochajs/backer/26/avatar)](https://opencollective.com/mochajs/backer/26/website)
-[![MochaJS Backer](https://opencollective.com/mochajs/backer/27/avatar)](https://opencollective.com/mochajs/backer/27/website)
-[![MochaJS Backer](https://opencollective.com/mochajs/backer/28/avatar)](https://opencollective.com/mochajs/backer/28/website)
-[![MochaJS Backer](https://opencollective.com/mochajs/backer/29/avatar)](https://opencollective.com/mochajs/backer/29/website)
-
-## Sponsors
-
-Does your company use Mocha? Ask your manager or marketing team if your company would be interested in supporting our project. Support will allow the maintainers to dedicate more time for maintenance and new features for everyone. Also, your company's logo will show [on GitHub](https://github.com/mochajs/mocha#readme) and on [our site](https://mochajs.org) - who doesn't want a little extra exposure? [Here's the info](https://opencollective.com/mochajs#sponsor).
-
-[![MochaJS Backer](https://opencollective.com/mochajs/sponsor/0/avatar)](https://opencollective.com/mochajs/sponsor/0/website)
-[![MochaJS Backer](https://opencollective.com/mochajs/sponsor/1/avatar)](https://opencollective.com/mochajs/sponsor/1/website)
-[![MochaJS Backer](https://opencollective.com/mochajs/sponsor/2/avatar)](https://opencollective.com/mochajs/sponsor/2/website)
-[![MochaJS Backer](https://opencollective.com/mochajs/sponsor/3/avatar)](https://opencollective.com/mochajs/sponsor/3/website)
-[![MochaJS Backer](https://opencollective.com/mochajs/sponsor/4/avatar)](https://opencollective.com/mochajs/sponsor/4/website)
-[![MochaJS Backer](https://opencollective.com/mochajs/sponsor/5/avatar)](https://opencollective.com/mochajs/sponsor/5/website)
-[![MochaJS Backer](https://opencollective.com/mochajs/sponsor/6/avatar)](https://opencollective.com/mochajs/sponsor/6/website)
-[![MochaJS Backer](https://opencollective.com/mochajs/sponsor/7/avatar)](https://opencollective.com/mochajs/sponsor/7/website)
-[![MochaJS Backer](https://opencollective.com/mochajs/sponsor/8/avatar)](https://opencollective.com/mochajs/sponsor/8/website)
-[![MochaJS Backer](https://opencollective.com/mochajs/sponsor/9/avatar)](https://opencollective.com/mochajs/sponsor/9/website)
-[![MochaJS Backer](https://opencollective.com/mochajs/sponsor/10/avatar)](https://opencollective.com/mochajs/sponsor/10/website)
-[![MochaJS Backer](https://opencollective.com/mochajs/sponsor/11/avatar)](https://opencollective.com/mochajs/sponsor/11/website)
-[![MochaJS Backer](https://opencollective.com/mochajs/sponsor/12/avatar)](https://opencollective.com/mochajs/sponsor/12/website)
-[![MochaJS Backer](https://opencollective.com/mochajs/sponsor/13/avatar)](https://opencollective.com/mochajs/sponsor/13/website)
-[![MochaJS Backer](https://opencollective.com/mochajs/sponsor/14/avatar)](https://opencollective.com/mochajs/sponsor/14/website)
-[![MochaJS Backer](https://opencollective.com/mochajs/sponsor/15/avatar)](https://opencollective.com/mochajs/sponsor/15/website)
-[![MochaJS Backer](https://opencollective.com/mochajs/sponsor/16/avatar)](https://opencollective.com/mochajs/sponsor/16/website)
-[![MochaJS Backer](https://opencollective.com/mochajs/sponsor/17/avatar)](https://opencollective.com/mochajs/sponsor/17/website)
-[![MochaJS Backer](https://opencollective.com/mochajs/sponsor/18/avatar)](https://opencollective.com/mochajs/sponsor/18/website)
-[![MochaJS Backer](https://opencollective.com/mochajs/sponsor/19/avatar)](https://opencollective.com/mochajs/sponsor/19/website)
-
-## License
-
-[MIT](LICENSE)
-
-[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bhttps%3A%2F%2Fgithub.com%2Fmochajs%2Fmocha.svg?type=large)](https://app.fossa.io/projects/git%2Bhttps%3A%2F%2Fgithub.com%2Fmochajs%2Fmocha?ref=badge_large)