mocha 6.0.0-1 → 6.0.0

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,41 @@
1
+ # 6.0.0 / 2019-02-18
2
+
3
+ ## :tada: Enhancements
4
+
5
+ - [#3726](https://github.com/mochajs/mocha/issues/3726): Add ability to unload files from `require` cache ([**@plroebuck**](https://github.com/plroebuck))
6
+
7
+ ## :bug: Fixes
8
+
9
+ - [#3737](https://github.com/mochajs/mocha/issues/3737): Fix falsy values from options globals ([**@plroebuck**](https://github.com/plroebuck))
10
+ - [#3707](https://github.com/mochajs/mocha/issues/3707): Fix encapsulation issues for `Suite#_onlyTests` and `Suite#_onlySuites` ([**@vkarpov15**](https://github.com/vkarpov15))
11
+ - [#3711](https://github.com/mochajs/mocha/issues/3711): Fix diagnostic messages dealing with plurality and markup of output ([**@plroebuck**](https://github.com/plroebuck))
12
+ - [#3723](https://github.com/mochajs/mocha/issues/3723): Fix "reporter-option" to allow comma-separated options ([**@boneskull**](https://github.com/boneskull))
13
+ - [#3722](https://github.com/mochajs/mocha/issues/3722): Fix code quality and performance of `lookupFiles` and `files` ([**@plroebuck**](https://github.com/plroebuck))
14
+ - [#3650](https://github.com/mochajs/mocha/issues/3650), [#3654](https://github.com/mochajs/mocha/issues/3654): Fix noisy error message when no files found ([**@craigtaub**](https://github.com/craigtaub))
15
+ - [#3632](https://github.com/mochajs/mocha/issues/3632): Tests having an empty title are no longer confused with the "root" suite ([**@juergba**](https://github.com/juergba))
16
+ - [#3666](https://github.com/mochajs/mocha/issues/3666): Fix missing error codes ([**@vkarpov15**](https://github.com/vkarpov15))
17
+ - [#3684](https://github.com/mochajs/mocha/issues/3684): Fix exiting problem in Node.js v11.7.0+ ([**@addaleax**](https://github.com/addaleax))
18
+ - [#3691](https://github.com/mochajs/mocha/issues/3691): Fix `--delay` (and other boolean options) not working in all cases ([**@boneskull**](https://github.com/boneskull))
19
+ - [#3692](https://github.com/mochajs/mocha/issues/3692): Fix invalid command-line argument usage not causing actual errors ([**@boneskull**](https://github.com/boneskull))
20
+ - [#3698](https://github.com/mochajs/mocha/issues/3698), [#3699](https://github.com/mochajs/mocha/issues/3699): Fix debug-related Node.js options not working in all cases ([**@boneskull**](https://github.com/boneskull))
21
+ - [#3700](https://github.com/mochajs/mocha/issues/3700): Growl notifications now show the correct number of tests run ([**@outsideris**](https://github.com/outsideris))
22
+ - [#3686](https://github.com/mochajs/mocha/issues/3686): Avoid potential ReDoS when diffing large objects ([**@cyjake**](https://github.com/cyjake))
23
+ - [#3715](https://github.com/mochajs/mocha/issues/3715): Fix incorrect order of emitted events when used programmatically ([**@boneskull**](https://github.com/boneskull))
24
+ - [#3706](https://github.com/mochajs/mocha/issues/3706): Fix regression wherein `--reporter-option`/`--reporter-options` did not support comma-separated key/value pairs ([**@boneskull**](https://github.com/boneskull))
25
+
26
+ ## :book: Documentation
27
+
28
+ - [#3652](https://github.com/mochajs/mocha/issues/3652): Switch from Jekyll to Eleventy ([**@Munter**](https://github.com/Munter))
29
+
30
+ ## :nut_and_bolt: Other
31
+
32
+ - [#3677](https://github.com/mochajs/mocha/issues/3677): Add error objects for createUnsupportedError and createInvalidExceptionError ([**@boneskull**](https://github.com/boneskull))
33
+ - [#3733](https://github.com/mochajs/mocha/issues/3733): Removed unnecessary processing in post-processing hook ([**@wanseob**](https://github.com/wanseob))
34
+ - [#3730](https://github.com/mochajs/mocha/issues/3730): Update nyc to latest version ([**@coreyfarrell**](https://github.com/coreyfarrell))
35
+ - [#3648](https://github.com/mochajs/mocha/issues/3648), [#3680](https://github.com/mochajs/mocha/issues/3680): Fixes to support latest versions of [unexpected](https://npm.im/unexpected) and [unexpected-sinon](https://npm.im/unexpected-sinon) ([**@sunesimonsen**](https://github.com/sunesimonsen))
36
+ - [#3638](https://github.com/mochajs/mocha/issues/3638): Add meta tag to site ([**@MartijnCuppens**](https://github.com/MartijnCuppens))
37
+ - [#3653](https://github.com/mochajs/mocha/issues/3653): Fix parts of test suite failing to run on Windows ([**@boneskull**](https://github.com/boneskull))
38
+
1
39
  # 6.0.0-1 / 2019-01-02
2
40
 
3
41
  ## :bug: Fixes
package/bin/mocha CHANGED
@@ -9,71 +9,78 @@
9
9
  * @private
10
10
  */
11
11
 
12
- const {deprecate} = require('../lib/utils');
12
+ const {deprecate, warn} = require('../lib/utils');
13
13
  const {spawn} = require('child_process');
14
14
  const {loadOptions} = require('../lib/cli/options');
15
- const {isNodeFlag, impliesNoTimeouts} = require('../lib/cli/node-flags');
15
+ const {
16
+ unparseNodeFlags,
17
+ isNodeFlag,
18
+ impliesNoTimeouts
19
+ } = require('../lib/cli/node-flags');
16
20
  const unparse = require('yargs-unparser');
17
- const debug = require('debug')('mocha:cli');
21
+ const debug = require('debug')('mocha:cli:mocha');
18
22
  const {aliases} = require('../lib/cli/run-option-metadata');
23
+ const nodeEnv = require('node-environment-flags');
19
24
 
20
25
  const mochaPath = require.resolve('./_mocha');
21
- const childOpts = {};
22
- const nodeOpts = {};
26
+ const mochaArgs = {};
27
+ const nodeArgs = {};
23
28
 
24
29
  const opts = loadOptions(process.argv.slice(2));
25
30
  debug('loaded opts', opts);
26
31
 
32
+ /**
33
+ * Given option/command `value`, disable timeouts if applicable
34
+ * @param {string} [value] - Value to check
35
+ * @ignore
36
+ */
37
+ const disableTimeouts = value => {
38
+ if (impliesNoTimeouts(value)) {
39
+ debug(`option "${value}" disabled timeouts`);
40
+ mochaArgs.timeout = 0;
41
+ delete mochaArgs.timeouts;
42
+ delete mochaArgs.t;
43
+ }
44
+ };
45
+
46
+ /**
47
+ * If `value` begins with `v8-` and is not explicitly `v8-options`, remove prefix
48
+ * @param {string} [value] - Value to check
49
+ * @returns {string} `value` with prefix (maybe) removed
50
+ * @ignore
51
+ */
52
+ const trimV8Option = value =>
53
+ value !== 'v8-options' && /^v8-/.test(value) ? value.slice(3) : value;
54
+
55
+ // sort options into "node" and "mocha" buckets
27
56
  Object.keys(opts).forEach(opt => {
28
57
  if (isNodeFlag(opt)) {
29
- if (/^v8-/.test(opt)) {
30
- opt = opt.slice(2);
31
- }
32
- nodeOpts[opt] = opts[opt];
33
- if (impliesNoTimeouts(opt)) {
34
- debug(`option "${opt}" disabled timeouts`);
35
- childOpts.timeout = false;
36
- }
58
+ nodeArgs[trimV8Option(opt)] = opts[opt];
59
+ disableTimeouts(opt);
37
60
  } else {
38
- childOpts[opt] = opts[opt];
61
+ mochaArgs[opt] = opts[opt];
39
62
  }
40
63
  });
41
64
 
42
- // allow --debug to invoke --inspect on Node.js v8 or newer nodeOpts.inspect = childOpts.debug;
43
- if (childOpts.debug) {
44
- childOpts.timeout = false;
45
- delete childOpts.debug;
46
- debug('--debug -> --inspect');
47
- } else if (childOpts['debug-brk']) {
48
- nodeOpts['inspect-brk'] = childOpts['debug-brk'];
49
- childOpts.timeout = false;
50
- delete childOpts['debug-brk'];
51
- debug('--debug-brk -> --inspect-brk');
52
- }
53
-
54
- // historical
55
- if (nodeOpts.gc) {
56
- deprecate(
57
- '"-gc" is deprecated and will be removed from a future version of Mocha. Use "--gc-global" instead.'
58
- );
59
- nodeOpts['gc-global'] = nodeOpts.gc;
60
- delete nodeOpts.gc;
61
- }
62
-
63
65
  // Native debugger handling
64
66
  // see https://nodejs.org/api/debugger.html#debugger_debugger
65
67
  // look for 'debug' or 'inspect' that would launch this debugger,
66
68
  // remove it from Mocha's opts and prepend it to Node's opts.
67
69
  // also coerce depending on Node.js version.
68
- if (/^(debug|inspect)$/.test(childOpts._[0])) {
69
- childOpts.timeout = false;
70
- childOpts._.shift();
70
+ // A deprecation warning will be printed by node, if applicable.
71
+ // (mochaArgs._ are "positional" arguments, not prefixed with - or --)
72
+ if (/^(debug|inspect)$/.test(mochaArgs._[0])) {
73
+ const command = mochaArgs._.shift();
74
+ disableTimeouts(command);
71
75
  // don't conflict with inspector
72
- delete nodeOpts['debug'];
73
- delete nodeOpts['inspect'];
74
- delete nodeOpts['debug-brk'];
75
- delete nodeOpts['inspect-brk'];
76
- nodeOpts._ = [
76
+ ['debug', 'inspect', 'debug-brk', 'inspect-brk']
77
+ .filter(opt => opt in nodeArgs || opt in mochaArgs)
78
+ .forEach(opt => {
79
+ warn(`command "${command}" provided; --${opt} ignored`);
80
+ delete nodeArgs[opt];
81
+ delete mochaArgs[opt];
82
+ });
83
+ nodeArgs._ = [
77
84
  parseInt(
78
85
  process.version
79
86
  .slice(1)
@@ -86,10 +93,37 @@ if (/^(debug|inspect)$/.test(childOpts._[0])) {
86
93
  ];
87
94
  }
88
95
 
96
+ // allow --debug to invoke --inspect on Node.js v8 or newer.
97
+ ['debug', 'debug-brk']
98
+ .filter(opt => opt in nodeArgs && !nodeEnv.has(opt))
99
+ .forEach(opt => {
100
+ const newOpt = opt === 'debug' ? 'inspect' : 'inspect-brk';
101
+ warn(
102
+ `"--${opt}" is not available in Node.js ${
103
+ process.version
104
+ }; use "--${newOpt}" instead.`
105
+ );
106
+ nodeArgs[newOpt] = nodeArgs[opt];
107
+ mochaArgs.timeout = false;
108
+ debug(`--${opt} -> ${newOpt}`);
109
+ delete nodeArgs[opt];
110
+ });
111
+
112
+ // historical
113
+ if (nodeArgs.gc) {
114
+ deprecate(
115
+ '"-gc" is deprecated and will be removed from a future version of Mocha. Use "--gc-global" instead.'
116
+ );
117
+ nodeArgs['gc-global'] = nodeArgs.gc;
118
+ delete nodeArgs.gc;
119
+ }
120
+
121
+ debug('final node args', nodeArgs);
122
+
89
123
  const args = [].concat(
90
- unparse(nodeOpts),
124
+ unparseNodeFlags(nodeArgs),
91
125
  mochaPath,
92
- unparse(childOpts, {alias: aliases})
126
+ unparse(mochaArgs, {alias: aliases})
93
127
  );
94
128
 
95
129
  debug(`exec ${process.execPath} w/ args:`, args);
@@ -10,6 +10,7 @@
10
10
  */
11
11
  var Date = global.Date;
12
12
  var setTimeout = global.setTimeout;
13
+ var EVENT_RUN_END = require('../runner').constants.EVENT_RUN_END;
13
14
 
14
15
  /**
15
16
  * Checks if browser notification support exists.
@@ -53,7 +54,7 @@ exports.notify = function(runner) {
53
54
  .catch(notPermitted);
54
55
  };
55
56
 
56
- runner.once('end', sendNotification);
57
+ runner.once(EVENT_RUN_END, sendNotification);
57
58
  };
58
59
 
59
60
  /**
@@ -129,7 +130,7 @@ function display(runner) {
129
130
  var title;
130
131
 
131
132
  if (stats.failures) {
132
- _message = stats.failures + ' of ' + runner.total + ' tests failed';
133
+ _message = stats.failures + ' of ' + stats.tests + ' tests failed';
133
134
  message = symbol.cross + ' ' + _message;
134
135
  title = 'Failed';
135
136
  } else {
@@ -7,6 +7,7 @@
7
7
  */
8
8
 
9
9
  const nodeFlags = require('node-environment-flags');
10
+ const unparse = require('yargs-unparser');
10
11
 
11
12
  /**
12
13
  * These flags are considered "debug" flags.
@@ -34,6 +35,7 @@ const debugFlags = new Set(['debug', 'debug-brk', 'inspect', 'inspect-brk']);
34
35
  exports.isNodeFlag = flag =>
35
36
  !/^(?:require|r)$/.test(flag) &&
36
37
  (nodeFlags.has(flag) ||
38
+ debugFlags.has(flag) ||
37
39
  /(?:preserve-symlinks(?:-main)?|harmony(?:[_-]|$)|(?:trace[_-].+$)|gc(?:[_-]global)?$|es[_-]staging$|use[_-]strict$|v8[_-](?!options).+?$)/.test(
38
40
  flag
39
41
  ));
@@ -46,3 +48,22 @@ exports.isNodeFlag = flag =>
46
48
  * @private
47
49
  */
48
50
  exports.impliesNoTimeouts = flag => debugFlags.has(flag);
51
+
52
+ /**
53
+ * All non-strictly-boolean arguments to node--those with values--must specify those values using `=`, e.g., `--inspect=0.0.0.0`.
54
+ * Unparse these arguments using `yargs-unparser` (which would result in `--inspect 0.0.0.0`), then supply `=` where we have values.
55
+ * There's probably an easier or more robust way to do this; fixes welcome
56
+ * @param {Object} opts - Arguments object
57
+ * @returns {string[]} Unparsed arguments using `=` to specify values
58
+ * @private
59
+ */
60
+ exports.unparseNodeFlags = opts => {
61
+ var args = unparse(opts);
62
+ return args.length
63
+ ? args
64
+ .join(' ')
65
+ .split(/\b/)
66
+ .map(arg => (arg === ' ' ? '=' : arg))
67
+ .join('')
68
+ : [];
69
+ };
@@ -17,6 +17,8 @@ const {loadConfig, findConfig} = require('./config');
17
17
  const findup = require('findup-sync');
18
18
  const {deprecate} = require('../utils');
19
19
  const debug = require('debug')('mocha:cli:options');
20
+ const {createMissingArgumentError} = require('../errors');
21
+ const {isNodeFlag} = require('./node-flags');
20
22
 
21
23
  /**
22
24
  * The `yargs-parser` namespace
@@ -73,21 +75,50 @@ const nargOpts = types.array
73
75
  * @private
74
76
  * @ignore
75
77
  */
76
- const parse = (args = [], ...configObjects) =>
77
- yargsParser(
78
- args,
79
- Object.assign(
80
- {
81
- configuration,
82
- configObjects,
83
- coerce: coerceOpts,
84
- narg: nargOpts,
85
- alias: aliases
86
- },
87
- types
88
- )
78
+ const parse = (args = [], ...configObjects) => {
79
+ // save node-specific args for special handling.
80
+ // 1. when these args have a "=" they should be considered to have values
81
+ // 2. if they don't, they just boolean flags
82
+ // 3. to avoid explicitly defining the set of them, we tell yargs-parser they
83
+ // are ALL boolean flags.
84
+ // 4. we can then reapply the values after yargs-parser is done.
85
+ const nodeArgs = (Array.isArray(args) ? args : args.split(' ')).reduce(
86
+ (acc, arg) => {
87
+ const pair = arg.split('=');
88
+ const flag = pair[0].replace(/^--?/, '');
89
+ if (isNodeFlag(flag)) {
90
+ return arg.includes('=')
91
+ ? acc.concat([[flag, pair[1]]])
92
+ : acc.concat([[flag, true]]);
93
+ }
94
+ return acc;
95
+ },
96
+ []
89
97
  );
90
98
 
99
+ const result = yargsParser.detailed(args, {
100
+ configuration,
101
+ configObjects,
102
+ coerce: coerceOpts,
103
+ narg: nargOpts,
104
+ alias: aliases,
105
+ string: types.string,
106
+ array: types.array,
107
+ number: types.number,
108
+ boolean: types.boolean.concat(nodeArgs.map(pair => pair[0]))
109
+ });
110
+ if (result.error) {
111
+ throw createMissingArgumentError(result.error.message);
112
+ }
113
+
114
+ // reapply "=" arg values from above
115
+ nodeArgs.forEach(([key, value]) => {
116
+ result.argv[key] = value;
117
+ });
118
+
119
+ return result.argv;
120
+ };
121
+
91
122
  /**
92
123
  * - Replaces comments with empty strings
93
124
  * - Replaces escaped spaces (e.g., 'xxx\ yyy') with HTML space
@@ -8,13 +8,13 @@
8
8
  */
9
9
 
10
10
  const fs = require('fs');
11
+ const path = require('path');
12
+ const ansi = require('ansi-colors');
11
13
  const debug = require('debug')('mocha:cli:run:helpers');
14
+ const minimatch = require('minimatch');
12
15
  const Context = require('../context');
13
- const path = require('path');
16
+ const Mocha = require('../mocha');
14
17
  const utils = require('../utils');
15
- const minimatch = require('minimatch');
16
- const ansi = require('ansi-colors');
17
- const symbols = require('log-symbols');
18
18
 
19
19
  const cwd = (exports.cwd = process.cwd());
20
20
 
@@ -26,7 +26,7 @@ const cwd = (exports.cwd = process.cwd());
26
26
  */
27
27
  const exitMochaLater = code => {
28
28
  process.on('exit', () => {
29
- process.exit(Math.min(code, 255));
29
+ process.exitCode = Math.min(code, 255);
30
30
  });
31
31
  };
32
32
 
@@ -138,13 +138,14 @@ exports.handleFiles = ({
138
138
  spec = []
139
139
  } = {}) => {
140
140
  let files = [];
141
+ const unmatched = [];
141
142
  spec.forEach(arg => {
142
143
  let newFiles;
143
144
  try {
144
145
  newFiles = utils.lookupFiles(arg, extension, recursive);
145
146
  } catch (err) {
146
147
  if (err.code === 'ERR_MOCHA_NO_FILES_MATCH_PATTERN') {
147
- console.warn('Warning: %s: %O', err.message, err.pattern);
148
+ unmatched.push({message: err.message, pattern: err.pattern});
148
149
  return;
149
150
  }
150
151
 
@@ -164,8 +165,18 @@ exports.handleFiles = ({
164
165
  });
165
166
 
166
167
  if (!files.length) {
167
- console.error(ansi.red(`${symbols.error} No test files found`));
168
+ // give full message details when only 1 file is missing
169
+ const noneFoundMsg =
170
+ unmatched.length === 1
171
+ ? `Error: No test files found: ${JSON.stringify(unmatched[0].pattern)}` // stringify to print escaped characters raw
172
+ : 'Error: No test files found';
173
+ console.error(ansi.red(noneFoundMsg));
168
174
  process.exit(1);
175
+ } else {
176
+ // print messages as an warning
177
+ unmatched.forEach(warning => {
178
+ console.warn(ansi.yellow(`Warning: ${warning.message}`));
179
+ });
169
180
  }
170
181
 
171
182
  const fileArgs = file.map(filepath => path.resolve(filepath));
@@ -239,9 +250,7 @@ exports.watchRun = (
239
250
  };
240
251
 
241
252
  const purge = () => {
242
- watchFiles.forEach(file => {
243
- delete require.cache[file];
244
- });
253
+ watchFiles.forEach(Mocha.unloadFile);
245
254
  };
246
255
 
247
256
  loadAndRun();
@@ -28,6 +28,7 @@ exports.types = {
28
28
  'bail',
29
29
  'check-leaks',
30
30
  'color',
31
+ 'delay',
31
32
  'diff',
32
33
  'exit',
33
34
  'forbid-only',
@@ -35,9 +36,12 @@ exports.types = {
35
36
  'full-trace',
36
37
  'growl',
37
38
  'inline-diffs',
39
+ 'interfaces',
38
40
  'invert',
39
41
  'no-colors',
40
42
  'recursive',
43
+ 'reporters',
44
+ 'sort',
41
45
  'watch'
42
46
  ],
43
47
  number: ['retries', 'slow', 'timeout'],
package/lib/cli/run.js CHANGED
@@ -8,9 +8,11 @@
8
8
  */
9
9
 
10
10
  const Mocha = require('../mocha');
11
- const ansi = require('ansi-colors');
12
- const errors = require('../errors');
13
- const createInvalidArgumentValueError = errors.createInvalidArgumentValueError;
11
+ const {
12
+ createUnsupportedError,
13
+ createInvalidArgumentValueError,
14
+ createMissingArgumentError
15
+ } = require('../errors');
14
16
 
15
17
  const {
16
18
  list,
@@ -188,7 +190,7 @@ exports.builder = yargs =>
188
190
  },
189
191
  'reporter-option': {
190
192
  coerce: opts =>
191
- opts.reduce((acc, opt) => {
193
+ list(opts).reduce((acc, opt) => {
192
194
  const pair = opt.split('=');
193
195
 
194
196
  if (pair.length > 2 || !pair.length) {
@@ -258,15 +260,17 @@ exports.builder = yargs =>
258
260
 
259
261
  // yargs.implies() isn't flexible enough to handle this
260
262
  if (argv.invert && !('fgrep' in argv || 'grep' in argv)) {
261
- throw new Error(
262
- '"--invert" requires one of "--fgrep <str>" or "--grep <regexp>"'
263
+ throw createMissingArgumentError(
264
+ '"--invert" requires one of "--fgrep <str>" or "--grep <regexp>"',
265
+ '--fgrep|--grep',
266
+ 'string|regexp'
263
267
  );
264
268
  }
265
269
 
266
270
  if (argv.compilers) {
267
- throw new Error(
271
+ throw createUnsupportedError(
268
272
  `--compilers is DEPRECATED and no longer supported.
269
- See ${ansi.cyan('https://git.io/vdcSr')} for migration information.`
273
+ See https://git.io/vdcSr for migration information.`
270
274
  );
271
275
  }
272
276
 
package/lib/errors.js CHANGED
@@ -7,7 +7,7 @@
7
7
  */
8
8
 
9
9
  /**
10
- * Creates an error object used when no files to be tested could be found using specified pattern.
10
+ * Creates an error object to be thrown when no files to be tested could be found using specified pattern.
11
11
  *
12
12
  * @public
13
13
  * @param {string} message - Error message to be displayed.
@@ -22,7 +22,7 @@ function createNoFilesMatchPatternError(message, pattern) {
22
22
  }
23
23
 
24
24
  /**
25
- * Creates an error object used when the reporter specified in the options was not found.
25
+ * Creates an error object to be thrown when the reporter specified in the options was not found.
26
26
  *
27
27
  * @public
28
28
  * @param {string} message - Error message to be displayed.
@@ -37,7 +37,7 @@ function createInvalidReporterError(message, reporter) {
37
37
  }
38
38
 
39
39
  /**
40
- * Creates an error object used when the interface specified in the options was not found.
40
+ * Creates an error object to be thrown when the interface specified in the options was not found.
41
41
  *
42
42
  * @public
43
43
  * @param {string} message - Error message to be displayed.
@@ -52,20 +52,20 @@ function createInvalidInterfaceError(message, ui) {
52
52
  }
53
53
 
54
54
  /**
55
- * Creates an error object used when the type of output specified was not supported.
55
+ * Creates an error object to be thrown when a behavior, option, or parameter is unsupported.
56
56
  *
57
57
  * @public
58
58
  * @param {string} message - Error message to be displayed.
59
59
  * @returns {Error} instance detailing the error condition
60
60
  */
61
- function createNotSupportedError(message) {
61
+ function createUnsupportedError(message) {
62
62
  var err = new Error(message);
63
- err.code = 'ERR_MOCHA_NOT_SUPPORTED';
63
+ err.code = 'ERR_MOCHA_UNSUPPORTED';
64
64
  return err;
65
65
  }
66
66
 
67
67
  /**
68
- * Creates an error object used when an argument is missing.
68
+ * Creates an error object to be thrown when an argument is missing.
69
69
  *
70
70
  * @public
71
71
  * @param {string} message - Error message to be displayed.
@@ -78,7 +78,7 @@ function createMissingArgumentError(message, argument, expected) {
78
78
  }
79
79
 
80
80
  /**
81
- * Creates an error object used when an argument did not use the supported type
81
+ * Creates an error object to be thrown when an argument did not use the supported type
82
82
  *
83
83
  * @public
84
84
  * @param {string} message - Error message to be displayed.
@@ -96,7 +96,7 @@ function createInvalidArgumentTypeError(message, argument, expected) {
96
96
  }
97
97
 
98
98
  /**
99
- * Creates an error object used when an argument did not use the supported value
99
+ * Creates an error object to be thrown when an argument did not use the supported value
100
100
  *
101
101
  * @public
102
102
  * @param {string} message - Error message to be displayed.
@@ -115,25 +115,27 @@ function createInvalidArgumentValueError(message, argument, value, reason) {
115
115
  }
116
116
 
117
117
  /**
118
- * Creates an error object used when an error was thrown but no details were specified.
118
+ * Creates an error object to be thrown when an exception was caught, but the `Error` is falsy or undefined.
119
119
  *
120
120
  * @public
121
121
  * @param {string} message - Error message to be displayed.
122
122
  * @returns {Error} instance detailing the error condition
123
123
  */
124
- function createUndefinedError(message) {
124
+ function createInvalidExceptionError(message, value) {
125
125
  var err = new Error(message);
126
- err.code = 'ERR_MOCHA_UNDEFINED_ERROR';
126
+ err.code = 'ERR_MOCHA_INVALID_EXCEPTION';
127
+ err.valueType = typeof value;
128
+ err.value = value;
127
129
  return err;
128
130
  }
129
131
 
130
132
  module.exports = {
131
133
  createInvalidArgumentTypeError: createInvalidArgumentTypeError,
132
134
  createInvalidArgumentValueError: createInvalidArgumentValueError,
135
+ createInvalidExceptionError: createInvalidExceptionError,
133
136
  createInvalidInterfaceError: createInvalidInterfaceError,
134
137
  createInvalidReporterError: createInvalidReporterError,
135
138
  createMissingArgumentError: createMissingArgumentError,
136
139
  createNoFilesMatchPatternError: createNoFilesMatchPatternError,
137
- createNotSupportedError: createNotSupportedError,
138
- createUndefinedError: createUndefinedError
140
+ createUnsupportedError: createUnsupportedError
139
141
  };
package/lib/growl.js CHANGED
@@ -8,6 +8,7 @@
8
8
  const os = require('os');
9
9
  const path = require('path');
10
10
  const {sync: which} = require('which');
11
+ const {EVENT_RUN_END} = require('./runner').constants;
11
12
 
12
13
  /**
13
14
  * @summary
@@ -41,7 +42,7 @@ exports.isCapable = () => {
41
42
  * @param {Runner} runner - Runner instance.
42
43
  */
43
44
  exports.notify = runner => {
44
- runner.once('end', () => {
45
+ runner.once(EVENT_RUN_END, () => {
45
46
  display(runner);
46
47
  });
47
48
  };
@@ -64,7 +65,7 @@ const display = runner => {
64
65
  let title;
65
66
 
66
67
  if (stats.failures) {
67
- _message = `${stats.failures} of ${runner.total} tests failed`;
68
+ _message = `${stats.failures} of ${stats.tests} tests failed`;
68
69
  message = `${symbol.cross} ${_message}`;
69
70
  title = 'Failed';
70
71
  } else {
@@ -1,6 +1,8 @@
1
1
  'use strict';
2
2
 
3
3
  var Test = require('../test');
4
+ var EVENT_FILE_PRE_REQUIRE = require('../suite').constants
5
+ .EVENT_FILE_PRE_REQUIRE;
4
6
 
5
7
  /**
6
8
  * BDD-style interface:
@@ -22,7 +24,7 @@ var Test = require('../test');
22
24
  module.exports = function bddInterface(suite) {
23
25
  var suites = [suite];
24
26
 
25
- suite.on('pre-require', function(context, file, mocha) {
27
+ suite.on(EVENT_FILE_PRE_REQUIRE, function(context, file, mocha) {
26
28
  var common = require('./common')(suites, context, mocha);
27
29
 
28
30
  context.before = common.before;
@@ -130,7 +130,7 @@ module.exports = function(suites, context, mocha) {
130
130
  throw new Error('`.only` forbidden');
131
131
  }
132
132
 
133
- suite.parent._onlySuites = suite.parent._onlySuites.concat(suite);
133
+ suite.parent.appendOnlySuite(suite);
134
134
  }
135
135
  if (suite.pending) {
136
136
  if (mocha.options.forbidPending && shouldBeTested(suite)) {
@@ -141,10 +141,11 @@ module.exports = function(suites, context, mocha) {
141
141
  var result = opts.fn.call(suite);
142
142
  if (typeof result !== 'undefined') {
143
143
  utils.deprecate(
144
- 'Deprecation Warning: Suites do not support a return value;' +
145
- opts.title +
146
- ' returned :' +
147
- result
144
+ 'Suites ignore return values. Suite "' +
145
+ suite.fullTitle() +
146
+ '" in ' +
147
+ suite.file +
148
+ ' returned a value; this may be a bug in your test code'
148
149
  );
149
150
  }
150
151
  suites.shift();
@@ -174,7 +175,7 @@ module.exports = function(suites, context, mocha) {
174
175
  * @returns {*}
175
176
  */
176
177
  only: function(mocha, test) {
177
- test.parent._onlyTests = test.parent._onlyTests.concat(test);
178
+ test.parent.appendOnlyTest(test);
178
179
  return test;
179
180
  },
180
181
 
@@ -22,7 +22,7 @@ var Test = require('../test');
22
22
  module.exports = function(suite) {
23
23
  var suites = [suite];
24
24
 
25
- suite.on('require', visit);
25
+ suite.on(Suite.constants.EVENT_FILE_REQUIRE, visit);
26
26
 
27
27
  function visit(obj, file) {
28
28
  var suite;