mocha 10.2.0 → 10.4.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/README.md CHANGED
@@ -1,5 +1,5 @@
1
1
  <p align="center">
2
- <img src="https://cldup.com/xFVFxOioAU.svg" alt="Mocha test framework"/>
2
+ <img src="https://cldup.com/xFVFxOioAU.svg" alt="Mocha test framework logo"/>
3
3
  </p>
4
4
 
5
5
  <p align="center">☕️ Simple, flexible, fun JavaScript test framework for Node.js & The Browser ☕️</p>
@@ -8,9 +8,9 @@
8
8
  <a href="https://github.com/mochajs/mocha/actions?query=workflow%3ATests+branch%3Amaster"><img src="https://github.com/mochajs/mocha/workflows/Tests/badge.svg?branch=master" alt="GitHub Actions Build Status"></a>
9
9
  <a href="https://coveralls.io/github/mochajs/mocha"><img src="https://coveralls.io/repos/github/mochajs/mocha/badge.svg" alt="Coverage Status"></a>
10
10
  <a href="https://app.fossa.io/projects/git%2Bhttps%3A%2F%2Fgithub.com%2Fmochajs%2Fmocha?ref=badge_shield"><img src="https://app.fossa.io/api/projects/git%2Bhttps%3A%2F%2Fgithub.com%2Fmochajs%2Fmocha.svg?type=shield" alt="FOSSA Status"></a>
11
- <a href="https://gitter.im/mochajs/mocha?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge"><img src="https://badges.gitter.im/Join%20Chat.svg" alt="Gitter"></a>
12
- <a href="https://github.com/mochajs/mocha#sponsors"><img src="https://opencollective.com/mochajs/tiers/sponsors/badge.svg" alt="OpenCollective"></a>
13
- <a href="https://github.com/mochajs/mocha#backers"><img src="https://opencollective.com/mochajs/tiers/backers/badge.svg" alt="OpenCollective"></a>
11
+ <a href="https://discord.gg/KeDn2uXhER"><img alt="Chat - Discord" src="https://img.shields.io/badge/chat-Discord-5765F2.svg" /></a>
12
+ <a href="https://github.com/mochajs/mocha#sponsors"><img src="https://opencollective.com/mochajs/tiers/sponsors/badge.svg" alt="OpenCollective Sponsors"></a>
13
+ <a href="https://github.com/mochajs/mocha#backers"><img src="https://opencollective.com/mochajs/tiers/backers/badge.svg" alt="OpenCollective Backers"></a>
14
14
  </p>
15
15
 
16
16
  <p align="center">
@@ -22,11 +22,12 @@
22
22
 
23
23
  ## Links
24
24
 
25
- - **[Documentation](https://mochajs.org/)**
25
+ - **[Documentation](https://mochajs.org)**
26
26
  - **[Release Notes / History / Changes](https://github.com/mochajs/mocha/blob/master/CHANGELOG.md)**
27
27
  - [Code of Conduct](https://github.com/mochajs/mocha/blob/master/.github/CODE_OF_CONDUCT.md)
28
28
  - [Contributing](https://github.com/mochajs/mocha/blob/master/.github/CONTRIBUTING.md)
29
- - [Gitter Chatroom](https://gitter.im/mochajs/mocha) (ask questions here!)
29
+ - [Development](https://github.com/mochajs/mocha/blob/master/.github/DEVELOPMENT.md)
30
+ - [Discord](https://discord.gg/KeDn2uXhER) (ask questions here!)
30
31
  - [Issue Tracker](https://github.com/mochajs/mocha/issues)
31
32
 
32
33
  ## Backers
@@ -37,7 +38,10 @@
37
38
 
38
39
  ## Sponsors
39
40
 
40
- Does your company use Mocha? Ask your manager or marketing team if your company would be interested in supporting our project. Support will allow the maintainers to dedicate more time for maintenance and new features for everyone. Also, your company's logo will show [on GitHub](https://github.com/mochajs/mocha#readme) and on [our site](https://mochajs.org#sponsors) - who doesn't want a little extra exposure? [Here's the info](https://opencollective.com/mochajs).
41
+ Does your company use Mocha? Ask your manager or marketing team if your company would be interested in supporting our project.
42
+ Support will allow the maintainers to dedicate more time for maintenance and new features for everyone.
43
+ Also, your company's logo will show [on GitHub](https://github.com/mochajs/mocha#readme) and on [our site](https://mochajs.org#sponsors) - who doesn't want a little extra exposure?
44
+ [Here's the info](https://opencollective.com/mochajs).
41
45
 
42
46
  [![MochaJS Sponsor](https://opencollective.com/mochajs/tiers/sponsors/0/avatar)](https://opencollective.com/mochajs/tiers/sponsors/0/website)
43
47
  [![MochaJS Sponsor](https://opencollective.com/mochajs/tiers/sponsors/1/avatar)](https://opencollective.com/mochajs/tiers/sponsors/1/website)
@@ -53,11 +57,11 @@ You might want to know that:
53
57
 
54
58
  You might want to help:
55
59
 
56
- - New to contributing to Mocha? Check out this list of [good first issues](https://github.com/mochajs/mocha/issues?q=is%3Aissue+is%3Aopen+label%3Agood-first-issue)
57
- - Mocha could use a hand with [these issues](https://github.com/mochajs/mocha/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22)
60
+ - New to contributing to Mocha? Check out this list of [good first issues](https://github.com/mochajs/mocha/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22)
61
+ - Mocha could use a hand with [these issues](https://github.com/mochajs/mocha/issues?q=is%3Aopen+is%3Aissue+label%3A%22status%3A+accepting+prs%22)
58
62
  - The [maintainer's handbook](https://github.com/mochajs/mocha/blob/master/MAINTAINERS.md) explains how things get done
59
63
 
60
- Finally, come [chat with the maintainers](https://gitter.im/mochajs/contributors) on Gitter if you want to help with:
64
+ Finally, come [chat with the maintainers on Discord](https://discord.gg/KeDn2uXhER) if you want to help with:
61
65
 
62
66
  - Triaging issues, answering questions
63
67
  - Review, merging, and closing pull requests
package/lib/cli/cli.js CHANGED
@@ -23,7 +23,7 @@ const {
23
23
  const lookupFiles = require('./lookup-files');
24
24
  const commands = require('./commands');
25
25
  const ansi = require('ansi-colors');
26
- const {repository, homepage, version, gitter} = require('../../package.json');
26
+ const {repository, homepage, version, discord} = require('../../package.json');
27
27
  const {cwd} = require('../utils');
28
28
 
29
29
  /**
@@ -68,7 +68,7 @@ exports.main = (argv = process.argv.slice(2), mochaArgs) => {
68
68
  .wrap(process.stdout.columns ? Math.min(process.stdout.columns, 80) : 80)
69
69
  .epilog(
70
70
  `Mocha Resources
71
- Chat: ${ansi.magenta(gitter)}
71
+ Chat: ${ansi.magenta(discord)}
72
72
  GitHub: ${ansi.blue(repository.url)}
73
73
  Docs: ${ansi.yellow(homepage)}
74
74
  `
@@ -35,7 +35,10 @@ module.exports = ({
35
35
  try {
36
36
  const moreSpecFiles = castArray(lookupFiles(arg, extension, recursive))
37
37
  .filter(filename =>
38
- ignore.every(pattern => !minimatch(filename, pattern))
38
+ ignore.every(
39
+ pattern =>
40
+ !minimatch(filename, pattern, {windowsPathsNoEscape: true})
41
+ )
39
42
  )
40
43
  .map(filename => path.resolve(filename));
41
44
  return [...specFiles, ...moreSpecFiles];
@@ -75,7 +75,7 @@ module.exports = function lookupFiles(
75
75
 
76
76
  if (!fs.existsSync(filepath)) {
77
77
  let pattern;
78
- if (glob.hasMagic(filepath)) {
78
+ if (glob.hasMagic(filepath, {windowsPathsNoEscape: true})) {
79
79
  // Handle glob as is without extensions
80
80
  pattern = filepath;
81
81
  } else {
@@ -86,7 +86,12 @@ module.exports = function lookupFiles(
86
86
  pattern = `${filepath}+(${strExtensions})`;
87
87
  debug('looking for files using glob pattern: %s', pattern);
88
88
  }
89
- files.push(...glob.sync(pattern, {nodir: true}));
89
+ files.push(
90
+ ...glob.sync(pattern, {
91
+ nodir: true,
92
+ windowsPathsNoEscape: true
93
+ })
94
+ );
90
95
  if (!files.length) {
91
96
  throw createNoFilesMatchPatternError(
92
97
  `Cannot find any files matching pattern "${filepath}"`,
package/lib/cli/run.js CHANGED
@@ -369,7 +369,7 @@ exports.handler = async function (argv) {
369
369
  try {
370
370
  await runMocha(mocha, argv);
371
371
  } catch (err) {
372
- console.error('\n' + (err.stack || `Error: ${err.message || err}`));
372
+ console.error('\n Exception during run:', err);
373
373
  process.exit(1);
374
374
  }
375
375
  };
@@ -221,6 +221,56 @@ var generateDiff = (exports.generateDiff = function (actual, expected) {
221
221
  }
222
222
  });
223
223
 
224
+ /**
225
+ * Traverses err.cause and returns all stack traces
226
+ *
227
+ * @private
228
+ * @param {Error} err
229
+ * @param {Set<Error>} [seen]
230
+ * @return {FullErrorStack}
231
+ */
232
+ var getFullErrorStack = function (err, seen) {
233
+ if (seen && seen.has(err)) {
234
+ return { message: '', msg: '<circular>', stack: '' };
235
+ }
236
+
237
+ var message;
238
+
239
+ if (typeof err.inspect === 'function') {
240
+ message = err.inspect() + '';
241
+ } else if (err.message && typeof err.message.toString === 'function') {
242
+ message = err.message + '';
243
+ } else {
244
+ message = '';
245
+ }
246
+
247
+ var msg;
248
+ var stack = err.stack || message;
249
+ var index = message ? stack.indexOf(message) : -1;
250
+
251
+ if (index === -1) {
252
+ msg = message;
253
+ } else {
254
+ index += message.length;
255
+ msg = stack.slice(0, index);
256
+ // remove msg from stack
257
+ stack = stack.slice(index + 1);
258
+
259
+ if (err.cause) {
260
+ seen = seen || new Set();
261
+ seen.add(err);
262
+ const causeStack = getFullErrorStack(err.cause, seen)
263
+ stack += '\n Caused by: ' + causeStack.msg + (causeStack.stack ? '\n' + causeStack.stack : '');
264
+ }
265
+ }
266
+
267
+ return {
268
+ message,
269
+ msg,
270
+ stack
271
+ };
272
+ };
273
+
224
274
  /**
225
275
  * Outputs the given `failures` as a list.
226
276
  *
@@ -241,7 +291,6 @@ exports.list = function (failures) {
241
291
  color('error stack', '\n%s\n');
242
292
 
243
293
  // msg
244
- var msg;
245
294
  var err;
246
295
  if (test.err && test.err.multiple) {
247
296
  if (multipleTest !== test) {
@@ -252,25 +301,8 @@ exports.list = function (failures) {
252
301
  } else {
253
302
  err = test.err;
254
303
  }
255
- var message;
256
- if (typeof err.inspect === 'function') {
257
- message = err.inspect() + '';
258
- } else if (err.message && typeof err.message.toString === 'function') {
259
- message = err.message + '';
260
- } else {
261
- message = '';
262
- }
263
- var stack = err.stack || message;
264
- var index = message ? stack.indexOf(message) : -1;
265
304
 
266
- if (index === -1) {
267
- msg = message;
268
- } else {
269
- index += message.length;
270
- msg = stack.slice(0, index);
271
- // remove msg from stack
272
- stack = stack.slice(index + 1);
273
- }
305
+ var { message, msg, stack } = getFullErrorStack(err);
274
306
 
275
307
  // uncaught
276
308
  if (err.uncaught) {
@@ -548,3 +580,12 @@ function sameType(a, b) {
548
580
  Base.consoleLog = consoleLog;
549
581
 
550
582
  Base.abstract = true;
583
+
584
+ /**
585
+ * An object with all stack traces recursively mounted from each err.cause
586
+ * @memberof module:lib/reporters/base
587
+ * @typedef {Object} FullErrorStack
588
+ * @property {string} message
589
+ * @property {string} msg
590
+ * @property {string} stack
591
+ */
@@ -66,7 +66,7 @@ function NyanCat(runner, options) {
66
66
  runner.once(EVENT_RUN_END, function () {
67
67
  Base.cursor.show();
68
68
  for (var i = 0; i < self.numberOfLines; i++) {
69
- write('\n');
69
+ process.stdout.write('\n');
70
70
  }
71
71
  self.epilogue();
72
72
  });
@@ -102,15 +102,15 @@ NyanCat.prototype.drawScoreboard = function () {
102
102
  var stats = this.stats;
103
103
 
104
104
  function draw(type, n) {
105
- write(' ');
106
- write(Base.color(type, n));
107
- write('\n');
105
+ process.stdout.write(' ');
106
+ process.stdout.write(Base.color(type, n));
107
+ process.stdout.write('\n');
108
108
  }
109
109
 
110
110
  draw('green', stats.passes);
111
111
  draw('fail', stats.failures);
112
112
  draw('pending', stats.pending);
113
- write('\n');
113
+ process.stdout.write('\n');
114
114
 
115
115
  this.cursorUp(this.numberOfLines);
116
116
  };
@@ -144,9 +144,9 @@ NyanCat.prototype.drawRainbow = function () {
144
144
  var self = this;
145
145
 
146
146
  this.trajectories.forEach(function (line) {
147
- write('\u001b[' + self.scoreboardWidth + 'C');
148
- write(line.join(''));
149
- write('\n');
147
+ process.stdout.write('\u001b[' + self.scoreboardWidth + 'C');
148
+ process.stdout.write(line.join(''));
149
+ process.stdout.write('\n');
150
150
  });
151
151
 
152
152
  this.cursorUp(this.numberOfLines);
@@ -163,25 +163,25 @@ NyanCat.prototype.drawNyanCat = function () {
163
163
  var dist = '\u001b[' + startWidth + 'C';
164
164
  var padding = '';
165
165
 
166
- write(dist);
167
- write('_,------,');
168
- write('\n');
166
+ process.stdout.write(dist);
167
+ process.stdout.write('_,------,');
168
+ process.stdout.write('\n');
169
169
 
170
- write(dist);
170
+ process.stdout.write(dist);
171
171
  padding = self.tick ? ' ' : ' ';
172
- write('_|' + padding + '/\\_/\\ ');
173
- write('\n');
172
+ process.stdout.write('_|' + padding + '/\\_/\\ ');
173
+ process.stdout.write('\n');
174
174
 
175
- write(dist);
175
+ process.stdout.write(dist);
176
176
  padding = self.tick ? '_' : '__';
177
177
  var tail = self.tick ? '~' : '^';
178
- write(tail + '|' + padding + this.face() + ' ');
179
- write('\n');
178
+ process.stdout.write(tail + '|' + padding + this.face() + ' ');
179
+ process.stdout.write('\n');
180
180
 
181
- write(dist);
181
+ process.stdout.write(dist);
182
182
  padding = self.tick ? ' ' : ' ';
183
- write(padding + '"" "" ');
184
- write('\n');
183
+ process.stdout.write(padding + '"" "" ');
184
+ process.stdout.write('\n');
185
185
 
186
186
  this.cursorUp(this.numberOfLines);
187
187
  };
@@ -213,7 +213,7 @@ NyanCat.prototype.face = function () {
213
213
  */
214
214
 
215
215
  NyanCat.prototype.cursorUp = function (n) {
216
- write('\u001b[' + n + 'A');
216
+ process.stdout.write('\u001b[' + n + 'A');
217
217
  };
218
218
 
219
219
  /**
@@ -224,7 +224,7 @@ NyanCat.prototype.cursorUp = function (n) {
224
224
  */
225
225
 
226
226
  NyanCat.prototype.cursorDown = function (n) {
227
- write('\u001b[' + n + 'B');
227
+ process.stdout.write('\u001b[' + n + 'B');
228
228
  };
229
229
 
230
230
  /**
@@ -264,13 +264,4 @@ NyanCat.prototype.rainbowify = function (str) {
264
264
  return '\u001b[38;5;' + color + 'm' + str + '\u001b[0m';
265
265
  };
266
266
 
267
- /**
268
- * Stdout helper.
269
- *
270
- * @param {string} string A message to write to stdout.
271
- */
272
- function write(string) {
273
- process.stdout.write(string);
274
- }
275
-
276
267
  NyanCat.description = '"nyan cat"';
@@ -158,6 +158,7 @@ XUnit.prototype.test = function (test) {
158
158
  var attrs = {
159
159
  classname: test.parent.fullTitle(),
160
160
  name: test.title,
161
+ file: test.file,
161
162
  time: test.duration / 1000 || 0
162
163
  };
163
164
 
package/lib/runnable.js CHANGED
@@ -211,7 +211,7 @@ Runnable.prototype.fullTitle = function () {
211
211
  *
212
212
  * @memberof Mocha.Runnable
213
213
  * @public
214
- * @return {string}
214
+ * @return {string[]}
215
215
  */
216
216
  Runnable.prototype.titlePath = function () {
217
217
  return this.parent.titlePath().concat([this.title]);
package/lib/runner.js CHANGED
@@ -443,11 +443,22 @@ Runner.prototype.fail = function (test, err, force) {
443
443
  err = thrown2Error(err);
444
444
  }
445
445
 
446
- try {
447
- err.stack =
448
- this.fullStackTrace || !err.stack ? err.stack : stackFilter(err.stack);
449
- } catch (ignore) {
450
- // some environments do not take kindly to monkeying with the stack
446
+ // Filter the stack traces
447
+ if (!this.fullStackTrace) {
448
+ const alreadyFiltered = new Set();
449
+ let currentErr = err;
450
+
451
+ while (currentErr && currentErr.stack && !alreadyFiltered.has(currentErr)) {
452
+ alreadyFiltered.add(currentErr);
453
+
454
+ try {
455
+ currentErr.stack = stackFilter(currentErr.stack);
456
+ } catch (ignore) {
457
+ // some environments do not take kindly to monkeying with the stack
458
+ }
459
+
460
+ currentErr = currentErr.cause;
461
+ }
451
462
  }
452
463
 
453
464
  this.emit(constants.EVENT_TEST_FAIL, test, err);
package/lib/suite.js CHANGED
@@ -387,7 +387,7 @@ Suite.prototype.fullTitle = function () {
387
387
  *
388
388
  * @memberof Suite
389
389
  * @public
390
- * @return {string}
390
+ * @return {string[]}
391
391
  */
392
392
  Suite.prototype.titlePath = function () {
393
393
  var result = [];
package/lib/utils.js CHANGED
@@ -8,8 +8,6 @@
8
8
  /**
9
9
  * Module dependencies.
10
10
  */
11
-
12
- const {nanoid} = require('nanoid/non-secure');
13
11
  var path = require('path');
14
12
  var util = require('util');
15
13
  var he = require('he');
@@ -615,11 +613,22 @@ exports.constants = exports.defineConstants({
615
613
  MOCHA_ID_PROP_NAME
616
614
  });
617
615
 
616
+ const uniqueIDBase =
617
+ 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_';
618
+
618
619
  /**
619
620
  * Creates a new unique identifier
621
+ * Does not create cryptographically safe ids.
622
+ * Trivial copy of nanoid/non-secure
620
623
  * @returns {string} Unique identifier
621
624
  */
622
- exports.uniqueID = () => nanoid();
625
+ exports.uniqueID = () => {
626
+ let id = '';
627
+ for (let i = 0; i < 21; i++) {
628
+ id += uniqueIDBase[(Math.random() * 64) | 0];
629
+ }
630
+ return id;
631
+ };
623
632
 
624
633
  exports.assignNewMochaID = obj => {
625
634
  const id = exports.uniqueID();