mocha 5.1.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.
Files changed (61) hide show
  1. package/CHANGELOG.md +686 -984
  2. package/README.md +2 -1
  3. package/{images → assets/growl}/error.png +0 -0
  4. package/{images → assets/growl}/ok.png +0 -0
  5. package/bin/_mocha +4 -595
  6. package/bin/mocha +121 -61
  7. package/bin/options.js +6 -39
  8. package/browser-entry.js +21 -17
  9. package/lib/browser/growl.js +165 -2
  10. package/lib/browser/progress.js +11 -11
  11. package/lib/{template.html → browser/template.html} +0 -0
  12. package/lib/browser/tty.js +2 -2
  13. package/lib/cli/cli.js +68 -0
  14. package/lib/cli/commands.js +13 -0
  15. package/lib/cli/config.js +79 -0
  16. package/lib/cli/index.js +9 -0
  17. package/lib/cli/init.js +37 -0
  18. package/lib/cli/node-flags.js +69 -0
  19. package/lib/cli/one-and-dones.js +70 -0
  20. package/lib/cli/options.js +330 -0
  21. package/lib/cli/run-helpers.js +337 -0
  22. package/lib/cli/run-option-metadata.js +76 -0
  23. package/lib/cli/run.js +297 -0
  24. package/lib/context.js +14 -14
  25. package/lib/errors.js +141 -0
  26. package/lib/growl.js +136 -0
  27. package/lib/hook.js +5 -16
  28. package/lib/interfaces/bdd.js +16 -13
  29. package/lib/interfaces/common.js +62 -18
  30. package/lib/interfaces/exports.js +5 -8
  31. package/lib/interfaces/qunit.js +10 -10
  32. package/lib/interfaces/tdd.js +12 -11
  33. package/lib/mocha.js +477 -256
  34. package/lib/mocharc.json +10 -0
  35. package/lib/pending.js +1 -5
  36. package/lib/reporters/base.js +95 -117
  37. package/lib/reporters/doc.js +23 -9
  38. package/lib/reporters/dot.js +19 -13
  39. package/lib/reporters/html.js +82 -47
  40. package/lib/reporters/json-stream.js +43 -23
  41. package/lib/reporters/json.js +32 -23
  42. package/lib/reporters/landing.js +16 -9
  43. package/lib/reporters/list.js +19 -11
  44. package/lib/reporters/markdown.js +18 -12
  45. package/lib/reporters/min.js +8 -4
  46. package/lib/reporters/nyan.js +42 -35
  47. package/lib/reporters/progress.js +12 -7
  48. package/lib/reporters/spec.js +23 -12
  49. package/lib/reporters/tap.js +250 -32
  50. package/lib/reporters/xunit.js +61 -35
  51. package/lib/runnable.js +152 -95
  52. package/lib/runner.js +296 -248
  53. package/lib/stats-collector.js +83 -0
  54. package/lib/suite.js +294 -75
  55. package/lib/test.js +16 -15
  56. package/lib/utils.js +419 -146
  57. package/mocha.js +4589 -2228
  58. package/package.json +137 -38
  59. package/lib/ms.js +0 -94
  60. package/lib/reporters/base.js.orig +0 -498
  61. package/lib/reporters/json.js.orig +0 -128
package/lib/runnable.js CHANGED
@@ -1,50 +1,33 @@
1
1
  'use strict';
2
- /**
3
- * @module Runnable
4
- */
5
- /**
6
- * Module dependencies.
7
- */
2
+
8
3
  var EventEmitter = require('events').EventEmitter;
9
4
  var Pending = require('./pending');
10
5
  var debug = require('debug')('mocha:runnable');
11
- var milliseconds = require('./ms');
6
+ var milliseconds = require('ms');
12
7
  var utils = require('./utils');
8
+ var createInvalidExceptionError = require('./errors')
9
+ .createInvalidExceptionError;
13
10
 
14
11
  /**
15
12
  * Save timer references to avoid Sinon interfering (see GH-237).
16
13
  */
17
-
18
- /* eslint-disable no-unused-vars, no-native-reassign */
19
14
  var Date = global.Date;
20
15
  var setTimeout = global.setTimeout;
21
- var setInterval = global.setInterval;
22
16
  var clearTimeout = global.clearTimeout;
23
- var clearInterval = global.clearInterval;
24
- /* eslint-enable no-unused-vars, no-native-reassign */
25
-
26
- /**
27
- * Object#toString().
28
- */
29
-
30
17
  var toString = Object.prototype.toString;
31
18
 
32
- /**
33
- * Expose `Runnable`.
34
- */
35
-
36
19
  module.exports = Runnable;
37
20
 
38
21
  /**
39
- * Initialize a new `Runnable` with the given `title` and callback `fn`. Derived from [EventEmitter](https://nodejs.org/api/events.html#events_class_eventemitter)
22
+ * Initialize a new `Runnable` with the given `title` and callback `fn`.
40
23
  *
41
- * @memberof Mocha
42
- * @public
43
24
  * @class
25
+ * @extends external:EventEmitter
26
+ * @public
44
27
  * @param {String} title
45
28
  * @param {Function} fn
46
29
  */
47
- function Runnable (title, fn) {
30
+ function Runnable(title, fn) {
48
31
  this.title = title;
49
32
  this.fn = fn;
50
33
  this.body = (fn || '').toString();
@@ -65,23 +48,43 @@ function Runnable (title, fn) {
65
48
  utils.inherits(Runnable, EventEmitter);
66
49
 
67
50
  /**
68
- * Set & get timeout `ms`.
51
+ * Get current timeout value in msecs.
69
52
  *
70
- * @api private
71
- * @param {number|string} ms
72
- * @return {Runnable|number} ms or Runnable instance.
53
+ * @private
54
+ * @returns {number} current timeout threshold value
55
+ */
56
+ /**
57
+ * @summary
58
+ * Set timeout threshold value (msecs).
59
+ *
60
+ * @description
61
+ * A string argument can use shorthand (e.g., "2s") and will be converted.
62
+ * The value will be clamped to range [<code>0</code>, <code>2^<sup>31</sup>-1</code>].
63
+ * If clamped value matches either range endpoint, timeouts will be disabled.
64
+ *
65
+ * @private
66
+ * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout#Maximum_delay_value}
67
+ * @param {number|string} ms - Timeout threshold value.
68
+ * @returns {Runnable} this
69
+ * @chainable
73
70
  */
74
- Runnable.prototype.timeout = function (ms) {
71
+ Runnable.prototype.timeout = function(ms) {
75
72
  if (!arguments.length) {
76
73
  return this._timeout;
77
74
  }
78
- // see #1652 for reasoning
79
- if (ms === 0 || ms > Math.pow(2, 31)) {
80
- this._enableTimeouts = false;
81
- }
82
75
  if (typeof ms === 'string') {
83
76
  ms = milliseconds(ms);
84
77
  }
78
+
79
+ // Clamp to range
80
+ var INT_MAX = Math.pow(2, 31) - 1;
81
+ var range = [0, INT_MAX];
82
+ ms = utils.clamp(ms, range);
83
+
84
+ // see #1652 for reasoning
85
+ if (ms === range[0] || ms === range[1]) {
86
+ this._enableTimeouts = false;
87
+ }
85
88
  debug('timeout %d', ms);
86
89
  this._timeout = ms;
87
90
  if (this.timer) {
@@ -93,11 +96,11 @@ Runnable.prototype.timeout = function (ms) {
93
96
  /**
94
97
  * Set or get slow `ms`.
95
98
  *
96
- * @api private
99
+ * @private
97
100
  * @param {number|string} ms
98
101
  * @return {Runnable|number} ms or Runnable instance.
99
102
  */
100
- Runnable.prototype.slow = function (ms) {
103
+ Runnable.prototype.slow = function(ms) {
101
104
  if (!arguments.length || typeof ms === 'undefined') {
102
105
  return this._slow;
103
106
  }
@@ -112,11 +115,11 @@ Runnable.prototype.slow = function (ms) {
112
115
  /**
113
116
  * Set and get whether timeout is `enabled`.
114
117
  *
115
- * @api private
118
+ * @private
116
119
  * @param {boolean} enabled
117
120
  * @return {Runnable|boolean} enabled or Runnable instance.
118
121
  */
119
- Runnable.prototype.enableTimeouts = function (enabled) {
122
+ Runnable.prototype.enableTimeouts = function(enabled) {
120
123
  if (!arguments.length) {
121
124
  return this._enableTimeouts;
122
125
  }
@@ -130,18 +133,17 @@ Runnable.prototype.enableTimeouts = function (enabled) {
130
133
  *
131
134
  * @memberof Mocha.Runnable
132
135
  * @public
133
- * @api public
134
136
  */
135
- Runnable.prototype.skip = function () {
137
+ Runnable.prototype.skip = function() {
136
138
  throw new Pending('sync skip');
137
139
  };
138
140
 
139
141
  /**
140
142
  * Check if this runnable or its parent suite is marked as pending.
141
143
  *
142
- * @api private
144
+ * @private
143
145
  */
144
- Runnable.prototype.isPending = function () {
146
+ Runnable.prototype.isPending = function() {
145
147
  return this.pending || (this.parent && this.parent.isPending());
146
148
  };
147
149
 
@@ -150,8 +152,8 @@ Runnable.prototype.isPending = function () {
150
152
  * @return {boolean}
151
153
  * @private
152
154
  */
153
- Runnable.prototype.isFailed = function () {
154
- return !this.isPending() && this.state === 'failed';
155
+ Runnable.prototype.isFailed = function() {
156
+ return !this.isPending() && this.state === constants.STATE_FAILED;
155
157
  };
156
158
 
157
159
  /**
@@ -159,16 +161,16 @@ Runnable.prototype.isFailed = function () {
159
161
  * @return {boolean}
160
162
  * @private
161
163
  */
162
- Runnable.prototype.isPassed = function () {
163
- return !this.isPending() && this.state === 'passed';
164
+ Runnable.prototype.isPassed = function() {
165
+ return !this.isPending() && this.state === constants.STATE_PASSED;
164
166
  };
165
167
 
166
168
  /**
167
169
  * Set or get number of retries.
168
170
  *
169
- * @api private
171
+ * @private
170
172
  */
171
- Runnable.prototype.retries = function (n) {
173
+ Runnable.prototype.retries = function(n) {
172
174
  if (!arguments.length) {
173
175
  return this._retries;
174
176
  }
@@ -178,9 +180,9 @@ Runnable.prototype.retries = function (n) {
178
180
  /**
179
181
  * Set or get current retry
180
182
  *
181
- * @api private
183
+ * @private
182
184
  */
183
- Runnable.prototype.currentRetry = function (n) {
185
+ Runnable.prototype.currentRetry = function(n) {
184
186
  if (!arguments.length) {
185
187
  return this._currentRetry;
186
188
  }
@@ -193,10 +195,9 @@ Runnable.prototype.currentRetry = function (n) {
193
195
  *
194
196
  * @memberof Mocha.Runnable
195
197
  * @public
196
- * @api public
197
198
  * @return {string}
198
199
  */
199
- Runnable.prototype.fullTitle = function () {
200
+ Runnable.prototype.fullTitle = function() {
200
201
  return this.titlePath().join(' ');
201
202
  };
202
203
 
@@ -205,49 +206,52 @@ Runnable.prototype.fullTitle = function () {
205
206
  *
206
207
  * @memberof Mocha.Runnable
207
208
  * @public
208
- * @api public
209
209
  * @return {string}
210
210
  */
211
- Runnable.prototype.titlePath = function () {
211
+ Runnable.prototype.titlePath = function() {
212
212
  return this.parent.titlePath().concat([this.title]);
213
213
  };
214
214
 
215
215
  /**
216
216
  * Clear the timeout.
217
217
  *
218
- * @api private
218
+ * @private
219
219
  */
220
- Runnable.prototype.clearTimeout = function () {
220
+ Runnable.prototype.clearTimeout = function() {
221
221
  clearTimeout(this.timer);
222
222
  };
223
223
 
224
224
  /**
225
225
  * Inspect the runnable void of private properties.
226
226
  *
227
- * @api private
227
+ * @private
228
228
  * @return {string}
229
229
  */
230
- Runnable.prototype.inspect = function () {
231
- return JSON.stringify(this, function (key, val) {
232
- if (key[0] === '_') {
233
- return;
234
- }
235
- if (key === 'parent') {
236
- return '#<Suite>';
237
- }
238
- if (key === 'ctx') {
239
- return '#<Context>';
240
- }
241
- return val;
242
- }, 2);
230
+ Runnable.prototype.inspect = function() {
231
+ return JSON.stringify(
232
+ this,
233
+ function(key, val) {
234
+ if (key[0] === '_') {
235
+ return;
236
+ }
237
+ if (key === 'parent') {
238
+ return '#<Suite>';
239
+ }
240
+ if (key === 'ctx') {
241
+ return '#<Context>';
242
+ }
243
+ return val;
244
+ },
245
+ 2
246
+ );
243
247
  };
244
248
 
245
249
  /**
246
250
  * Reset the timeout.
247
251
  *
248
- * @api private
252
+ * @private
249
253
  */
250
- Runnable.prototype.resetTimeout = function () {
254
+ Runnable.prototype.resetTimeout = function() {
251
255
  var self = this;
252
256
  var ms = this.timeout() || 1e9;
253
257
 
@@ -255,7 +259,7 @@ Runnable.prototype.resetTimeout = function () {
255
259
  return;
256
260
  }
257
261
  this.clearTimeout();
258
- this.timer = setTimeout(function () {
262
+ this.timer = setTimeout(function() {
259
263
  if (!self._enableTimeouts) {
260
264
  return;
261
265
  }
@@ -267,10 +271,10 @@ Runnable.prototype.resetTimeout = function () {
267
271
  /**
268
272
  * Set or get a list of whitelisted globals for this test run.
269
273
  *
270
- * @api private
274
+ * @private
271
275
  * @param {string[]} globals
272
276
  */
273
- Runnable.prototype.globals = function (globals) {
277
+ Runnable.prototype.globals = function(globals) {
274
278
  if (!arguments.length) {
275
279
  return this._allowedGlobals;
276
280
  }
@@ -281,9 +285,9 @@ Runnable.prototype.globals = function (globals) {
281
285
  * Run the test and invoke `fn(err)`.
282
286
  *
283
287
  * @param {Function} fn
284
- * @api private
288
+ * @private
285
289
  */
286
- Runnable.prototype.run = function (fn) {
290
+ Runnable.prototype.run = function(fn) {
287
291
  var self = this;
288
292
  var start = new Date();
289
293
  var ctx = this.ctx;
@@ -296,7 +300,7 @@ Runnable.prototype.run = function (fn) {
296
300
  }
297
301
 
298
302
  // called multiple times
299
- function multiple (err) {
303
+ function multiple(err) {
300
304
  if (emitted) {
301
305
  return;
302
306
  }
@@ -311,7 +315,7 @@ Runnable.prototype.run = function (fn) {
311
315
  }
312
316
 
313
317
  // finished
314
- function done (err) {
318
+ function done(err) {
315
319
  var ms = self.timeout();
316
320
  if (self.timedOut) {
317
321
  return;
@@ -338,7 +342,7 @@ Runnable.prototype.run = function (fn) {
338
342
  this.resetTimeout();
339
343
 
340
344
  // allows skip() to be used in an explicit async context
341
- this.skip = function asyncSkip () {
345
+ this.skip = function asyncSkip() {
342
346
  done(new Pending('async skip call'));
343
347
  // halt execution. the Runnable will be marked pending
344
348
  // by the previous call, and the uncaught handler will ignore
@@ -353,7 +357,7 @@ Runnable.prototype.run = function (fn) {
353
357
  callFnAsync(this.fn);
354
358
  } catch (err) {
355
359
  emitted = true;
356
- done(utils.getError(err));
360
+ done(Runnable.toValueOrError(err));
357
361
  }
358
362
  return;
359
363
  }
@@ -376,46 +380,56 @@ Runnable.prototype.run = function (fn) {
376
380
  }
377
381
  } catch (err) {
378
382
  emitted = true;
379
- done(utils.getError(err));
383
+ done(Runnable.toValueOrError(err));
380
384
  }
381
385
 
382
- function callFn (fn) {
386
+ function callFn(fn) {
383
387
  var result = fn.call(ctx);
384
388
  if (result && typeof result.then === 'function') {
385
389
  self.resetTimeout();
386
- result
387
- .then(function () {
390
+ result.then(
391
+ function() {
388
392
  done();
389
393
  // Return null so libraries like bluebird do not warn about
390
394
  // subsequently constructed Promises.
391
395
  return null;
392
396
  },
393
- function (reason) {
397
+ function(reason) {
394
398
  done(reason || new Error('Promise rejected with no or falsy reason'));
395
- });
399
+ }
400
+ );
396
401
  } else {
397
402
  if (self.asyncOnly) {
398
- return done(new Error('--async-only option in use without declaring `done()` or returning a promise'));
403
+ return done(
404
+ new Error(
405
+ '--async-only option in use without declaring `done()` or returning a promise'
406
+ )
407
+ );
399
408
  }
400
409
 
401
410
  done();
402
411
  }
403
412
  }
404
413
 
405
- function callFnAsync (fn) {
406
- var result = fn.call(ctx, function (err) {
414
+ function callFnAsync(fn) {
415
+ var result = fn.call(ctx, function(err) {
407
416
  if (err instanceof Error || toString.call(err) === '[object Error]') {
408
417
  return done(err);
409
418
  }
410
419
  if (err) {
411
420
  if (Object.prototype.toString.call(err) === '[object Object]') {
412
- return done(new Error('done() invoked with non-Error: ' +
413
- JSON.stringify(err)));
421
+ return done(
422
+ new Error('done() invoked with non-Error: ' + JSON.stringify(err))
423
+ );
414
424
  }
415
425
  return done(new Error('done() invoked with non-Error: ' + err));
416
426
  }
417
427
  if (result && utils.isPromise(result)) {
418
- return done(new Error('Resolution method is overspecified. Specify a callback *or* return a Promise; not both.'));
428
+ return done(
429
+ new Error(
430
+ 'Resolution method is overspecified. Specify a callback *or* return a Promise; not both.'
431
+ )
432
+ );
419
433
  }
420
434
 
421
435
  done();
@@ -430,10 +444,53 @@ Runnable.prototype.run = function (fn) {
430
444
  * @returns {Error} a "timeout" error
431
445
  * @private
432
446
  */
433
- Runnable.prototype._timeoutError = function (ms) {
434
- var msg = 'Timeout of ' + ms + 'ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves.';
447
+ Runnable.prototype._timeoutError = function(ms) {
448
+ var msg =
449
+ 'Timeout of ' +
450
+ ms +
451
+ 'ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves.';
435
452
  if (this.file) {
436
453
  msg += ' (' + this.file + ')';
437
454
  }
438
455
  return new Error(msg);
439
456
  };
457
+
458
+ var constants = utils.defineConstants(
459
+ /**
460
+ * {@link Runnable}-related constants.
461
+ * @public
462
+ * @memberof Runnable
463
+ * @readonly
464
+ * @static
465
+ * @alias constants
466
+ * @enum {string}
467
+ */
468
+ {
469
+ /**
470
+ * Value of `state` prop when a `Runnable` has failed
471
+ */
472
+ STATE_FAILED: 'failed',
473
+ /**
474
+ * Value of `state` prop when a `Runnable` has passed
475
+ */
476
+ STATE_PASSED: 'passed'
477
+ }
478
+ );
479
+
480
+ /**
481
+ * Given `value`, return identity if truthy, otherwise create an "invalid exception" error and return that.
482
+ * @param {*} [value] - Value to return, if present
483
+ * @returns {*|Error} `value`, otherwise an `Error`
484
+ * @private
485
+ */
486
+ Runnable.toValueOrError = function(value) {
487
+ return (
488
+ value ||
489
+ createInvalidExceptionError(
490
+ 'Runnable failed with falsy or undefined exception. Please throw an Error instead.',
491
+ value
492
+ )
493
+ );
494
+ };
495
+
496
+ Runnable.constants = constants;