mocha 8.0.0 → 8.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,71 @@
1
+ # 8.1.2 / 2020-08-25
2
+
3
+ ## :bug: Fixes
4
+
5
+ - [#4418](https://github.com/mochajs/mocha/issues/4418): Fix command-line flag incompatibility in forthcoming Node.js v14.9.0 ([**@boneskull**](https://github.com/boneskull))
6
+ - [#4401](https://github.com/mochajs/mocha/issues/4401): Fix missing global variable in browser ([**@irrationelle**](https://github.com/irrationelle))
7
+
8
+ ## :lock: Security Fixes
9
+
10
+ - [#4396](https://github.com/mochajs/mocha/issues/4396): Update many dependencies ([**@GChuf**](https://github.com/GChuf))
11
+
12
+ ## :book: Documentation
13
+
14
+ - Various fixes by [**@sujin-park**](https://github.com/sujin-park), [**@wwhurin**](https://github.com/wwhurin) & [**@Donghoon759**](https://github.com/Donghoon759)
15
+
16
+ # 8.1.1 / 2020-08-04
17
+
18
+ ## :bug: Fixes
19
+
20
+ - [#4394](https://github.com/mochajs/mocha/issues/4394): Fix regression wherein certain reporters did not correctly detect terminal width ([**@boneskull**](https://github.com/boneskull))
21
+
22
+ # 8.1.0 / 2020-07-30
23
+
24
+ In this release, Mocha now builds its browser bundle with Rollup and Babel, which will provide the project's codebase more flexibility and consistency.
25
+
26
+ While we've been diligent about backwards compatibility, it's _possible_ consumers of the browser bundle will encounter differences (other than an increase in the bundle size). If you _do_ encounter an issue with the build, please [report it here](https://github.com/mochajs/mocha/issues/new?labels=unconfirmed-bug&template=bug_report.md&title=).
27
+
28
+ This release **does not** drop support for IE11.
29
+
30
+ Other community contributions came from [**@Devjeel**](https://github.com/Devjeel), [**@Harsha509**](https://github.com/Harsha509) and [**@sharath2106**](https://github.com/sharath2106). _Thank you_ to everyone who contributed to this release!
31
+
32
+ > Do you read Korean? See [this guide to running parallel tests in Mocha](https://blog.outsider.ne.kr/1489), translated by our maintainer, [**@outsideris**](https://github.com/outsideris).
33
+
34
+ ## :tada: Enhancements
35
+
36
+ - [#4287](https://github.com/mochajs/mocha/issues/4287): Use background colors with inline diffs for better visual distinction ([**@michael-brade**](https://github.com/michael-brade))
37
+
38
+ ## :bug: Fixes
39
+
40
+ - [#4328](https://github.com/mochajs/mocha/issues/4328): Fix "watch" mode when Mocha run in parallel ([**@boneskull**](https://github.com/boneskull))
41
+ - [#4382](https://github.com/mochajs/mocha/issues/4382): Fix root hook execution in "watch" mode ([**@indieisaconcept**](https://github.com/indieisaconcept))
42
+ - [#4383](https://github.com/mochajs/mocha/issues/4383): Consistent auto-generated hook titles ([**@cspotcode**](https://github.com/cspotcode))
43
+ - [#4359](https://github.com/mochajs/mocha/issues/4359): Better errors when running `mocha init` ([**@boneskull**](https://github.com/boneskull))
44
+ - [#4341](https://github.com/mochajs/mocha/issues/4341): Fix weirdness when using `delay` option in browser ([**@craigtaub**](https://github.com/craigtaub))
45
+
46
+ ## :lock: Security Fixes
47
+
48
+ - [#4378](https://github.com/mochajs/mocha/issues/4378), [#4333](https://github.com/mochajs/mocha/issues/4333): Update [javascript-serialize](https://npm.im/javascript-serialize) ([**@martinoppitz**](https://github.com/martinoppitz), [**@wnghdcjfe**](https://github.com/wnghdcjfe))
49
+ - [#4354](https://github.com/mochajs/mocha/issues/4354): Update [yargs-unparser](https://npm.im/yargs-unparser) ([**@martinoppitz**](https://github.com/martinoppitz))
50
+
51
+ ## :book: Documentation & Website
52
+
53
+ - [#4173](https://github.com/mochajs/mocha/issues/4173): Document how to use `--enable-source-maps` with Mocha ([**@bcoe**](https://github.com/bcoe))
54
+ - [#4343](https://github.com/mochajs/mocha/issues/4343): Clean up some API docs ([**@craigtaub**](https://github.com/craigtaub))
55
+ - [#4318](https://github.com/mochajs/mocha/issues/4318): Sponsor images are now self-hosted ([**@Munter**](https://github.com/Munter))
56
+
57
+ ## :nut_and_bolt: Other
58
+
59
+ - [#4293](https://github.com/mochajs/mocha/issues/4293): Use Rollup and Babel in build pipeline; add source map to published files ([**@Munter**](https://github.com/Munter))
60
+
61
+ # 8.0.1 / 2020-06-10
62
+
63
+ The obligatory patch after a major.
64
+
65
+ ## :bug: Fixes
66
+
67
+ - [#4328](https://github.com/mochajs/mocha/issues/4328): Fix `--parallel` when combined with `--watch` ([**@boneskull**](https://github.com/boneskull))
68
+
1
69
  # 8.0.0 / 2020-06-10
2
70
 
3
71
  In this major release, Mocha adds the ability to _run tests in parallel_. Better late than never! Please note the **breaking changes** detailed below.
@@ -6,7 +74,7 @@ Let's welcome [**@giltayar**](https://github.com/giltayar) and [**@nicojs**](htt
6
74
 
7
75
  ## :boom: Breaking Changes
8
76
 
9
- - [#4164](https://github.com/mochajs/mocha/issues/4164): **Mocha v8.0.0 now requires Node.js v10.0.0 or newer.** Mocha no longer supports the Node.js v8.x line ("Carbon"), which entered End-of-Life at the end of 2019 ([**@UlisesGascon**](https://github.com/UlisesGascon))
77
+ - [#4164](https://github.com/mochajs/mocha/issues/4164): **Mocha v8.0.0 now requires Node.js v10.12.0 or newer.** Mocha no longer supports the Node.js v8.x line ("Carbon"), which entered End-of-Life at the end of 2019 ([**@UlisesGascon**](https://github.com/UlisesGascon))
10
78
 
11
79
  - [#4175](https://github.com/mochajs/mocha/issues/4175): Having been deprecated with a warning since v7.0.0, **`mocha.opts` is no longer supported** ([**@juergba**](https://github.com/juergba))
12
80
 
@@ -27,6 +95,7 @@ Let's welcome [**@giltayar**](https://github.com/giltayar) and [**@nicojs**](htt
27
95
  - [#4223](https://github.com/mochajs/mocha/issues/4223): The context object's `skip()` (`this.skip()`) in a "before all" (`before()`) hook will no longer execute subsequent sibling hooks, in addition to hooks in child suites ([**@juergba**](https://github.com/juergba))
28
96
 
29
97
  - [#4178](https://github.com/mochajs/mocha/issues/4178): Remove previously soft-deprecated APIs ([**@wnghdcjfe**](https://github.com/wnghdcjfe)):
98
+
30
99
  - `Mocha.prototype.ignoreLeaks()`
31
100
  - `Mocha.prototype.useColors()`
32
101
  - `Mocha.prototype.useInlineDiffs()`
@@ -46,6 +115,10 @@ Let's welcome [**@giltayar**](https://github.com/giltayar) and [**@nicojs**](htt
46
115
 
47
116
  - [#4246](https://github.com/mochajs/mocha/issues/4246): Add documentation for parallel mode and Root Hook plugins ([**@boneskull**](https://github.com/boneskull))
48
117
 
118
+ ## :nut_and_bolt: Other
119
+
120
+ - [#4200](https://github.com/mochajs/mocha/issues/4200): Drop mkdirp and replace it with fs.mkdirSync ([**@HyunSangHan**](https://github.com/HyunSangHan))
121
+
49
122
  ## :bug: Fixes
50
123
 
51
124
  (All bug fixes in Mocha v8.0.0 are also breaking changes, and are listed above)
package/browser-entry.js CHANGED
@@ -9,6 +9,8 @@
9
9
 
10
10
  process.stdout = require('browser-stdout')({label: false});
11
11
 
12
+ var parseQuery = require('./lib/browser/parse-query');
13
+ var highlightTags = require('./lib/browser/highlight-tags');
12
14
  var Mocha = require('./lib/mocha');
13
15
 
14
16
  /**
@@ -77,6 +79,13 @@ process.on = function(e, fn) {
77
79
  }
78
80
  };
79
81
 
82
+ process.listeners = function(e) {
83
+ if (e === 'uncaughtException') {
84
+ return uncaughtExceptionHandlers;
85
+ }
86
+ return [];
87
+ };
88
+
80
89
  // The BDD UI is registered by default, but no UI will be functional in the
81
90
  // browser without an explicit call to the overridden `mocha.ui` (see below).
82
91
  // Ensure that this default UI does not expose its methods to the global scope.
@@ -139,11 +148,19 @@ mocha.setup = function(opts) {
139
148
  if (typeof opts === 'string') {
140
149
  opts = {ui: opts};
141
150
  }
142
- for (var opt in opts) {
143
- if (Object.prototype.hasOwnProperty.call(opts, opt)) {
144
- this[opt](opts[opt]);
145
- }
151
+ if (opts.delay === true) {
152
+ this.delay();
146
153
  }
154
+ var self = this;
155
+ Object.keys(opts)
156
+ .filter(function(opt) {
157
+ return opt !== 'delay';
158
+ })
159
+ .forEach(function(opt) {
160
+ if (Object.prototype.hasOwnProperty.call(opts, opt)) {
161
+ self[opt](opts[opt]);
162
+ }
163
+ });
147
164
  return this;
148
165
  };
149
166
 
@@ -155,7 +172,7 @@ mocha.run = function(fn) {
155
172
  var options = mocha.options;
156
173
  mocha.globals('location');
157
174
 
158
- var query = Mocha.utils.parseQuery(global.location.search || '');
175
+ var query = parseQuery(global.location.search || '');
159
176
  if (query.grep) {
160
177
  mocha.grep(query.grep);
161
178
  }
@@ -174,7 +191,7 @@ mocha.run = function(fn) {
174
191
  document.getElementById('mocha') &&
175
192
  options.noHighlighting !== true
176
193
  ) {
177
- Mocha.utils.highlightTags('code');
194
+ highlightTags('code');
178
195
  }
179
196
  if (fn) {
180
197
  fn(err);
@@ -199,4 +216,4 @@ global.mocha = mocha;
199
216
  // this allows test/acceptance/required-tokens.js to pass; thus,
200
217
  // you can now do `const describe = require('mocha').describe` in a
201
218
  // browser context (assuming browserification). should fix #880
202
- module.exports = global;
219
+ module.exports = Object.assign(mocha, global);
@@ -0,0 +1,39 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * Highlight the given string of `js`.
5
+ *
6
+ * @private
7
+ * @param {string} js
8
+ * @return {string}
9
+ */
10
+ function highlight(js) {
11
+ return js
12
+ .replace(/</g, '&lt;')
13
+ .replace(/>/g, '&gt;')
14
+ .replace(/\/\/(.*)/gm, '<span class="comment">//$1</span>')
15
+ .replace(/('.*?')/gm, '<span class="string">$1</span>')
16
+ .replace(/(\d+\.\d+)/gm, '<span class="number">$1</span>')
17
+ .replace(/(\d+)/gm, '<span class="number">$1</span>')
18
+ .replace(
19
+ /\bnew[ \t]+(\w+)/gm,
20
+ '<span class="keyword">new</span> <span class="init">$1</span>'
21
+ )
22
+ .replace(
23
+ /\b(function|new|throw|return|var|if|else)\b/gm,
24
+ '<span class="keyword">$1</span>'
25
+ );
26
+ }
27
+
28
+ /**
29
+ * Highlight the contents of tag `name`.
30
+ *
31
+ * @private
32
+ * @param {string} name
33
+ */
34
+ module.exports = function highlightTags(name) {
35
+ var code = document.getElementById('mocha').getElementsByTagName(name);
36
+ for (var i = 0, len = code.length; i < len; ++i) {
37
+ code[i].innerHTML = highlight(code[i].innerHTML);
38
+ }
39
+ };
@@ -0,0 +1,24 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * Parse the given `qs`.
5
+ *
6
+ * @private
7
+ * @param {string} qs
8
+ * @return {Object<string, string>}
9
+ */
10
+ module.exports = function parseQuery(qs) {
11
+ return qs
12
+ .replace('?', '')
13
+ .split('&')
14
+ .reduce(function(obj, pair) {
15
+ var i = pair.indexOf('=');
16
+ var key = pair.slice(0, i);
17
+ var val = pair.slice(++i);
18
+
19
+ // Due to how the URLSearchParams API treats spaces
20
+ obj[key] = decodeURIComponent(val.replace(/\+/g, '%20'));
21
+
22
+ return obj;
23
+ }, {});
24
+ };
@@ -1,5 +1,9 @@
1
1
  'use strict';
2
2
 
3
+ /**
4
+ @module browser/Progress
5
+ */
6
+
3
7
  /**
4
8
  * Expose `Progress`.
5
9
  */
@@ -1,16 +1,18 @@
1
1
  <!DOCTYPE html>
2
2
  <html lang="en">
3
3
  <head>
4
- <meta charset="utf-8">
4
+ <meta charset="utf-8" />
5
5
  <title>Mocha</title>
6
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
- <link rel="stylesheet" href="mocha.css">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
+ <link rel="stylesheet" href="mocha.css" />
8
8
  </head>
9
9
  <body>
10
10
  <div id="mocha"></div>
11
11
  <script src="mocha.js"></script>
12
- <script>mocha.setup('bdd');</script>
13
- <script src="tests.js"></script>
12
+ <script>
13
+ mocha.setup('bdd');
14
+ </script>
15
+ <script src="tests.spec.js"></script>
14
16
  <script>
15
17
  mocha.run();
16
18
  </script>
package/lib/cli/cli.js CHANGED
@@ -52,7 +52,7 @@ exports.main = (argv = process.argv.slice(2)) => {
52
52
  debug('caught error sometime before command handler: %O', err);
53
53
  yargs.showHelp();
54
54
  console.error(`\n${symbols.error} ${ansi.red('ERROR:')} ${msg}`);
55
- yargs.exit(1);
55
+ process.exitCode = 1;
56
56
  })
57
57
  .help('help', 'Show usage information & exit')
58
58
  .alias('help', 'h')
@@ -4,8 +4,8 @@ const path = require('path');
4
4
  const ansi = require('ansi-colors');
5
5
  const debug = require('debug')('mocha:cli:run:helpers');
6
6
  const minimatch = require('minimatch');
7
- const utils = require('../utils');
8
7
  const {NO_FILES_MATCH_PATTERN} = require('../errors').constants;
8
+ const lookupFiles = require('./lookup-files');
9
9
 
10
10
  /**
11
11
  * Exports a function that collects test files from CLI parameters.
@@ -27,7 +27,7 @@ module.exports = ({ignore, extension, file, recursive, sort, spec} = {}) => {
27
27
  spec.forEach(arg => {
28
28
  let newFiles;
29
29
  try {
30
- newFiles = utils.lookupFiles(arg, extension, recursive);
30
+ newFiles = lookupFiles(arg, extension, recursive);
31
31
  } catch (err) {
32
32
  if (err.code === NO_FILES_MATCH_PATTERN) {
33
33
  unmatched.push({message: err.message, pattern: err.pattern});
@@ -81,6 +81,7 @@ module.exports = ({ignore, extension, file, recursive, sort, spec} = {}) => {
81
81
 
82
82
  /**
83
83
  * An object to configure how Mocha gathers test files
84
+ * @private
84
85
  * @typedef {Object} FileCollectionOptions
85
86
  * @property {string[]} extension - File extensions to use
86
87
  * @property {string[]} spec - Files, dirs, globs to run
@@ -0,0 +1,145 @@
1
+ 'use strict';
2
+
3
+ var fs = require('fs');
4
+ var path = require('path');
5
+ var glob = require('glob');
6
+ var {format} = require('util');
7
+ var errors = require('../errors');
8
+ var createNoFilesMatchPatternError = errors.createNoFilesMatchPatternError;
9
+ var createMissingArgumentError = errors.createMissingArgumentError;
10
+ var {sQuote, dQuote} = require('../utils');
11
+
12
+ /**
13
+ * Determines if pathname would be a "hidden" file (or directory) on UN*X.
14
+ *
15
+ * @description
16
+ * On UN*X, pathnames beginning with a full stop (aka dot) are hidden during
17
+ * typical usage. Dotfiles, plain-text configuration files, are prime examples.
18
+ *
19
+ * @see {@link http://xahlee.info/UnixResource_dir/writ/unix_origin_of_dot_filename.html|Origin of Dot File Names}
20
+ *
21
+ * @private
22
+ * @param {string} pathname - Pathname to check for match.
23
+ * @return {boolean} whether pathname would be considered a hidden file.
24
+ * @example
25
+ * isHiddenOnUnix('.profile'); // => true
26
+ */
27
+ function isHiddenOnUnix(pathname) {
28
+ return path.basename(pathname)[0] === '.';
29
+ }
30
+
31
+ /**
32
+ * Determines if pathname has a matching file extension.
33
+ *
34
+ * @private
35
+ * @param {string} pathname - Pathname to check for match.
36
+ * @param {string[]} exts - List of file extensions (sans period).
37
+ * @return {boolean} whether file extension matches.
38
+ * @example
39
+ * hasMatchingExtname('foo.html', ['js', 'css']); // => false
40
+ */
41
+ function hasMatchingExtname(pathname, exts) {
42
+ var suffix = path.extname(pathname).slice(1);
43
+ return exts.some(function(element) {
44
+ return suffix === element;
45
+ });
46
+ }
47
+
48
+ /**
49
+ * Lookup file names at the given `path`.
50
+ *
51
+ * @description
52
+ * Filenames are returned in _traversal_ order by the OS/filesystem.
53
+ * **Make no assumption that the names will be sorted in any fashion.**
54
+ *
55
+ * @public
56
+ * @memberof Mocha.utils
57
+ * @param {string} filepath - Base path to start searching from.
58
+ * @param {string[]} [extensions=[]] - File extensions to look for.
59
+ * @param {boolean} [recursive=false] - Whether to recurse into subdirectories.
60
+ * @return {string[]} An array of paths.
61
+ * @throws {Error} if no files match pattern.
62
+ * @throws {TypeError} if `filepath` is directory and `extensions` not provided.
63
+ */
64
+ module.exports = function lookupFiles(filepath, extensions, recursive) {
65
+ extensions = extensions || [];
66
+ recursive = recursive || false;
67
+ var files = [];
68
+ var stat;
69
+
70
+ if (!fs.existsSync(filepath)) {
71
+ var pattern;
72
+ if (glob.hasMagic(filepath)) {
73
+ // Handle glob as is without extensions
74
+ pattern = filepath;
75
+ } else {
76
+ // glob pattern e.g. 'filepath+(.js|.ts)'
77
+ var strExtensions = extensions
78
+ .map(function(v) {
79
+ return '.' + v;
80
+ })
81
+ .join('|');
82
+ pattern = filepath + '+(' + strExtensions + ')';
83
+ }
84
+ files = glob.sync(pattern, {nodir: true});
85
+ if (!files.length) {
86
+ throw createNoFilesMatchPatternError(
87
+ 'Cannot find any files matching pattern ' + dQuote(filepath),
88
+ filepath
89
+ );
90
+ }
91
+ return files;
92
+ }
93
+
94
+ // Handle file
95
+ try {
96
+ stat = fs.statSync(filepath);
97
+ if (stat.isFile()) {
98
+ return filepath;
99
+ }
100
+ } catch (err) {
101
+ // ignore error
102
+ return;
103
+ }
104
+
105
+ // Handle directory
106
+ fs.readdirSync(filepath).forEach(function(dirent) {
107
+ var pathname = path.join(filepath, dirent);
108
+ var stat;
109
+
110
+ try {
111
+ stat = fs.statSync(pathname);
112
+ if (stat.isDirectory()) {
113
+ if (recursive) {
114
+ files = files.concat(lookupFiles(pathname, extensions, recursive));
115
+ }
116
+ return;
117
+ }
118
+ } catch (err) {
119
+ // ignore error
120
+ return;
121
+ }
122
+ if (!extensions.length) {
123
+ throw createMissingArgumentError(
124
+ format(
125
+ 'Argument %s required when argument %s is a directory',
126
+ sQuote('extensions'),
127
+ sQuote('filepath')
128
+ ),
129
+ 'extensions',
130
+ 'array'
131
+ );
132
+ }
133
+
134
+ if (
135
+ !stat.isFile() ||
136
+ !hasMatchingExtname(pathname, extensions) ||
137
+ isHiddenOnUnix(pathname)
138
+ ) {
139
+ return;
140
+ }
141
+ files.push(pathname);
142
+ });
143
+
144
+ return files;
145
+ };
@@ -7,6 +7,7 @@
7
7
  */
8
8
 
9
9
  const nodeFlags = process.allowedNodeEnvironmentFlags;
10
+ const {isMochaFlag} = require('./run-option-metadata');
10
11
  const unparse = require('yargs-unparser');
11
12
 
12
13
  /**
@@ -43,16 +44,14 @@ exports.isNodeFlag = (flag, bareword = true) => {
43
44
  flag = flag.replace(/^--?/, '');
44
45
  }
45
46
  return (
46
- // treat --require/-r as Mocha flag even though it's also a node flag
47
- !(flag === 'require' || flag === 'r') &&
48
47
  // check actual node flags from `process.allowedNodeEnvironmentFlags`,
49
48
  // then historical support for various V8 and non-`NODE_OPTIONS` flags
50
49
  // and also any V8 flags with `--v8-` prefix
51
- ((nodeFlags && nodeFlags.has(flag)) ||
52
- debugFlags.has(flag) ||
53
- /(?:preserve-symlinks(?:-main)?|harmony(?:[_-]|$)|(?:trace[_-].+$)|gc(?:[_-]global)?$|es[_-]staging$|use[_-]strict$|v8[_-](?!options).+?$)/.test(
54
- flag
55
- ))
50
+ (!isMochaFlag(flag) && nodeFlags && nodeFlags.has(flag)) ||
51
+ debugFlags.has(flag) ||
52
+ /(?:preserve-symlinks(?:-main)?|harmony(?:[_-]|$)|(?:trace[_-].+$)|gc(?:[_-]global)?$|es[_-]staging$|use[_-]strict$|v8[_-](?!options).+?$)/.test(
53
+ flag
54
+ )
56
55
  );
57
56
  };
58
57
 
@@ -12,7 +12,7 @@
12
12
  * @type {{string:string[]}}
13
13
  * @private
14
14
  */
15
- exports.types = {
15
+ const TYPES = (exports.types = {
16
16
  array: [
17
17
  'extension',
18
18
  'file',
@@ -58,7 +58,7 @@ exports.types = {
58
58
  'slow',
59
59
  'timeout'
60
60
  ]
61
- };
61
+ });
62
62
 
63
63
  /**
64
64
  * Option aliases keyed by canonical option name.
@@ -88,3 +88,26 @@ exports.aliases = {
88
88
  ui: ['u'],
89
89
  watch: ['w']
90
90
  };
91
+
92
+ const ALL_MOCHA_FLAGS = Object.keys(TYPES).reduce((acc, key) => {
93
+ // gets all flags from each of the fields in `types`, adds those,
94
+ // then adds aliases of each flag (if any)
95
+ TYPES[key].forEach(flag => {
96
+ acc.add(flag);
97
+ const aliases = exports.aliases[flag] || [];
98
+ aliases.forEach(alias => {
99
+ acc.add(alias);
100
+ });
101
+ });
102
+ return acc;
103
+ }, new Set());
104
+
105
+ /**
106
+ * Returns `true` if the provided `flag` is known to Mocha.
107
+ * @param {string} flag - Flag to check
108
+ * @returns {boolean} If `true`, this is a Mocha flag
109
+ * @private
110
+ */
111
+ exports.isMochaFlag = flag => {
112
+ return ALL_MOCHA_FLAGS.has(flag.replace(/^--?/, ''));
113
+ };
@@ -19,7 +19,7 @@ const collectFiles = require('./collect-files');
19
19
  * @param {Object} opts - Options
20
20
  * @param {string[]} [opts.watchFiles] - List of paths and patterns to
21
21
  * watch. If not provided all files with an extension included in
22
- * `fileColletionParams.extension` are watched. See first argument of
22
+ * `fileCollectionParams.extension` are watched. See first argument of
23
23
  * `chokidar.watch`.
24
24
  * @param {string[]} opts.watchIgnore - List of paths and patterns to
25
25
  * exclude from watching. See `ignored` option of `chokidar`.
@@ -36,11 +36,37 @@ exports.watchParallelRun = (
36
36
  watchFiles,
37
37
  watchIgnore,
38
38
  beforeRun({mocha}) {
39
- mocha.files = collectFiles(fileCollectParams);
39
+ // I don't know why we're cloning the root suite.
40
+ const rootSuite = mocha.suite.clone();
41
+
42
+ // this `require` is needed because the require cache has been cleared. the dynamic
43
+ // exports set via the below call to `mocha.ui()` won't work properly if a
44
+ // test depends on this module (see `required-tokens.spec.js`).
45
+ const Mocha = require('../mocha');
46
+
47
+ // ... and now that we've gotten a new module, we need to use it again due
48
+ // to `mocha.ui()` call
49
+ const newMocha = new Mocha(mocha.options);
50
+ // don't know why this is needed
51
+ newMocha.suite = rootSuite;
52
+ // nor this
53
+ newMocha.suite.ctx = new Context();
54
+
55
+ // reset the list of files
56
+ newMocha.files = collectFiles(fileCollectParams);
57
+
58
+ // because we've swapped out the root suite (see the `run` inner function
59
+ // in `createRerunner`), we need to call `mocha.ui()` again to set up the context/globals.
60
+ newMocha.ui(newMocha.options.ui);
61
+
62
+ // we need to call `newMocha.rootHooks` to set up rootHooks for the new
63
+ // suite
64
+ newMocha.rootHooks(newMocha.options.rootHooks);
65
+
40
66
  // in parallel mode, the main Mocha process doesn't actually load the
41
67
  // files. this flag prevents `mocha.run()` from autoloading.
42
- mocha.lazyLoadFiles(true);
43
- return mocha;
68
+ newMocha.lazyLoadFiles(true);
69
+ return newMocha;
44
70
  },
45
71
  afterRun({watcher}) {
46
72
  blastCache(watcher);
@@ -55,7 +81,7 @@ exports.watchParallelRun = (
55
81
  * @param {Object} opts - Options
56
82
  * @param {string[]} [opts.watchFiles] - List of paths and patterns to
57
83
  * watch. If not provided all files with an extension included in
58
- * `fileColletionParams.extension` are watched. See first argument of
84
+ * `fileCollectionParams.extension` are watched. See first argument of
59
85
  * `chokidar.watch`.
60
86
  * @param {string[]} opts.watchIgnore - List of paths and patterns to
61
87
  * exclude from watching. See `ignored` option of `chokidar`.
@@ -96,6 +122,10 @@ exports.watchRun = (mocha, {watchFiles, watchIgnore}, fileCollectParams) => {
96
122
  // in `createRerunner`), we need to call `mocha.ui()` again to set up the context/globals.
97
123
  newMocha.ui(newMocha.options.ui);
98
124
 
125
+ // we need to call `newMocha.rootHooks` to set up rootHooks for the new
126
+ // suite
127
+ newMocha.rootHooks(newMocha.options.rootHooks);
128
+
99
129
  return newMocha;
100
130
  },
101
131
  afterRun({watcher}) {
@@ -114,7 +144,7 @@ exports.watchRun = (mocha, {watchFiles, watchIgnore}, fileCollectParams) => {
114
144
  * @param {AfterWatchRun} [opts.afterRun] - Function to call after `mocha.run()`
115
145
  * @param {string[]} [opts.watchFiles] - List of paths and patterns to watch. If
116
146
  * not provided all files with an extension included in
117
- * `fileColletionParams.extension` are watched. See first argument of
147
+ * `fileCollectionParams.extension` are watched. See first argument of
118
148
  * `chokidar.watch`.
119
149
  * @param {string[]} [opts.watchIgnore] - List of paths and patterns to exclude
120
150
  * from watching. See `ignored` option of `chokidar`.
package/lib/errors.js CHANGED
@@ -59,12 +59,12 @@ var constants = {
59
59
  UNSUPPORTED: 'ERR_MOCHA_UNSUPPORTED',
60
60
 
61
61
  /**
62
- * Invalid state transition occuring in `Mocha` instance
62
+ * Invalid state transition occurring in `Mocha` instance
63
63
  */
64
64
  INSTANCE_ALREADY_RUNNING: 'ERR_MOCHA_INSTANCE_ALREADY_RUNNING',
65
65
 
66
66
  /**
67
- * Invalid state transition occuring in `Mocha` instance
67
+ * Invalid state transition occurring in `Mocha` instance
68
68
  */
69
69
  INSTANCE_ALREADY_DISPOSED: 'ERR_MOCHA_INSTANCE_ALREADY_DISPOSED',
70
70
 
@@ -1,5 +1,9 @@
1
1
  'use strict';
2
2
 
3
+ /**
4
+ @module interfaces/common
5
+ */
6
+
3
7
  var Suite = require('../suite');
4
8
  var errors = require('../errors');
5
9
  var createMissingArgumentError = errors.createMissingArgumentError;
@@ -9,6 +13,7 @@ var createForbiddenExclusivityError = errors.createForbiddenExclusivityError;
9
13
  /**
10
14
  * Functions common to more than one interface.
11
15
  *
16
+ * @private
12
17
  * @param {Suite[]} suites
13
18
  * @param {Context} context
14
19
  * @param {Mocha} mocha