mocha 10.3.0 → 10.5.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
@@ -5,7 +5,7 @@
5
5
  <p align="center">☕️ Simple, flexible, fun JavaScript test framework for Node.js & The Browser ☕️</p>
6
6
 
7
7
  <p align="center">
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>
8
+ <a href="https://github.com/mochajs/mocha/actions?query=workflow%3ATests+branch%3Amain"><img src="https://github.com/mochajs/mocha/workflows/Tests/badge.svg?branch=main" 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
11
  <a href="https://discord.gg/KeDn2uXhER"><img alt="Chat - Discord" src="https://img.shields.io/badge/chat-Discord-5765F2.svg" /></a>
@@ -23,10 +23,10 @@
23
23
  ## Links
24
24
 
25
25
  - **[Documentation](https://mochajs.org)**
26
- - **[Release Notes / History / Changes](https://github.com/mochajs/mocha/blob/master/CHANGELOG.md)**
27
- - [Code of Conduct](https://github.com/mochajs/mocha/blob/master/.github/CODE_OF_CONDUCT.md)
28
- - [Contributing](https://github.com/mochajs/mocha/blob/master/.github/CONTRIBUTING.md)
29
- - [Development](https://github.com/mochajs/mocha/blob/master/.github/DEVELOPMENT.md)
26
+ - **[Release Notes / History / Changes](https://github.com/mochajs/mocha/blob/main/CHANGELOG.md)**
27
+ - [Code of Conduct](https://github.com/mochajs/mocha/blob/main/.github/CODE_OF_CONDUCT.md)
28
+ - [Contributing](https://github.com/mochajs/mocha/blob/main/.github/CONTRIBUTING.md)
29
+ - [Development](https://github.com/mochajs/mocha/blob/main/.github/DEVELOPMENT.md)
30
30
  - [Discord](https://discord.gg/KeDn2uXhER) (ask questions here!)
31
31
  - [Issue Tracker](https://github.com/mochajs/mocha/issues)
32
32
 
@@ -59,7 +59,7 @@ You might want to help:
59
59
 
60
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
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)
62
- - The [maintainer's handbook](https://github.com/mochajs/mocha/blob/master/MAINTAINERS.md) explains how things get done
62
+ - The [maintainer's handbook](https://github.com/mochajs/mocha/blob/main/MAINTAINERS.md) explains how things get done
63
63
 
64
64
  Finally, come [chat with the maintainers on Discord](https://discord.gg/KeDn2uXhER) if you want to help with:
65
65
 
@@ -69,6 +69,6 @@ Finally, come [chat with the maintainers on Discord](https://discord.gg/KeDn2uXh
69
69
 
70
70
  ## License
71
71
 
72
- Copyright 2011-2022 OpenJS Foundation and contributors. Licensed [MIT](https://github.com/mochajs/mocha/blob/master/LICENSE).
72
+ Copyright 2011-2022 OpenJS Foundation and contributors. Licensed [MIT](https://github.com/mochajs/mocha/blob/main/LICENSE).
73
73
 
74
74
  [![FOSSA Status](https://app.fossa.io/api/projects/git%2Bhttps%3A%2F%2Fgithub.com%2Fmochajs%2Fmocha.svg?type=large)](https://app.fossa.io/projects/git%2Bhttps%3A%2F%2Fgithub.com%2Fmochajs%2Fmocha?ref=badge_large)
package/browser-entry.js CHANGED
@@ -71,8 +71,8 @@ process.listenerCount = function (name) {
71
71
 
72
72
  process.on = function (e, fn) {
73
73
  if (e === 'uncaughtException') {
74
- global.onerror = function (err, url, line) {
75
- fn(new Error(err + ' (' + url + ':' + line + ')'));
74
+ global.onerror = function (msg, url, line, col, err) {
75
+ fn(err || new Error(msg + ' (' + url + ':' + line + ':' + col + ')'));
76
76
  return !mocha.options.allowUncaught;
77
77
  };
78
78
  uncaughtExceptionHandlers.push(fn);
@@ -208,9 +208,10 @@ module.exports.loadPkgRc = loadPkgRc;
208
208
  * Priority list:
209
209
  *
210
210
  * 1. Command-line args
211
- * 2. RC file (`.mocharc.c?js`, `.mocharc.ya?ml`, `mocharc.json`)
212
- * 3. `mocha` prop of `package.json`
213
- * 4. default configuration (`lib/mocharc.json`)
211
+ * 2. `MOCHA_OPTIONS` environment variable.
212
+ * 3. RC file (`.mocharc.c?js`, `.mocharc.ya?ml`, `mocharc.json`)
213
+ * 4. `mocha` prop of `package.json`
214
+ * 5. default configuration (`lib/mocharc.json`)
214
215
  *
215
216
  * If a {@link module:lib/cli/one-and-dones.ONE_AND_DONE_ARGS "one-and-done" option} is present in the `argv` array, no external config files will be read.
216
217
  * @summary Parses options read from `.mocharc.*` and `package.json`.
@@ -231,6 +232,7 @@ const loadOptions = (argv = []) => {
231
232
  return args;
232
233
  }
233
234
 
235
+ const envConfig = parse(process.env.MOCHA_OPTIONS || '');
234
236
  const rcConfig = loadRc(args);
235
237
  const pkgConfig = loadPkgRc(args);
236
238
 
@@ -243,7 +245,14 @@ const loadOptions = (argv = []) => {
243
245
  args._ = args._.concat(pkgConfig._ || []);
244
246
  }
245
247
 
246
- args = parse(args._, mocharc, args, rcConfig || {}, pkgConfig || {});
248
+ args = parse(
249
+ args._,
250
+ mocharc,
251
+ args,
252
+ envConfig,
253
+ rcConfig || {},
254
+ pkgConfig || {}
255
+ );
247
256
 
248
257
  // recombine positional arguments and "spec"
249
258
  if (args.spec) {
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
  };
@@ -54,7 +54,7 @@ const ONCE_EVENT_NAMES = [EVENT_DELAY_BEGIN, EVENT_DELAY_END];
54
54
 
55
55
  /**
56
56
  * The `ParallelBuffered` reporter is used by each worker process in "parallel"
57
- * mode, by default. Instead of reporting to to `STDOUT`, etc., it retains a
57
+ * mode, by default. Instead of reporting to `STDOUT`, etc., it retains a
58
58
  * list of events it receives and hands these off to the callback passed into
59
59
  * {@link Mocha#run}. That callback will then return the data to the main
60
60
  * process.
@@ -117,7 +117,7 @@ class SerializableEvent {
117
117
  /**
118
118
  * Constructs a `SerializableEvent`, throwing if we receive unexpected data.
119
119
  *
120
- * Practically, events emitted from `Runner` have a minumum of zero (0)
120
+ * Practically, events emitted from `Runner` have a minimum of zero (0)
121
121
  * arguments-- (for example, {@link Runnable.constants.EVENT_RUN_BEGIN}) and a
122
122
  * maximum of two (2) (for example,
123
123
  * {@link Runnable.constants.EVENT_TEST_FAIL}, where the second argument is an
@@ -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
+ */
@@ -10,7 +10,6 @@
10
10
 
11
11
  var Base = require('./base');
12
12
  var utils = require('../utils');
13
- var Progress = require('../browser/progress');
14
13
  var escapeRe = require('escape-string-regexp');
15
14
  var constants = require('../runner').constants;
16
15
  var EVENT_TEST_PASS = constants.EVENT_TEST_PASS;
@@ -38,7 +37,7 @@ exports = module.exports = HTML;
38
37
 
39
38
  var statsTemplate =
40
39
  '<ul id="mocha-stats">' +
41
- '<li class="progress"><canvas width="40" height="40"></canvas></li>' +
40
+ '<li class="progress-contain"><progress class="progress-element" max="100" value="0"></progress><svg class="progress-ring"><circle class="ring-flatlight" stroke-dasharray="100%,0%"/><circle class="ring-highlight" stroke-dasharray="0%,100%"/></svg><div class="progress-text">0%</div></li>' +
42
41
  '<li class="passes"><a href="javascript:void(0);">passes:</a> <em>0</em></li>' +
43
42
  '<li class="failures"><a href="javascript:void(0);">failures:</a> <em>0</em></li>' +
44
43
  '<li class="duration">duration: <em>0</em>s</li>' +
@@ -68,24 +67,16 @@ function HTML(runner, options) {
68
67
  var failures = items[2].getElementsByTagName('em')[0];
69
68
  var failuresLink = items[2].getElementsByTagName('a')[0];
70
69
  var duration = items[3].getElementsByTagName('em')[0];
71
- var canvas = stat.getElementsByTagName('canvas')[0];
72
70
  var report = fragment('<ul id="mocha-report"></ul>');
73
71
  var stack = [report];
74
- var progress;
75
- var ctx;
72
+ var progressText = items[0].getElementsByTagName('div')[0];
73
+ var progressBar = items[0].getElementsByTagName('progress')[0];
74
+ var progressRing = [
75
+ items[0].getElementsByClassName('ring-flatlight')[0],
76
+ items[0].getElementsByClassName('ring-highlight')[0]];
77
+ var progressRingRadius = null; // computed CSS unavailable now, so set later
76
78
  var root = document.getElementById('mocha');
77
79
 
78
- if (canvas.getContext) {
79
- var ratio = window.devicePixelRatio || 1;
80
- canvas.style.width = canvas.width;
81
- canvas.style.height = canvas.height;
82
- canvas.width *= ratio;
83
- canvas.height *= ratio;
84
- ctx = canvas.getContext('2d');
85
- ctx.scale(ratio, ratio);
86
- progress = new Progress();
87
- }
88
-
89
80
  if (!root) {
90
81
  return error('#mocha div missing, add it to your document');
91
82
  }
@@ -115,10 +106,6 @@ function HTML(runner, options) {
115
106
  root.appendChild(stat);
116
107
  root.appendChild(report);
117
108
 
118
- if (progress) {
119
- progress.size(40);
120
- }
121
-
122
109
  runner.on(EVENT_SUITE_BEGIN, function (suite) {
123
110
  if (suite.root) {
124
111
  return;
@@ -234,8 +221,26 @@ function HTML(runner, options) {
234
221
  function updateStats() {
235
222
  // TODO: add to stats
236
223
  var percent = ((stats.tests / runner.total) * 100) | 0;
237
- if (progress) {
238
- progress.update(percent).draw(ctx);
224
+ progressBar.value = percent;
225
+ if (progressText) {
226
+ // setting a toFixed that is too low, makes small changes to progress not shown
227
+ // setting it too high, makes the progress text longer then it needs to
228
+ // to address this, calculate the toFixed based on the magnitude of total
229
+ var decimalPlaces = Math.ceil(Math.log10(runner.total / 100));
230
+ text(
231
+ progressText,
232
+ percent.toFixed(Math.min(Math.max(decimalPlaces, 0), 100)) + '%'
233
+ );
234
+ }
235
+ if (progressRing) {
236
+ var radius = parseFloat(getComputedStyle(progressRing[0]).getPropertyValue('r'));
237
+ var wholeArc = Math.PI * 2 * radius;
238
+ var highlightArc = percent * (wholeArc / 100);
239
+ // The progress ring is in 2 parts, the flatlight color and highlight color.
240
+ // Rendering both on top of the other, seems to make a 3rd color on the edges.
241
+ // To create 1 whole ring with 2 colors, both parts are inverse of the other.
242
+ progressRing[0].style['stroke-dasharray'] = `0,${highlightArc}px,${wholeArc}px`;
243
+ progressRing[1].style['stroke-dasharray'] = `${highlightArc}px,${wholeArc}px`;
239
244
  }
240
245
 
241
246
  // update stats
@@ -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/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/mocha.css CHANGED
@@ -22,6 +22,9 @@
22
22
  --mocha-stats-color: #888;
23
23
  --mocha-stats-em-color: #000;
24
24
  --mocha-stats-hover-color: #eee;
25
+ --mocha-progress-ring-color: #eee;
26
+ --mocha-progress-ring-highlight-color: #9f9f9f;
27
+ --mocha-progress-text-color: #000;
25
28
  --mocha-error-color: #c00;
26
29
 
27
30
  --mocha-code-comment: #ddd;
@@ -54,6 +57,9 @@
54
57
  --mocha-stats-color: #aaa;
55
58
  --mocha-stats-em-color: #fff;
56
59
  --mocha-stats-hover-color: #444;
60
+ --mocha-progress-ring-color: #444;
61
+ --mocha-progress-ring-highlight-color: #888;
62
+ --mocha-progress-text-color: #fff;
57
63
  --mocha-error-color: #f44;
58
64
 
59
65
  --mocha-code-comment: #ddd;
@@ -325,6 +331,10 @@ body {
325
331
  }
326
332
 
327
333
  #mocha-stats {
334
+ --ring-container-size: 40px;
335
+ --ring-size: 39px;
336
+ --ring-radius: calc(var(--ring-size) / 2);
337
+
328
338
  position: fixed;
329
339
  top: 15px;
330
340
  right: 10px;
@@ -334,20 +344,52 @@ body {
334
344
  z-index: 1;
335
345
  }
336
346
 
337
- #mocha-stats .progress {
347
+ #mocha-stats .progress-contain {
338
348
  float: right;
339
- padding-top: 0;
349
+ padding: 0;
350
+ }
351
+
352
+ #mocha-stats :is(.progress-element, .progress-text) {
353
+ width: var(--ring-container-size);
354
+ display: block;
355
+ top: 12px;
356
+ position: absolute;
357
+ }
358
+
359
+ #mocha-stats .progress-element {
360
+ visibility: hidden;
361
+ height: calc(var(--ring-container-size) / 2);
362
+ }
363
+
364
+ #mocha-stats .progress-text {
365
+ text-align: center;
366
+ text-overflow: clip;
367
+ overflow: hidden;
368
+ color: var(--mocha-stats-em-color);
369
+ font-size: 11px;
370
+ }
340
371
 
341
- /**
342
- * Set safe initial values, so mochas .progress does not inherit these
343
- * properties from Bootstrap .progress (which causes .progress height to
344
- * equal line height set in Bootstrap).
345
- */
346
- height: auto;
347
- -webkit-box-shadow: none;
348
- -moz-box-shadow: none;
349
- box-shadow: none;
350
- background-color: initial;
372
+ #mocha-stats .progress-ring {
373
+ width: var(--ring-container-size);
374
+ height: var(--ring-container-size);
375
+ }
376
+
377
+ #mocha-stats :is(.ring-flatlight, .ring-highlight) {
378
+ --stroke-thickness: 1.65px;
379
+ --center: calc(var(--ring-container-size) / 2);
380
+ cx: var(--center);
381
+ cy: var(--center);
382
+ r: calc(var(--ring-radius) - calc(var(--stroke-thickness) / 2));
383
+ fill: hsla(0, 0%, 0%, 0);
384
+ stroke-width: var(--stroke-thickness);
385
+ }
386
+
387
+ #mocha-stats .ring-flatlight {
388
+ stroke: var(--mocha-progress-ring-color);
389
+ }
390
+
391
+ #mocha-stats .ring-highlight {
392
+ stroke: var(--mocha-progress-ring-highlight-color);
351
393
  }
352
394
 
353
395
  #mocha-stats em {
@@ -370,11 +412,6 @@ body {
370
412
  padding-top: 11px;
371
413
  }
372
414
 
373
- #mocha-stats canvas {
374
- width: 40px;
375
- height: 40px;
376
- }
377
-
378
415
  #mocha code .comment { color: var(--mocha-code-comment); }
379
416
  #mocha code .init { color: var(--mocha-code-init); }
380
417
  #mocha code .string { color: var(--mocha-code-string); }