mocha 9.1.1 → 9.2.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 (47) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +1 -1
  3. package/browser-entry.js +27 -20
  4. package/lib/browser/growl.js +5 -5
  5. package/lib/browser/parse-query.js +1 -1
  6. package/lib/browser/progress.js +6 -6
  7. package/lib/cli/one-and-dones.js +1 -2
  8. package/lib/cli/run-helpers.js +1 -1
  9. package/lib/cli/run.js +1 -1
  10. package/lib/cli/watch-run.js +3 -6
  11. package/lib/context.js +5 -5
  12. package/lib/errors.js +1 -1
  13. package/lib/hook.js +2 -2
  14. package/lib/interfaces/bdd.js +23 -20
  15. package/lib/interfaces/common.js +7 -7
  16. package/lib/interfaces/exports.js +1 -1
  17. package/lib/interfaces/qunit.js +7 -7
  18. package/lib/interfaces/tdd.js +9 -9
  19. package/lib/mocha.js +57 -67
  20. package/lib/nodejs/buffered-worker-pool.js +17 -1
  21. package/lib/{esm-utils.js → nodejs/esm-utils.js} +18 -3
  22. package/lib/reporters/base.js +18 -21
  23. package/lib/reporters/doc.js +4 -4
  24. package/lib/reporters/dot.js +5 -5
  25. package/lib/reporters/html.js +12 -12
  26. package/lib/reporters/json-stream.js +4 -4
  27. package/lib/reporters/json.js +7 -7
  28. package/lib/reporters/landing.js +5 -5
  29. package/lib/reporters/list.js +5 -5
  30. package/lib/reporters/markdown.js +5 -5
  31. package/lib/reporters/min.js +1 -1
  32. package/lib/reporters/nyan.js +16 -16
  33. package/lib/reporters/progress.js +3 -3
  34. package/lib/reporters/spec.js +6 -6
  35. package/lib/reporters/tap.js +17 -17
  36. package/lib/reporters/xunit.js +9 -9
  37. package/lib/runnable.js +21 -21
  38. package/lib/runner.js +44 -47
  39. package/lib/stats-collector.js +7 -7
  40. package/lib/suite.js +44 -73
  41. package/lib/test.js +4 -4
  42. package/lib/utils.js +19 -46
  43. package/mocha-es2018.js +435 -492
  44. package/mocha.js +1545 -1050
  45. package/mocha.js.map +1 -1
  46. package/package.json +50 -52
  47. package/CHANGELOG.md +0 -1004
package/lib/mocha.js CHANGED
@@ -13,9 +13,7 @@ var growl = require('./nodejs/growl');
13
13
  var utils = require('./utils');
14
14
  var mocharc = require('./mocharc.json');
15
15
  var Suite = require('./suite');
16
- var esmUtils = utils.supportsEsModules(true)
17
- ? require('./esm-utils')
18
- : undefined;
16
+ var esmUtils = require('./nodejs/esm-utils');
19
17
  var createStatsCollector = require('./stats-collector');
20
18
  const {
21
19
  warn,
@@ -25,11 +23,8 @@ const {
25
23
  createMochaInstanceAlreadyRunningError,
26
24
  createUnsupportedError
27
25
  } = require('./errors');
28
- const {
29
- EVENT_FILE_PRE_REQUIRE,
30
- EVENT_FILE_POST_REQUIRE,
31
- EVENT_FILE_REQUIRE
32
- } = Suite.constants;
26
+ const {EVENT_FILE_PRE_REQUIRE, EVENT_FILE_POST_REQUIRE, EVENT_FILE_REQUIRE} =
27
+ Suite.constants;
33
28
  var debug = require('debug')('mocha:mocha');
34
29
 
35
30
  exports = module.exports = Mocha;
@@ -96,46 +91,46 @@ exports.Hook = require('./hook');
96
91
  exports.Test = require('./test');
97
92
 
98
93
  let currentContext;
99
- exports.afterEach = function(...args) {
94
+ exports.afterEach = function (...args) {
100
95
  return (currentContext.afterEach || currentContext.teardown).apply(
101
96
  this,
102
97
  args
103
98
  );
104
99
  };
105
- exports.after = function(...args) {
100
+ exports.after = function (...args) {
106
101
  return (currentContext.after || currentContext.suiteTeardown).apply(
107
102
  this,
108
103
  args
109
104
  );
110
105
  };
111
- exports.beforeEach = function(...args) {
106
+ exports.beforeEach = function (...args) {
112
107
  return (currentContext.beforeEach || currentContext.setup).apply(this, args);
113
108
  };
114
- exports.before = function(...args) {
109
+ exports.before = function (...args) {
115
110
  return (currentContext.before || currentContext.suiteSetup).apply(this, args);
116
111
  };
117
- exports.describe = function(...args) {
112
+ exports.describe = function (...args) {
118
113
  return (currentContext.describe || currentContext.suite).apply(this, args);
119
114
  };
120
- exports.describe.only = function(...args) {
115
+ exports.describe.only = function (...args) {
121
116
  return (currentContext.describe || currentContext.suite).only.apply(
122
117
  this,
123
118
  args
124
119
  );
125
120
  };
126
- exports.describe.skip = function(...args) {
121
+ exports.describe.skip = function (...args) {
127
122
  return (currentContext.describe || currentContext.suite).skip.apply(
128
123
  this,
129
124
  args
130
125
  );
131
126
  };
132
- exports.it = function(...args) {
127
+ exports.it = function (...args) {
133
128
  return (currentContext.it || currentContext.test).apply(this, args);
134
129
  };
135
- exports.it.only = function(...args) {
130
+ exports.it.only = function (...args) {
136
131
  return (currentContext.it || currentContext.test).only.apply(this, args);
137
132
  };
138
- exports.it.skip = function(...args) {
133
+ exports.it.skip = function (...args) {
139
134
  return (currentContext.it || currentContext.test).skip.apply(this, args);
140
135
  };
141
136
  exports.xdescribe = exports.describe.skip;
@@ -146,7 +141,7 @@ exports.suiteTeardown = exports.after;
146
141
  exports.suite = exports.describe;
147
142
  exports.teardown = exports.afterEach;
148
143
  exports.test = exports.it;
149
- exports.run = function(...args) {
144
+ exports.run = function (...args) {
150
145
  return currentContext.run.apply(this, args);
151
146
  };
152
147
 
@@ -231,7 +226,7 @@ function Mocha(options = {}) {
231
226
  'growl',
232
227
  'inlineDiffs',
233
228
  'invert'
234
- ].forEach(function(opt) {
229
+ ].forEach(function (opt) {
235
230
  if (options[opt]) {
236
231
  this[opt]();
237
232
  }
@@ -289,7 +284,7 @@ function Mocha(options = {}) {
289
284
  * @returns {Mocha} this
290
285
  * @chainable
291
286
  */
292
- Mocha.prototype.bail = function(bail) {
287
+ Mocha.prototype.bail = function (bail) {
293
288
  this.suite.bail(bail !== false);
294
289
  return this;
295
290
  };
@@ -307,7 +302,7 @@ Mocha.prototype.bail = function(bail) {
307
302
  * @returns {Mocha} this
308
303
  * @chainable
309
304
  */
310
- Mocha.prototype.addFile = function(file) {
305
+ Mocha.prototype.addFile = function (file) {
311
306
  this.files.push(file);
312
307
  return this;
313
308
  };
@@ -328,7 +323,7 @@ Mocha.prototype.addFile = function(file) {
328
323
  * // Use XUnit reporter and direct its output to file
329
324
  * mocha.reporter('xunit', { output: '/path/to/testspec.xunit.xml' });
330
325
  */
331
- Mocha.prototype.reporter = function(reporterName, reporterOptions) {
326
+ Mocha.prototype.reporter = function (reporterName, reporterOptions) {
332
327
  if (typeof reporterName === 'function') {
333
328
  this._reporter = reporterName;
334
329
  } else {
@@ -384,7 +379,7 @@ Mocha.prototype.reporter = function(reporterName, reporterOptions) {
384
379
  * @chainable
385
380
  * @throws {Error} if requested interface cannot be loaded
386
381
  */
387
- Mocha.prototype.ui = function(ui) {
382
+ Mocha.prototype.ui = function (ui) {
388
383
  var bindInterface;
389
384
  if (typeof ui === 'function') {
390
385
  bindInterface = ui;
@@ -401,7 +396,7 @@ Mocha.prototype.ui = function(ui) {
401
396
  }
402
397
  bindInterface(this.suite);
403
398
 
404
- this.suite.on(EVENT_FILE_PRE_REQUIRE, function(context) {
399
+ this.suite.on(EVENT_FILE_PRE_REQUIRE, function (context) {
405
400
  currentContext = context;
406
401
  });
407
402
 
@@ -423,10 +418,10 @@ Mocha.prototype.ui = function(ui) {
423
418
  * @see {@link Mocha#loadFilesAsync}
424
419
  * @param {Function} [fn] - Callback invoked upon completion.
425
420
  */
426
- Mocha.prototype.loadFiles = function(fn) {
421
+ Mocha.prototype.loadFiles = function (fn) {
427
422
  var self = this;
428
423
  var suite = this.suite;
429
- this.files.forEach(function(file) {
424
+ this.files.forEach(function (file) {
430
425
  file = path.resolve(file);
431
426
  suite.emit(EVENT_FILE_PRE_REQUIRE, global, file, self);
432
427
  suite.emit(EVENT_FILE_REQUIRE, require(file), file, self);
@@ -455,23 +450,17 @@ Mocha.prototype.loadFiles = function(fn) {
455
450
  * .then(() => mocha.run(failures => process.exitCode = failures ? 1 : 0))
456
451
  * .catch(() => process.exitCode = 1);
457
452
  */
458
- Mocha.prototype.loadFilesAsync = function() {
453
+ Mocha.prototype.loadFilesAsync = function () {
459
454
  var self = this;
460
455
  var suite = this.suite;
461
456
  this.lazyLoadFiles(true);
462
457
 
463
- if (!esmUtils) {
464
- return new Promise(function(resolve) {
465
- self.loadFiles(resolve);
466
- });
467
- }
468
-
469
458
  return esmUtils.loadFilesAsync(
470
459
  this.files,
471
- function(file) {
460
+ function (file) {
472
461
  suite.emit(EVENT_FILE_PRE_REQUIRE, global, file, self);
473
462
  },
474
- function(file, resultModule) {
463
+ function (file, resultModule) {
475
464
  suite.emit(EVENT_FILE_REQUIRE, resultModule, file, self);
476
465
  suite.emit(EVENT_FILE_POST_REQUIRE, global, file, self);
477
466
  }
@@ -486,7 +475,7 @@ Mocha.prototype.loadFilesAsync = function() {
486
475
  * @see {@link Mocha#unloadFiles}
487
476
  * @param {string} file - Pathname of file to be unloaded.
488
477
  */
489
- Mocha.unloadFile = function(file) {
478
+ Mocha.unloadFile = function (file) {
490
479
  if (utils.isBrowser()) {
491
480
  throw createUnsupportedError(
492
481
  'unloadFile() is only suported in a Node.js environment'
@@ -510,7 +499,7 @@ Mocha.unloadFile = function(file) {
510
499
  * @returns {Mocha} this
511
500
  * @chainable
512
501
  */
513
- Mocha.prototype.unloadFiles = function() {
502
+ Mocha.prototype.unloadFiles = function () {
514
503
  if (this._state === mochaStates.DISPOSED) {
515
504
  throw createMochaInstanceAlreadyDisposedError(
516
505
  'Mocha instance is already disposed, it cannot be used again.',
@@ -519,7 +508,7 @@ Mocha.prototype.unloadFiles = function() {
519
508
  );
520
509
  }
521
510
 
522
- this.files.forEach(function(file) {
511
+ this.files.forEach(function (file) {
523
512
  Mocha.unloadFile(file);
524
513
  });
525
514
  this._state = mochaStates.INIT;
@@ -539,7 +528,7 @@ Mocha.prototype.unloadFiles = function() {
539
528
  * // Select tests whose full title begins with `"foo"` followed by a period
540
529
  * mocha.fgrep('foo.');
541
530
  */
542
- Mocha.prototype.fgrep = function(str) {
531
+ Mocha.prototype.fgrep = function (str) {
543
532
  if (!str) {
544
533
  return this;
545
534
  }
@@ -580,7 +569,7 @@ Mocha.prototype.fgrep = function(str) {
580
569
  * // Given embedded test `it('only-this-test')`...
581
570
  * mocha.grep('/^only-this-test$/'); // NO! Use `.only()` to do this!
582
571
  */
583
- Mocha.prototype.grep = function(re) {
572
+ Mocha.prototype.grep = function (re) {
584
573
  if (utils.isString(re)) {
585
574
  // extract args if it's regex-like, i.e: [string, pattern, flag]
586
575
  var arg = re.match(/^\/(.*)\/([gimy]{0,4})$|.*/);
@@ -603,7 +592,7 @@ Mocha.prototype.grep = function(re) {
603
592
  * // Select tests whose full title does *not* contain `"match"`, ignoring case
604
593
  * mocha.grep(/match/i).invert();
605
594
  */
606
- Mocha.prototype.invert = function() {
595
+ Mocha.prototype.invert = function () {
607
596
  this.options.invert = true;
608
597
  return this;
609
598
  };
@@ -617,7 +606,7 @@ Mocha.prototype.invert = function() {
617
606
  * @return {Mocha} this
618
607
  * @chainable
619
608
  */
620
- Mocha.prototype.checkLeaks = function(checkLeaks) {
609
+ Mocha.prototype.checkLeaks = function (checkLeaks) {
621
610
  this.options.checkLeaks = checkLeaks !== false;
622
611
  return this;
623
612
  };
@@ -632,7 +621,7 @@ Mocha.prototype.checkLeaks = function(checkLeaks) {
632
621
  * @return {Mocha} this
633
622
  * @chainable
634
623
  */
635
- Mocha.prototype.cleanReferencesAfterRun = function(cleanReferencesAfterRun) {
624
+ Mocha.prototype.cleanReferencesAfterRun = function (cleanReferencesAfterRun) {
636
625
  this._cleanReferencesAfterRun = cleanReferencesAfterRun !== false;
637
626
  return this;
638
627
  };
@@ -642,7 +631,7 @@ Mocha.prototype.cleanReferencesAfterRun = function(cleanReferencesAfterRun) {
642
631
  * It also removes function references to tests functions and hooks, so variables trapped in closures can be cleaned by the garbage collector.
643
632
  * @public
644
633
  */
645
- Mocha.prototype.dispose = function() {
634
+ Mocha.prototype.dispose = function () {
646
635
  if (this._state === mochaStates.RUNNING) {
647
636
  throw createMochaInstanceAlreadyRunningError(
648
637
  'Cannot dispose while the mocha instance is still running tests.'
@@ -663,7 +652,7 @@ Mocha.prototype.dispose = function() {
663
652
  * @return {Mocha} this
664
653
  * @chainable
665
654
  */
666
- Mocha.prototype.fullTrace = function(fullTrace) {
655
+ Mocha.prototype.fullTrace = function (fullTrace) {
667
656
  this.options.fullTrace = fullTrace !== false;
668
657
  return this;
669
658
  };
@@ -676,7 +665,7 @@ Mocha.prototype.fullTrace = function(fullTrace) {
676
665
  * @return {Mocha} this
677
666
  * @chainable
678
667
  */
679
- Mocha.prototype.growl = function() {
668
+ Mocha.prototype.growl = function () {
680
669
  this.options.growl = this.isGrowlCapable();
681
670
  if (!this.options.growl) {
682
671
  var detail = utils.isBrowser()
@@ -725,11 +714,11 @@ Mocha.prototype._growl = growl.notify;
725
714
  * // Specify variables to be expected in global scope
726
715
  * mocha.global(['jQuery', 'MyLib']);
727
716
  */
728
- Mocha.prototype.global = function(global) {
717
+ Mocha.prototype.global = function (global) {
729
718
  this.options.global = (this.options.global || [])
730
719
  .concat(global)
731
720
  .filter(Boolean)
732
- .filter(function(elt, idx, arr) {
721
+ .filter(function (elt, idx, arr) {
733
722
  return arr.indexOf(elt) === idx;
734
723
  });
735
724
  return this;
@@ -746,7 +735,7 @@ Mocha.prototype.globals = Mocha.prototype.global;
746
735
  * @return {Mocha} this
747
736
  * @chainable
748
737
  */
749
- Mocha.prototype.color = function(color) {
738
+ Mocha.prototype.color = function (color) {
750
739
  this.options.color = color !== false;
751
740
  return this;
752
741
  };
@@ -761,7 +750,7 @@ Mocha.prototype.color = function(color) {
761
750
  * @return {Mocha} this
762
751
  * @chainable
763
752
  */
764
- Mocha.prototype.inlineDiffs = function(inlineDiffs) {
753
+ Mocha.prototype.inlineDiffs = function (inlineDiffs) {
765
754
  this.options.inlineDiffs = inlineDiffs !== false;
766
755
  return this;
767
756
  };
@@ -775,7 +764,7 @@ Mocha.prototype.inlineDiffs = function(inlineDiffs) {
775
764
  * @return {Mocha} this
776
765
  * @chainable
777
766
  */
778
- Mocha.prototype.diff = function(diff) {
767
+ Mocha.prototype.diff = function (diff) {
779
768
  this.options.diff = diff !== false;
780
769
  return this;
781
770
  };
@@ -803,7 +792,7 @@ Mocha.prototype.diff = function(diff) {
803
792
  * // Same as above but using string argument
804
793
  * mocha.timeout('1s');
805
794
  */
806
- Mocha.prototype.timeout = function(msecs) {
795
+ Mocha.prototype.timeout = function (msecs) {
807
796
  this.suite.timeout(msecs);
808
797
  return this;
809
798
  };
@@ -822,7 +811,7 @@ Mocha.prototype.timeout = function(msecs) {
822
811
  * // Allow any failed test to retry one more time
823
812
  * mocha.retries(1);
824
813
  */
825
- Mocha.prototype.retries = function(retry) {
814
+ Mocha.prototype.retries = function (retry) {
826
815
  this.suite.retries(retry);
827
816
  return this;
828
817
  };
@@ -844,7 +833,7 @@ Mocha.prototype.retries = function(retry) {
844
833
  * // Same as above but using string argument
845
834
  * mocha.slow('0.5s');
846
835
  */
847
- Mocha.prototype.slow = function(msecs) {
836
+ Mocha.prototype.slow = function (msecs) {
848
837
  this.suite.slow(msecs);
849
838
  return this;
850
839
  };
@@ -858,7 +847,7 @@ Mocha.prototype.slow = function(msecs) {
858
847
  * @return {Mocha} this
859
848
  * @chainable
860
849
  */
861
- Mocha.prototype.asyncOnly = function(asyncOnly) {
850
+ Mocha.prototype.asyncOnly = function (asyncOnly) {
862
851
  this.options.asyncOnly = asyncOnly !== false;
863
852
  return this;
864
853
  };
@@ -870,7 +859,7 @@ Mocha.prototype.asyncOnly = function(asyncOnly) {
870
859
  * @return {Mocha} this
871
860
  * @chainable
872
861
  */
873
- Mocha.prototype.noHighlighting = function() {
862
+ Mocha.prototype.noHighlighting = function () {
874
863
  this.options.noHighlighting = true;
875
864
  return this;
876
865
  };
@@ -884,7 +873,7 @@ Mocha.prototype.noHighlighting = function() {
884
873
  * @return {Mocha} this
885
874
  * @chainable
886
875
  */
887
- Mocha.prototype.allowUncaught = function(allowUncaught) {
876
+ Mocha.prototype.allowUncaught = function (allowUncaught) {
888
877
  this.options.allowUncaught = allowUncaught !== false;
889
878
  return this;
890
879
  };
@@ -915,7 +904,7 @@ Mocha.prototype.delay = function delay() {
915
904
  * @return {Mocha} this
916
905
  * @chainable
917
906
  */
918
- Mocha.prototype.dryRun = function(dryRun) {
907
+ Mocha.prototype.dryRun = function (dryRun) {
919
908
  this.options.dryRun = dryRun !== false;
920
909
  return this;
921
910
  };
@@ -929,7 +918,7 @@ Mocha.prototype.dryRun = function(dryRun) {
929
918
  * @return {Mocha} this
930
919
  * @chainable
931
920
  */
932
- Mocha.prototype.failZero = function(failZero) {
921
+ Mocha.prototype.failZero = function (failZero) {
933
922
  this.options.failZero = failZero !== false;
934
923
  return this;
935
924
  };
@@ -943,7 +932,7 @@ Mocha.prototype.failZero = function(failZero) {
943
932
  * @returns {Mocha} this
944
933
  * @chainable
945
934
  */
946
- Mocha.prototype.forbidOnly = function(forbidOnly) {
935
+ Mocha.prototype.forbidOnly = function (forbidOnly) {
947
936
  this.options.forbidOnly = forbidOnly !== false;
948
937
  return this;
949
938
  };
@@ -957,7 +946,7 @@ Mocha.prototype.forbidOnly = function(forbidOnly) {
957
946
  * @returns {Mocha} this
958
947
  * @chainable
959
948
  */
960
- Mocha.prototype.forbidPending = function(forbidPending) {
949
+ Mocha.prototype.forbidPending = function (forbidPending) {
961
950
  this.options.forbidPending = forbidPending !== false;
962
951
  return this;
963
952
  };
@@ -966,7 +955,7 @@ Mocha.prototype.forbidPending = function(forbidPending) {
966
955
  * Throws an error if mocha is in the wrong state to be able to transition to a "running" state.
967
956
  * @private
968
957
  */
969
- Mocha.prototype._guardRunningStateTransition = function() {
958
+ Mocha.prototype._guardRunningStateTransition = function () {
970
959
  if (this._state === mochaStates.RUNNING) {
971
960
  throw createMochaInstanceAlreadyRunningError(
972
961
  'Mocha instance is currently running tests, cannot start a next test run until this one is done',
@@ -1025,7 +1014,7 @@ Object.defineProperty(Mocha.prototype, 'version', {
1025
1014
  * // exit with non-zero status if there were test failures
1026
1015
  * mocha.run(failures => process.exitCode = failures ? 1 : 0);
1027
1016
  */
1028
- Mocha.prototype.run = function(fn) {
1017
+ Mocha.prototype.run = function (fn) {
1029
1018
  this._guardRunningStateTransition();
1030
1019
  this._state = mochaStates.RUNNING;
1031
1020
  if (this._previousRunner) {
@@ -1328,9 +1317,10 @@ Mocha.prototype.hasGlobalSetupFixtures = function hasGlobalSetupFixtures() {
1328
1317
  * @public
1329
1318
  * @returns {boolean}
1330
1319
  */
1331
- Mocha.prototype.hasGlobalTeardownFixtures = function hasGlobalTeardownFixtures() {
1332
- return Boolean(this.options.globalTeardown.length);
1333
- };
1320
+ Mocha.prototype.hasGlobalTeardownFixtures =
1321
+ function hasGlobalTeardownFixtures() {
1322
+ return Boolean(this.options.globalTeardown.length);
1323
+ };
1334
1324
 
1335
1325
  /**
1336
1326
  * An alternative way to define root hooks that works with parallel runs.
@@ -75,7 +75,23 @@ class BufferedWorkerPool {
75
75
  process.execArgv.join(' ')
76
76
  );
77
77
 
78
- this.options = {...WORKER_POOL_DEFAULT_OPTS, opts, maxWorkers};
78
+ let counter = 0;
79
+ const onCreateWorker = ({forkOpts}) => {
80
+ return {
81
+ forkOpts: {
82
+ ...forkOpts,
83
+ // adds an incremental id to all workers, which can be useful to allocate resources for each process
84
+ env: {...process.env, MOCHA_WORKER_ID: counter++}
85
+ }
86
+ };
87
+ };
88
+
89
+ this.options = {
90
+ ...WORKER_POOL_DEFAULT_OPTS,
91
+ ...opts,
92
+ maxWorkers,
93
+ onCreateWorker
94
+ };
79
95
  this._pool = workerpool.pool(WORKER_PATH, this.options);
80
96
  }
81
97
 
@@ -53,15 +53,30 @@ exports.requireOrImport = hasStableEsmImplementation
53
53
  err.code === 'ERR_UNSUPPORTED_DIR_IMPORT'
54
54
  ) {
55
55
  try {
56
+ // Importing a file usually works, but the resolution of `import` is the ESM
57
+ // resolution algorithm, and not the CJS resolution algorithm. So in this case
58
+ // if we fail, we may have failed because we tried the ESM resolution and failed
59
+ // So we try to `require` it
56
60
  return require(file);
57
61
  } catch (requireErr) {
58
- if (requireErr.code === 'ERR_REQUIRE_ESM') {
59
- // This happens when the test file is a JS file, but via type:module is actually ESM,
62
+ if (
63
+ requireErr.code === 'ERR_REQUIRE_ESM' ||
64
+ (requireErr instanceof SyntaxError &&
65
+ requireErr
66
+ .toString()
67
+ .includes('Cannot use import statement outside a module'))
68
+ ) {
69
+ // ERR_REQUIRE_ESM happens when the test file is a JS file, but via type:module is actually ESM,
60
70
  // AND has an import to a file that doesn't exist.
61
- // This throws an `ERR_MODULE_NOT_FOUND` // error above,
71
+ // This throws an `ERR_MODULE_NOT_FOUND` error above,
62
72
  // and when we try to `require` it here, it throws an `ERR_REQUIRE_ESM`.
63
73
  // What we want to do is throw the original error (the `ERR_MODULE_NOT_FOUND`),
64
74
  // and not the `ERR_REQUIRE_ESM` error, which is a red herring.
75
+ //
76
+ // SyntaxError happens when in an edge case: when we're using an ESM loader that loads
77
+ // a `test.ts` file (i.e. unrecognized extension), and that file includes an unknown
78
+ // import (which thows an ERR_MODULE_NOT_FOUND). require-ing it will throw the
79
+ // syntax error, because we cannot require a file that has import-s.
65
80
  throw err;
66
81
  } else {
67
82
  throw requireErr;
@@ -107,7 +107,7 @@ exports.symbols = {
107
107
  * @param {string} str
108
108
  * @return {string}
109
109
  */
110
- var color = (exports.color = function(type, str) {
110
+ var color = (exports.color = function (type, str) {
111
111
  if (!exports.useColors) {
112
112
  return String(str);
113
113
  }
@@ -135,23 +135,23 @@ if (isatty) {
135
135
  */
136
136
 
137
137
  exports.cursor = {
138
- hide: function() {
138
+ hide: function () {
139
139
  isatty && process.stdout.write('\u001b[?25l');
140
140
  },
141
141
 
142
- show: function() {
142
+ show: function () {
143
143
  isatty && process.stdout.write('\u001b[?25h');
144
144
  },
145
145
 
146
- deleteLine: function() {
146
+ deleteLine: function () {
147
147
  isatty && process.stdout.write('\u001b[2K');
148
148
  },
149
149
 
150
- beginningOfLine: function() {
150
+ beginningOfLine: function () {
151
151
  isatty && process.stdout.write('\u001b[0G');
152
152
  },
153
153
 
154
- CR: function() {
154
+ CR: function () {
155
155
  if (isatty) {
156
156
  exports.cursor.deleteLine();
157
157
  exports.cursor.beginningOfLine();
@@ -161,7 +161,7 @@ exports.cursor = {
161
161
  }
162
162
  };
163
163
 
164
- var showDiff = (exports.showDiff = function(err) {
164
+ var showDiff = (exports.showDiff = function (err) {
165
165
  return (
166
166
  err &&
167
167
  err.showDiff !== false &&
@@ -188,7 +188,7 @@ function stringifyDiffObjs(err) {
188
188
  * @param {string} expected
189
189
  * @return {string} Diff
190
190
  */
191
- var generateDiff = (exports.generateDiff = function(actual, expected) {
191
+ var generateDiff = (exports.generateDiff = function (actual, expected) {
192
192
  try {
193
193
  const diffSize = 2048;
194
194
  if (actual.length > diffSize) {
@@ -220,10 +220,10 @@ var generateDiff = (exports.generateDiff = function(actual, expected) {
220
220
  * @param {Object[]} failures - Each is Test instance with corresponding
221
221
  * Error property
222
222
  */
223
- exports.list = function(failures) {
223
+ exports.list = function (failures) {
224
224
  var multipleErr, multipleTest;
225
225
  Base.consoleLog();
226
- failures.forEach(function(test, i) {
226
+ failures.forEach(function (test, i) {
227
227
  // format
228
228
  var fmt =
229
229
  color('error title', ' %s) %s:\n') +
@@ -282,7 +282,7 @@ exports.list = function(failures) {
282
282
 
283
283
  // indented test title
284
284
  var testTitle = '';
285
- test.titlePath().forEach(function(str, index) {
285
+ test.titlePath().forEach(function (str, index) {
286
286
  if (index !== 0) {
287
287
  testTitle += '\n ';
288
288
  }
@@ -318,7 +318,7 @@ function Base(runner, options) {
318
318
  this.runner = runner;
319
319
  this.stats = runner.stats; // assigned so Reporters keep a closer reference
320
320
 
321
- runner.on(EVENT_TEST_PASS, function(test) {
321
+ runner.on(EVENT_TEST_PASS, function (test) {
322
322
  if (test.duration > test.slow()) {
323
323
  test.speed = 'slow';
324
324
  } else if (test.duration > test.slow() / 2) {
@@ -328,7 +328,7 @@ function Base(runner, options) {
328
328
  }
329
329
  });
330
330
 
331
- runner.on(EVENT_TEST_FAIL, function(test, err) {
331
+ runner.on(EVENT_TEST_FAIL, function (test, err) {
332
332
  if (showDiff(err)) {
333
333
  stringifyDiffObjs(err);
334
334
  }
@@ -348,7 +348,7 @@ function Base(runner, options) {
348
348
  * @public
349
349
  * @memberof Mocha.reporters
350
350
  */
351
- Base.prototype.epilogue = function() {
351
+ Base.prototype.epilogue = function () {
352
352
  var stats = this.stats;
353
353
  var fmt;
354
354
 
@@ -411,7 +411,7 @@ function inlineDiff(actual, expected) {
411
411
  if (lines.length > 4) {
412
412
  var width = String(lines.length).length;
413
413
  msg = lines
414
- .map(function(str, i) {
414
+ .map(function (str, i) {
415
415
  return pad(++i, width) + ' |' + ' ' + str;
416
416
  })
417
417
  .join('\n');
@@ -468,10 +468,7 @@ function unifiedDiff(actual, expected) {
468
468
  ' ' +
469
469
  colorLines('diff removed', '- actual') +
470
470
  '\n\n' +
471
- lines
472
- .map(cleanUp)
473
- .filter(notBlank)
474
- .join('\n')
471
+ lines.map(cleanUp).filter(notBlank).join('\n')
475
472
  );
476
473
  }
477
474
 
@@ -486,7 +483,7 @@ function unifiedDiff(actual, expected) {
486
483
  function errorDiff(actual, expected) {
487
484
  return diff
488
485
  .diffWordsWithSpace(actual, expected)
489
- .map(function(str) {
486
+ .map(function (str) {
490
487
  if (str.added) {
491
488
  return colorLines('diff added inline', str.value);
492
489
  }
@@ -509,7 +506,7 @@ function errorDiff(actual, expected) {
509
506
  function colorLines(name, str) {
510
507
  return str
511
508
  .split('\n')
512
- .map(function(str) {
509
+ .map(function (str) {
513
510
  return color(name, str);
514
511
  })
515
512
  .join('\n');
@@ -39,7 +39,7 @@ function Doc(runner, options) {
39
39
  return Array(indents).join(' ');
40
40
  }
41
41
 
42
- runner.on(EVENT_SUITE_BEGIN, function(suite) {
42
+ runner.on(EVENT_SUITE_BEGIN, function (suite) {
43
43
  if (suite.root) {
44
44
  return;
45
45
  }
@@ -50,7 +50,7 @@ function Doc(runner, options) {
50
50
  Base.consoleLog('%s<dl>', indent());
51
51
  });
52
52
 
53
- runner.on(EVENT_SUITE_END, function(suite) {
53
+ runner.on(EVENT_SUITE_END, function (suite) {
54
54
  if (suite.root) {
55
55
  return;
56
56
  }
@@ -60,14 +60,14 @@ function Doc(runner, options) {
60
60
  --indents;
61
61
  });
62
62
 
63
- runner.on(EVENT_TEST_PASS, function(test) {
63
+ runner.on(EVENT_TEST_PASS, function (test) {
64
64
  Base.consoleLog('%s <dt>%s</dt>', indent(), utils.escape(test.title));
65
65
  Base.consoleLog('%s <dt>%s</dt>', indent(), utils.escape(test.file));
66
66
  var code = utils.escape(utils.clean(test.body));
67
67
  Base.consoleLog('%s <dd><pre><code>%s</code></pre></dd>', indent(), code);
68
68
  });
69
69
 
70
- runner.on(EVENT_TEST_FAIL, function(test, err) {
70
+ runner.on(EVENT_TEST_FAIL, function (test, err) {
71
71
  Base.consoleLog(
72
72
  '%s <dt class="error">%s</dt>',
73
73
  indent(),