mocha 5.1.0 → 6.0.0-1

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 (63) hide show
  1. package/CHANGELOG.md +653 -981
  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 +84 -58
  7. package/bin/options.js +6 -39
  8. package/browser-entry.js +21 -17
  9. package/lib/browser/growl.js +164 -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 +48 -0
  19. package/lib/cli/one-and-dones.js +70 -0
  20. package/lib/cli/options.js +299 -0
  21. package/lib/cli/run-helpers.js +328 -0
  22. package/lib/cli/run-option-metadata.js +72 -0
  23. package/lib/cli/run.js +293 -0
  24. package/lib/context.js +14 -14
  25. package/lib/errors.js +139 -0
  26. package/lib/growl.js +135 -0
  27. package/lib/hook.js +5 -16
  28. package/lib/interfaces/bdd.js +14 -13
  29. package/lib/interfaces/common.js +59 -16
  30. package/lib/interfaces/exports.js +4 -7
  31. package/lib/interfaces/qunit.js +8 -10
  32. package/lib/interfaces/tdd.js +10 -11
  33. package/lib/mocha.js +442 -255
  34. package/lib/mocharc.json +10 -0
  35. package/lib/pending.js +1 -5
  36. package/lib/reporters/base.js +92 -117
  37. package/lib/reporters/doc.js +18 -9
  38. package/lib/reporters/dot.js +13 -13
  39. package/lib/reporters/html.js +76 -47
  40. package/lib/reporters/json-stream.js +38 -23
  41. package/lib/reporters/json.js +26 -23
  42. package/lib/reporters/landing.js +9 -8
  43. package/lib/reporters/list.js +11 -10
  44. package/lib/reporters/markdown.js +13 -12
  45. package/lib/reporters/min.js +4 -3
  46. package/lib/reporters/nyan.js +36 -35
  47. package/lib/reporters/progress.js +8 -7
  48. package/lib/reporters/spec.js +14 -11
  49. package/lib/reporters/tap.js +243 -32
  50. package/lib/reporters/xunit.js +52 -33
  51. package/lib/runnable.js +103 -90
  52. package/lib/runner.js +156 -107
  53. package/lib/stats-collector.js +81 -0
  54. package/lib/suite.js +57 -51
  55. package/lib/test.js +13 -13
  56. package/lib/utils.js +192 -103
  57. package/mocha.js +3836 -2046
  58. package/package.json +122 -38
  59. package/bin/.eslintrc.yml +0 -3
  60. package/lib/browser/.eslintrc.yml +0 -4
  61. package/lib/ms.js +0 -94
  62. package/lib/reporters/base.js.orig +0 -498
  63. package/lib/reporters/json.js.orig +0 -128
package/bin/mocha CHANGED
@@ -3,75 +3,101 @@
3
3
  'use strict';
4
4
 
5
5
  /**
6
- * This tiny wrapper file checks for known node flags and appends them
7
- * when found, before invoking the "real" _mocha(1) executable.
6
+ * This wrapper executable checks for known node flags and appends them when found, before invoking the "real" _mocha(1) executable.
7
+ *
8
+ * @module bin/mocha
9
+ * @private
8
10
  */
9
11
 
10
- const spawn = require('child_process').spawn;
11
- const path = require('path');
12
- const getOptions = require('./options');
13
- const args = [path.join(__dirname, '_mocha')];
12
+ const {deprecate} = require('../lib/utils');
13
+ const {spawn} = require('child_process');
14
+ const {loadOptions} = require('../lib/cli/options');
15
+ const {isNodeFlag, impliesNoTimeouts} = require('../lib/cli/node-flags');
16
+ const unparse = require('yargs-unparser');
17
+ const debug = require('debug')('mocha:cli');
18
+ const {aliases} = require('../lib/cli/run-option-metadata');
14
19
 
15
- // Load mocha.opts into process.argv
16
- // Must be loaded here to handle node-specific options
17
- getOptions();
20
+ const mochaPath = require.resolve('./_mocha');
21
+ const childOpts = {};
22
+ const nodeOpts = {};
18
23
 
19
- process.argv.slice(2).forEach(arg => {
20
- const flag = arg.split('=')[0];
24
+ const opts = loadOptions(process.argv.slice(2));
25
+ debug('loaded opts', opts);
21
26
 
22
- switch (flag) {
23
- case '-d':
24
- args.unshift('--debug');
25
- args.push('--no-timeouts');
26
- break;
27
- case 'debug':
28
- case '--debug':
29
- case '--debug-brk':
30
- case '--inspect':
31
- case '--inspect-brk':
32
- args.unshift(arg);
33
- args.push('--no-timeouts');
34
- break;
35
- case '-gc':
36
- case '--expose-gc':
37
- args.unshift('--expose-gc');
38
- break;
39
- case '--gc-global':
40
- case '--es_staging':
41
- case '--no-deprecation':
42
- case '--no-warnings':
43
- case '--prof':
44
- case '--log-timer-events':
45
- case '--throw-deprecation':
46
- case '--trace-deprecation':
47
- case '--trace-warnings':
48
- case '--use_strict':
49
- case '--allow-natives-syntax':
50
- case '--perf-basic-prof':
51
- case '--napi-modules':
52
- args.unshift(arg);
53
- break;
54
- default:
55
- if (arg.indexOf('--harmony') === 0) {
56
- args.unshift(arg);
57
- } else if (arg.indexOf('--trace') === 0) {
58
- args.unshift(arg);
59
- } else if (arg.indexOf('--icu-data-dir') === 0) {
60
- args.unshift(arg);
61
- } else if (arg.indexOf('--max-old-space-size') === 0) {
62
- args.unshift(arg);
63
- } else if (arg.indexOf('--preserve-symlinks') === 0) {
64
- args.unshift(arg);
65
- } else {
66
- args.push(arg);
67
- }
68
- break;
27
+ Object.keys(opts).forEach(opt => {
28
+ 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
+ }
37
+ } else {
38
+ childOpts[opt] = opts[opt];
69
39
  }
70
40
  });
71
41
 
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
+ // Native debugger handling
64
+ // see https://nodejs.org/api/debugger.html#debugger_debugger
65
+ // look for 'debug' or 'inspect' that would launch this debugger,
66
+ // remove it from Mocha's opts and prepend it to Node's opts.
67
+ // also coerce depending on Node.js version.
68
+ if (/^(debug|inspect)$/.test(childOpts._[0])) {
69
+ childOpts.timeout = false;
70
+ childOpts._.shift();
71
+ // 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._ = [
77
+ parseInt(
78
+ process.version
79
+ .slice(1)
80
+ .split('.')
81
+ .shift(),
82
+ 10
83
+ ) >= 8
84
+ ? 'inspect'
85
+ : 'debug'
86
+ ];
87
+ }
88
+
89
+ const args = [].concat(
90
+ unparse(nodeOpts),
91
+ mochaPath,
92
+ unparse(childOpts, {alias: aliases})
93
+ );
94
+
95
+ debug(`exec ${process.execPath} w/ args:`, args);
96
+
72
97
  const proc = spawn(process.execPath, args, {
73
98
  stdio: 'inherit'
74
99
  });
100
+
75
101
  proc.on('exit', (code, signal) => {
76
102
  process.on('exit', () => {
77
103
  if (signal) {
package/bin/options.js CHANGED
@@ -1,43 +1,10 @@
1
1
  'use strict';
2
2
 
3
- /**
4
- * Dependencies.
3
+ /*
4
+ * This module is deprecated and will be removed in a future version of Mocha.
5
+ * @deprecated Deprecated in v6.0.0; source moved into {@link module:lib/cli/options lib/cli/options module}.
6
+ * @module
7
+ * @exports module:lib/cli/options
5
8
  */
6
9
 
7
- const fs = require('fs');
8
-
9
- /**
10
- * Export `getOptions`.
11
- */
12
-
13
- module.exports = getOptions;
14
-
15
- /**
16
- * Get options.
17
- */
18
-
19
- function getOptions () {
20
- if (process.argv.length === 3 && (process.argv[2] === '-h' || process.argv[2] === '--help')) {
21
- return;
22
- }
23
-
24
- const optsPath = process.argv.indexOf('--opts') === -1
25
- ? 'test/mocha.opts'
26
- : process.argv[process.argv.indexOf('--opts') + 1];
27
-
28
- try {
29
- const opts = fs.readFileSync(optsPath, 'utf8')
30
- .replace(/\\\s/g, '%20')
31
- .split(/\s/)
32
- .filter(Boolean)
33
- .map(value => value.replace(/%20/g, ' '));
34
-
35
- process.argv = process.argv
36
- .slice(0, 2)
37
- .concat(opts.concat(process.argv.slice(2)));
38
- } catch (err) {
39
- // ignore
40
- }
41
-
42
- process.env.LOADED_MOCHA_OPTS = true;
43
- }
10
+ module.exports = require('../lib/cli/options');
package/browser-entry.js CHANGED
@@ -7,7 +7,7 @@
7
7
  * Shim process.stdout.
8
8
  */
9
9
 
10
- process.stdout = require('browser-stdout')({level: false});
10
+ process.stdout = require('browser-stdout')({label: false});
11
11
 
12
12
  var Mocha = require('./lib/mocha');
13
13
 
@@ -17,7 +17,7 @@ var Mocha = require('./lib/mocha');
17
17
  * @return {undefined}
18
18
  */
19
19
 
20
- var mocha = new Mocha({ reporter: 'html' });
20
+ var mocha = new Mocha({reporter: 'html'});
21
21
 
22
22
  /**
23
23
  * Save timer references to avoid Sinon interfering (see GH-237).
@@ -38,12 +38,12 @@ var originalOnerrorHandler = global.onerror;
38
38
  * Revert to original onerror handler if previously defined.
39
39
  */
40
40
 
41
- process.removeListener = function (e, fn) {
41
+ process.removeListener = function(e, fn) {
42
42
  if (e === 'uncaughtException') {
43
43
  if (originalOnerrorHandler) {
44
44
  global.onerror = originalOnerrorHandler;
45
45
  } else {
46
- global.onerror = function () {};
46
+ global.onerror = function() {};
47
47
  }
48
48
  var i = uncaughtExceptionHandlers.indexOf(fn);
49
49
  if (i !== -1) {
@@ -56,9 +56,9 @@ process.removeListener = function (e, fn) {
56
56
  * Implements uncaughtException listener.
57
57
  */
58
58
 
59
- process.on = function (e, fn) {
59
+ process.on = function(e, fn) {
60
60
  if (e === 'uncaughtException') {
61
- global.onerror = function (err, url, line) {
61
+ global.onerror = function(err, url, line) {
62
62
  fn(new Error(err + ' (' + url + ':' + line + ')'));
63
63
  return !mocha.allowUncaught;
64
64
  };
@@ -74,9 +74,9 @@ mocha.suite.removeAllListeners('pre-require');
74
74
  var immediateQueue = [];
75
75
  var immediateTimeout;
76
76
 
77
- function timeslice () {
77
+ function timeslice() {
78
78
  var immediateStart = new Date().getTime();
79
- while (immediateQueue.length && (new Date().getTime() - immediateStart) < 100) {
79
+ while (immediateQueue.length && new Date().getTime() - immediateStart < 100) {
80
80
  immediateQueue.shift()();
81
81
  }
82
82
  if (immediateQueue.length) {
@@ -90,7 +90,7 @@ function timeslice () {
90
90
  * High-performance override of Runner.immediately.
91
91
  */
92
92
 
93
- Mocha.Runner.immediately = function (callback) {
93
+ Mocha.Runner.immediately = function(callback) {
94
94
  immediateQueue.push(callback);
95
95
  if (!immediateTimeout) {
96
96
  immediateTimeout = setTimeout(timeslice, 0);
@@ -102,8 +102,8 @@ Mocha.Runner.immediately = function (callback) {
102
102
  * This is useful when running tests in a browser because window.onerror will
103
103
  * only receive the 'message' attribute of the Error.
104
104
  */
105
- mocha.throwError = function (err) {
106
- uncaughtExceptionHandlers.forEach(function (fn) {
105
+ mocha.throwError = function(err) {
106
+ uncaughtExceptionHandlers.forEach(function(fn) {
107
107
  fn(err);
108
108
  });
109
109
  throw err;
@@ -114,7 +114,7 @@ mocha.throwError = function (err) {
114
114
  * Normally this would happen in Mocha.prototype.loadFiles.
115
115
  */
116
116
 
117
- mocha.ui = function (ui) {
117
+ mocha.ui = function(ui) {
118
118
  Mocha.prototype.ui.call(this, ui);
119
119
  this.suite.emit('pre-require', global, null, this);
120
120
  return this;
@@ -124,9 +124,9 @@ mocha.ui = function (ui) {
124
124
  * Setup mocha with the given setting options.
125
125
  */
126
126
 
127
- mocha.setup = function (opts) {
127
+ mocha.setup = function(opts) {
128
128
  if (typeof opts === 'string') {
129
- opts = { ui: opts };
129
+ opts = {ui: opts};
130
130
  }
131
131
  for (var opt in opts) {
132
132
  if (opts.hasOwnProperty(opt)) {
@@ -140,7 +140,7 @@ mocha.setup = function (opts) {
140
140
  * Run mocha, returning the Runner.
141
141
  */
142
142
 
143
- mocha.run = function (fn) {
143
+ mocha.run = function(fn) {
144
144
  var options = mocha.options;
145
145
  mocha.globals('location');
146
146
 
@@ -155,10 +155,14 @@ mocha.run = function (fn) {
155
155
  mocha.invert();
156
156
  }
157
157
 
158
- return Mocha.prototype.run.call(mocha, function (err) {
158
+ return Mocha.prototype.run.call(mocha, function(err) {
159
159
  // The DOM Document is not available in Web Workers.
160
160
  var document = global.document;
161
- if (document && document.getElementById('mocha') && options.noHighlighting !== true) {
161
+ if (
162
+ document &&
163
+ document.getElementById('mocha') &&
164
+ options.noHighlighting !== true
165
+ ) {
162
166
  Mocha.utils.highlightTags('code');
163
167
  }
164
168
  if (fn) {
@@ -1,5 +1,167 @@
1
1
  'use strict';
2
2
 
3
- // just stub out growl
3
+ /**
4
+ * Web Notifications module.
5
+ * @module Growl
6
+ */
4
7
 
5
- module.exports = require('../utils').noop;
8
+ /**
9
+ * Save timer references to avoid Sinon interfering (see GH-237).
10
+ */
11
+ var Date = global.Date;
12
+ var setTimeout = global.setTimeout;
13
+
14
+ /**
15
+ * Checks if browser notification support exists.
16
+ *
17
+ * @public
18
+ * @see {@link https://caniuse.com/#feat=notifications|Browser support (notifications)}
19
+ * @see {@link https://caniuse.com/#feat=promises|Browser support (promises)}
20
+ * @see {@link Mocha#growl}
21
+ * @see {@link Mocha#isGrowlCapable}
22
+ * @return {boolean} whether browser notification support exists
23
+ */
24
+ exports.isCapable = function() {
25
+ var hasNotificationSupport = 'Notification' in window;
26
+ var hasPromiseSupport = typeof Promise === 'function';
27
+ return process.browser && hasNotificationSupport && hasPromiseSupport;
28
+ };
29
+
30
+ /**
31
+ * Implements browser notifications as a pseudo-reporter.
32
+ *
33
+ * @public
34
+ * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/notification|Notification API}
35
+ * @see {@link https://developers.google.com/web/fundamentals/push-notifications/display-a-notification|Displaying a Notification}
36
+ * @see {@link Growl#isPermitted}
37
+ * @see {@link Mocha#_growl}
38
+ * @param {Runner} runner - Runner instance.
39
+ */
40
+ exports.notify = function(runner) {
41
+ var promise = isPermitted();
42
+
43
+ /**
44
+ * Attempt notification.
45
+ */
46
+ var sendNotification = function() {
47
+ // If user hasn't responded yet... "No notification for you!" (Seinfeld)
48
+ Promise.race([promise, Promise.resolve(undefined)])
49
+ .then(canNotify)
50
+ .then(function() {
51
+ display(runner);
52
+ })
53
+ .catch(notPermitted);
54
+ };
55
+
56
+ runner.once('end', sendNotification);
57
+ };
58
+
59
+ /**
60
+ * Checks if browser notification is permitted by user.
61
+ *
62
+ * @private
63
+ * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Notification/permission|Notification.permission}
64
+ * @see {@link Mocha#growl}
65
+ * @see {@link Mocha#isGrowlPermitted}
66
+ * @returns {Promise<boolean>} promise determining if browser notification
67
+ * permissible when fulfilled.
68
+ */
69
+ function isPermitted() {
70
+ var permitted = {
71
+ granted: function allow() {
72
+ return Promise.resolve(true);
73
+ },
74
+ denied: function deny() {
75
+ return Promise.resolve(false);
76
+ },
77
+ default: function ask() {
78
+ return Notification.requestPermission().then(function(permission) {
79
+ return permission === 'granted';
80
+ });
81
+ }
82
+ };
83
+
84
+ return permitted[Notification.permission]();
85
+ }
86
+
87
+ /**
88
+ * @summary
89
+ * Determines if notification should proceed.
90
+ *
91
+ * @description
92
+ * Notification shall <strong>not</strong> proceed unless `value` is true.
93
+ *
94
+ * `value` will equal one of:
95
+ * <ul>
96
+ * <li><code>true</code> (from `isPermitted`)</li>
97
+ * <li><code>false</code> (from `isPermitted`)</li>
98
+ * <li><code>undefined</code> (from `Promise.race`)</li>
99
+ * </ul>
100
+ *
101
+ * @private
102
+ * @param {boolean|undefined} value - Determines if notification permissible.
103
+ * @returns {Promise<undefined>} Notification can proceed
104
+ */
105
+ function canNotify(value) {
106
+ if (!value) {
107
+ var why = value === false ? 'blocked' : 'unacknowledged';
108
+ var reason = 'not permitted by user (' + why + ')';
109
+ return Promise.reject(new Error(reason));
110
+ }
111
+ return Promise.resolve();
112
+ }
113
+
114
+ /**
115
+ * Displays the notification.
116
+ *
117
+ * @private
118
+ * @param {Runner} runner - Runner instance.
119
+ */
120
+ function display(runner) {
121
+ var stats = runner.stats;
122
+ var symbol = {
123
+ cross: '\u274C',
124
+ tick: '\u2705'
125
+ };
126
+ var logo = require('../../package').notifyLogo;
127
+ var _message;
128
+ var message;
129
+ var title;
130
+
131
+ if (stats.failures) {
132
+ _message = stats.failures + ' of ' + runner.total + ' tests failed';
133
+ message = symbol.cross + ' ' + _message;
134
+ title = 'Failed';
135
+ } else {
136
+ _message = stats.passes + ' tests passed in ' + stats.duration + 'ms';
137
+ message = symbol.tick + ' ' + _message;
138
+ title = 'Passed';
139
+ }
140
+
141
+ // Send notification
142
+ var options = {
143
+ badge: logo,
144
+ body: message,
145
+ dir: 'ltr',
146
+ icon: logo,
147
+ lang: 'en-US',
148
+ name: 'mocha',
149
+ requireInteraction: false,
150
+ timestamp: Date.now()
151
+ };
152
+ var notification = new Notification(title, options);
153
+
154
+ // Autoclose after brief delay (makes various browsers act same)
155
+ var FORCE_DURATION = 4000;
156
+ setTimeout(notification.close.bind(notification), FORCE_DURATION);
157
+ }
158
+
159
+ /**
160
+ * As notifications are tangential to our purpose, just log the error.
161
+ *
162
+ * @private
163
+ * @param {Error} err - Why notification didn't happen.
164
+ */
165
+ function notPermitted(err) {
166
+ console.error('notification error:', err.message);
167
+ }
@@ -9,7 +9,7 @@ module.exports = Progress;
9
9
  /**
10
10
  * Initialize a new `Progress` indicator.
11
11
  */
12
- function Progress () {
12
+ function Progress() {
13
13
  this.percent = 0;
14
14
  this.size(0);
15
15
  this.fontSize(11);
@@ -19,11 +19,11 @@ function Progress () {
19
19
  /**
20
20
  * Set progress size to `size`.
21
21
  *
22
- * @api public
22
+ * @public
23
23
  * @param {number} size
24
24
  * @return {Progress} Progress instance.
25
25
  */
26
- Progress.prototype.size = function (size) {
26
+ Progress.prototype.size = function(size) {
27
27
  this._size = size;
28
28
  return this;
29
29
  };
@@ -31,11 +31,11 @@ Progress.prototype.size = function (size) {
31
31
  /**
32
32
  * Set text to `text`.
33
33
  *
34
- * @api public
34
+ * @public
35
35
  * @param {string} text
36
36
  * @return {Progress} Progress instance.
37
37
  */
38
- Progress.prototype.text = function (text) {
38
+ Progress.prototype.text = function(text) {
39
39
  this._text = text;
40
40
  return this;
41
41
  };
@@ -43,11 +43,11 @@ Progress.prototype.text = function (text) {
43
43
  /**
44
44
  * Set font size to `size`.
45
45
  *
46
- * @api public
46
+ * @public
47
47
  * @param {number} size
48
48
  * @return {Progress} Progress instance.
49
49
  */
50
- Progress.prototype.fontSize = function (size) {
50
+ Progress.prototype.fontSize = function(size) {
51
51
  this._fontSize = size;
52
52
  return this;
53
53
  };
@@ -58,7 +58,7 @@ Progress.prototype.fontSize = function (size) {
58
58
  * @param {string} family
59
59
  * @return {Progress} Progress instance.
60
60
  */
61
- Progress.prototype.font = function (family) {
61
+ Progress.prototype.font = function(family) {
62
62
  this._font = family;
63
63
  return this;
64
64
  };
@@ -69,7 +69,7 @@ Progress.prototype.font = function (family) {
69
69
  * @param {number} n
70
70
  * @return {Progress} Progress instance.
71
71
  */
72
- Progress.prototype.update = function (n) {
72
+ Progress.prototype.update = function(n) {
73
73
  this.percent = n;
74
74
  return this;
75
75
  };
@@ -80,7 +80,7 @@ Progress.prototype.update = function (n) {
80
80
  * @param {CanvasRenderingContext2d} ctx
81
81
  * @return {Progress} Progress instance.
82
82
  */
83
- Progress.prototype.draw = function (ctx) {
83
+ Progress.prototype.draw = function(ctx) {
84
84
  try {
85
85
  var percent = Math.min(this.percent, 100);
86
86
  var size = this._size;
@@ -112,7 +112,7 @@ Progress.prototype.draw = function (ctx) {
112
112
  var w = ctx.measureText(text).width;
113
113
 
114
114
  ctx.fillText(text, x - w / 2 + 1, y + fontSize / 2 - 1);
115
- } catch (err) {
115
+ } catch (ignore) {
116
116
  // don't fail if we can't render progress
117
117
  }
118
118
  return this;
File without changes
@@ -1,10 +1,10 @@
1
1
  'use strict';
2
2
 
3
- exports.isatty = function isatty () {
3
+ exports.isatty = function isatty() {
4
4
  return true;
5
5
  };
6
6
 
7
- exports.getWindowSize = function getWindowSize () {
7
+ exports.getWindowSize = function getWindowSize() {
8
8
  if ('innerHeight' in global) {
9
9
  return [global.innerHeight, global.innerWidth];
10
10
  }
package/lib/cli/cli.js ADDED
@@ -0,0 +1,68 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * This is where we finally parse and handle arguments passed to the `mocha` executable.
5
+ * Option parsing is handled by {@link https://npm.im/yargs yargs}.
6
+ * If executed via `node`, this module will run {@linkcode module:lib/cli/cli.main main()}.
7
+ *
8
+ * @private
9
+ * @module
10
+ */
11
+
12
+ const debug = require('debug')('mocha:cli:cli');
13
+ const symbols = require('log-symbols');
14
+ const yargs = require('yargs');
15
+ const path = require('path');
16
+ const {loadOptions} = require('./options');
17
+ const commands = require('./commands');
18
+ const ansi = require('ansi-colors');
19
+ const {repository, homepage, version, gitter} = require('../../package.json');
20
+
21
+ /**
22
+ * - Accepts an `Array` of arguments
23
+ * - Modifies {@link https://nodejs.org/api/modules.html#modules_module_paths Node.js' search path} for easy loading of consumer modules
24
+ * - Sets {@linkcode https://nodejs.org/api/errors.html#errors_error_stacktracelimit Error.stackTraceLimit} to `Infinity`
25
+ * @summary Mocha's main entry point from the command-line.
26
+ * @param {string[]} argv - Array of arguments to parse, or by default the lovely `process.argv.slice(2)`
27
+ */
28
+ exports.main = (argv = process.argv.slice(2)) => {
29
+ debug('entered main with raw args', argv);
30
+ // ensure we can require() from current working directory
31
+ module.paths.push(process.cwd(), path.resolve('node_modules'));
32
+
33
+ Error.stackTraceLimit = Infinity; // configurable via --stack-trace-limit?
34
+
35
+ yargs
36
+ .scriptName('mocha')
37
+ .command(commands.run)
38
+ .command(commands.init)
39
+ .updateStrings({
40
+ 'Positionals:': 'Positional Arguments',
41
+ 'Options:': 'Other Options',
42
+ 'Commands:': 'Commands'
43
+ })
44
+ .fail((msg, err, yargs) => {
45
+ debug(err);
46
+ yargs.showHelp();
47
+ console.error(`\n${symbols.error} ${ansi.red('ERROR:')} ${msg}`);
48
+ process.exit(1);
49
+ })
50
+ .help('help', 'Show usage information & exit')
51
+ .alias('help', 'h')
52
+ .version('version', 'Show version number & exit', version)
53
+ .alias('version', 'V')
54
+ .wrap(process.stdout.columns ? Math.min(process.stdout.columns, 80) : 80)
55
+ .epilog(
56
+ `Mocha Resources
57
+ Chat: ${ansi.magenta(gitter)}
58
+ GitHub: ${ansi.blue(repository.url)}
59
+ Docs: ${ansi.yellow(homepage)}
60
+ `
61
+ )
62
+ .parse(argv, loadOptions(argv));
63
+ };
64
+
65
+ // allow direct execution
66
+ if (require.main === module) {
67
+ exports.main();
68
+ }
@@ -0,0 +1,13 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * Exports Yargs commands
5
+ * @see https://git.io/fpJ0G
6
+ * @private
7
+ * @module
8
+ */
9
+
10
+ exports.init = require('./init');
11
+
12
+ // default command
13
+ exports.run = require('./run');