mocha 9.1.2 → 9.2.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 (46) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +1 -1
  3. package/browser-entry.js +26 -16
  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/config.js +7 -12
  8. package/lib/cli/run.js +1 -1
  9. package/lib/cli/watch-run.js +1 -4
  10. package/lib/context.js +5 -5
  11. package/lib/errors.js +1 -1
  12. package/lib/hook.js +2 -2
  13. package/lib/interfaces/bdd.js +23 -20
  14. package/lib/interfaces/common.js +7 -7
  15. package/lib/interfaces/exports.js +1 -1
  16. package/lib/interfaces/qunit.js +7 -7
  17. package/lib/interfaces/tdd.js +9 -9
  18. package/lib/mocha.js +56 -58
  19. package/lib/nodejs/buffered-worker-pool.js +17 -1
  20. package/lib/nodejs/esm-utils.js +18 -3
  21. package/lib/reporters/base.js +41 -28
  22. package/lib/reporters/doc.js +4 -4
  23. package/lib/reporters/dot.js +5 -5
  24. package/lib/reporters/html.js +12 -12
  25. package/lib/reporters/json-stream.js +4 -4
  26. package/lib/reporters/json.js +7 -7
  27. package/lib/reporters/landing.js +5 -5
  28. package/lib/reporters/list.js +5 -5
  29. package/lib/reporters/markdown.js +5 -5
  30. package/lib/reporters/min.js +1 -1
  31. package/lib/reporters/nyan.js +16 -16
  32. package/lib/reporters/progress.js +3 -3
  33. package/lib/reporters/spec.js +6 -6
  34. package/lib/reporters/tap.js +17 -17
  35. package/lib/reporters/xunit.js +9 -9
  36. package/lib/runnable.js +21 -21
  37. package/lib/runner.js +44 -47
  38. package/lib/stats-collector.js +7 -7
  39. package/lib/suite.js +44 -73
  40. package/lib/test.js +4 -4
  41. package/lib/utils.js +18 -19
  42. package/mocha-es2018.js +432 -449
  43. package/mocha.js +1246 -851
  44. package/mocha.js.map +1 -1
  45. package/package.json +38 -38
  46. package/CHANGELOG.md +0 -1015
package/lib/mocha.js CHANGED
@@ -23,11 +23,8 @@ const {
23
23
  createMochaInstanceAlreadyRunningError,
24
24
  createUnsupportedError
25
25
  } = require('./errors');
26
- const {
27
- EVENT_FILE_PRE_REQUIRE,
28
- EVENT_FILE_POST_REQUIRE,
29
- EVENT_FILE_REQUIRE
30
- } = Suite.constants;
26
+ const {EVENT_FILE_PRE_REQUIRE, EVENT_FILE_POST_REQUIRE, EVENT_FILE_REQUIRE} =
27
+ Suite.constants;
31
28
  var debug = require('debug')('mocha:mocha');
32
29
 
33
30
  exports = module.exports = Mocha;
@@ -94,46 +91,46 @@ exports.Hook = require('./hook');
94
91
  exports.Test = require('./test');
95
92
 
96
93
  let currentContext;
97
- exports.afterEach = function(...args) {
94
+ exports.afterEach = function (...args) {
98
95
  return (currentContext.afterEach || currentContext.teardown).apply(
99
96
  this,
100
97
  args
101
98
  );
102
99
  };
103
- exports.after = function(...args) {
100
+ exports.after = function (...args) {
104
101
  return (currentContext.after || currentContext.suiteTeardown).apply(
105
102
  this,
106
103
  args
107
104
  );
108
105
  };
109
- exports.beforeEach = function(...args) {
106
+ exports.beforeEach = function (...args) {
110
107
  return (currentContext.beforeEach || currentContext.setup).apply(this, args);
111
108
  };
112
- exports.before = function(...args) {
109
+ exports.before = function (...args) {
113
110
  return (currentContext.before || currentContext.suiteSetup).apply(this, args);
114
111
  };
115
- exports.describe = function(...args) {
112
+ exports.describe = function (...args) {
116
113
  return (currentContext.describe || currentContext.suite).apply(this, args);
117
114
  };
118
- exports.describe.only = function(...args) {
115
+ exports.describe.only = function (...args) {
119
116
  return (currentContext.describe || currentContext.suite).only.apply(
120
117
  this,
121
118
  args
122
119
  );
123
120
  };
124
- exports.describe.skip = function(...args) {
121
+ exports.describe.skip = function (...args) {
125
122
  return (currentContext.describe || currentContext.suite).skip.apply(
126
123
  this,
127
124
  args
128
125
  );
129
126
  };
130
- exports.it = function(...args) {
127
+ exports.it = function (...args) {
131
128
  return (currentContext.it || currentContext.test).apply(this, args);
132
129
  };
133
- exports.it.only = function(...args) {
130
+ exports.it.only = function (...args) {
134
131
  return (currentContext.it || currentContext.test).only.apply(this, args);
135
132
  };
136
- exports.it.skip = function(...args) {
133
+ exports.it.skip = function (...args) {
137
134
  return (currentContext.it || currentContext.test).skip.apply(this, args);
138
135
  };
139
136
  exports.xdescribe = exports.describe.skip;
@@ -144,7 +141,7 @@ exports.suiteTeardown = exports.after;
144
141
  exports.suite = exports.describe;
145
142
  exports.teardown = exports.afterEach;
146
143
  exports.test = exports.it;
147
- exports.run = function(...args) {
144
+ exports.run = function (...args) {
148
145
  return currentContext.run.apply(this, args);
149
146
  };
150
147
 
@@ -229,7 +226,7 @@ function Mocha(options = {}) {
229
226
  'growl',
230
227
  'inlineDiffs',
231
228
  'invert'
232
- ].forEach(function(opt) {
229
+ ].forEach(function (opt) {
233
230
  if (options[opt]) {
234
231
  this[opt]();
235
232
  }
@@ -287,7 +284,7 @@ function Mocha(options = {}) {
287
284
  * @returns {Mocha} this
288
285
  * @chainable
289
286
  */
290
- Mocha.prototype.bail = function(bail) {
287
+ Mocha.prototype.bail = function (bail) {
291
288
  this.suite.bail(bail !== false);
292
289
  return this;
293
290
  };
@@ -305,7 +302,7 @@ Mocha.prototype.bail = function(bail) {
305
302
  * @returns {Mocha} this
306
303
  * @chainable
307
304
  */
308
- Mocha.prototype.addFile = function(file) {
305
+ Mocha.prototype.addFile = function (file) {
309
306
  this.files.push(file);
310
307
  return this;
311
308
  };
@@ -326,7 +323,7 @@ Mocha.prototype.addFile = function(file) {
326
323
  * // Use XUnit reporter and direct its output to file
327
324
  * mocha.reporter('xunit', { output: '/path/to/testspec.xunit.xml' });
328
325
  */
329
- Mocha.prototype.reporter = function(reporterName, reporterOptions) {
326
+ Mocha.prototype.reporter = function (reporterName, reporterOptions) {
330
327
  if (typeof reporterName === 'function') {
331
328
  this._reporter = reporterName;
332
329
  } else {
@@ -382,7 +379,7 @@ Mocha.prototype.reporter = function(reporterName, reporterOptions) {
382
379
  * @chainable
383
380
  * @throws {Error} if requested interface cannot be loaded
384
381
  */
385
- Mocha.prototype.ui = function(ui) {
382
+ Mocha.prototype.ui = function (ui) {
386
383
  var bindInterface;
387
384
  if (typeof ui === 'function') {
388
385
  bindInterface = ui;
@@ -399,7 +396,7 @@ Mocha.prototype.ui = function(ui) {
399
396
  }
400
397
  bindInterface(this.suite);
401
398
 
402
- this.suite.on(EVENT_FILE_PRE_REQUIRE, function(context) {
399
+ this.suite.on(EVENT_FILE_PRE_REQUIRE, function (context) {
403
400
  currentContext = context;
404
401
  });
405
402
 
@@ -421,10 +418,10 @@ Mocha.prototype.ui = function(ui) {
421
418
  * @see {@link Mocha#loadFilesAsync}
422
419
  * @param {Function} [fn] - Callback invoked upon completion.
423
420
  */
424
- Mocha.prototype.loadFiles = function(fn) {
421
+ Mocha.prototype.loadFiles = function (fn) {
425
422
  var self = this;
426
423
  var suite = this.suite;
427
- this.files.forEach(function(file) {
424
+ this.files.forEach(function (file) {
428
425
  file = path.resolve(file);
429
426
  suite.emit(EVENT_FILE_PRE_REQUIRE, global, file, self);
430
427
  suite.emit(EVENT_FILE_REQUIRE, require(file), file, self);
@@ -453,17 +450,17 @@ Mocha.prototype.loadFiles = function(fn) {
453
450
  * .then(() => mocha.run(failures => process.exitCode = failures ? 1 : 0))
454
451
  * .catch(() => process.exitCode = 1);
455
452
  */
456
- Mocha.prototype.loadFilesAsync = function() {
453
+ Mocha.prototype.loadFilesAsync = function () {
457
454
  var self = this;
458
455
  var suite = this.suite;
459
456
  this.lazyLoadFiles(true);
460
457
 
461
458
  return esmUtils.loadFilesAsync(
462
459
  this.files,
463
- function(file) {
460
+ function (file) {
464
461
  suite.emit(EVENT_FILE_PRE_REQUIRE, global, file, self);
465
462
  },
466
- function(file, resultModule) {
463
+ function (file, resultModule) {
467
464
  suite.emit(EVENT_FILE_REQUIRE, resultModule, file, self);
468
465
  suite.emit(EVENT_FILE_POST_REQUIRE, global, file, self);
469
466
  }
@@ -478,7 +475,7 @@ Mocha.prototype.loadFilesAsync = function() {
478
475
  * @see {@link Mocha#unloadFiles}
479
476
  * @param {string} file - Pathname of file to be unloaded.
480
477
  */
481
- Mocha.unloadFile = function(file) {
478
+ Mocha.unloadFile = function (file) {
482
479
  if (utils.isBrowser()) {
483
480
  throw createUnsupportedError(
484
481
  'unloadFile() is only suported in a Node.js environment'
@@ -502,7 +499,7 @@ Mocha.unloadFile = function(file) {
502
499
  * @returns {Mocha} this
503
500
  * @chainable
504
501
  */
505
- Mocha.prototype.unloadFiles = function() {
502
+ Mocha.prototype.unloadFiles = function () {
506
503
  if (this._state === mochaStates.DISPOSED) {
507
504
  throw createMochaInstanceAlreadyDisposedError(
508
505
  'Mocha instance is already disposed, it cannot be used again.',
@@ -511,7 +508,7 @@ Mocha.prototype.unloadFiles = function() {
511
508
  );
512
509
  }
513
510
 
514
- this.files.forEach(function(file) {
511
+ this.files.forEach(function (file) {
515
512
  Mocha.unloadFile(file);
516
513
  });
517
514
  this._state = mochaStates.INIT;
@@ -531,7 +528,7 @@ Mocha.prototype.unloadFiles = function() {
531
528
  * // Select tests whose full title begins with `"foo"` followed by a period
532
529
  * mocha.fgrep('foo.');
533
530
  */
534
- Mocha.prototype.fgrep = function(str) {
531
+ Mocha.prototype.fgrep = function (str) {
535
532
  if (!str) {
536
533
  return this;
537
534
  }
@@ -572,7 +569,7 @@ Mocha.prototype.fgrep = function(str) {
572
569
  * // Given embedded test `it('only-this-test')`...
573
570
  * mocha.grep('/^only-this-test$/'); // NO! Use `.only()` to do this!
574
571
  */
575
- Mocha.prototype.grep = function(re) {
572
+ Mocha.prototype.grep = function (re) {
576
573
  if (utils.isString(re)) {
577
574
  // extract args if it's regex-like, i.e: [string, pattern, flag]
578
575
  var arg = re.match(/^\/(.*)\/([gimy]{0,4})$|.*/);
@@ -595,7 +592,7 @@ Mocha.prototype.grep = function(re) {
595
592
  * // Select tests whose full title does *not* contain `"match"`, ignoring case
596
593
  * mocha.grep(/match/i).invert();
597
594
  */
598
- Mocha.prototype.invert = function() {
595
+ Mocha.prototype.invert = function () {
599
596
  this.options.invert = true;
600
597
  return this;
601
598
  };
@@ -609,7 +606,7 @@ Mocha.prototype.invert = function() {
609
606
  * @return {Mocha} this
610
607
  * @chainable
611
608
  */
612
- Mocha.prototype.checkLeaks = function(checkLeaks) {
609
+ Mocha.prototype.checkLeaks = function (checkLeaks) {
613
610
  this.options.checkLeaks = checkLeaks !== false;
614
611
  return this;
615
612
  };
@@ -624,7 +621,7 @@ Mocha.prototype.checkLeaks = function(checkLeaks) {
624
621
  * @return {Mocha} this
625
622
  * @chainable
626
623
  */
627
- Mocha.prototype.cleanReferencesAfterRun = function(cleanReferencesAfterRun) {
624
+ Mocha.prototype.cleanReferencesAfterRun = function (cleanReferencesAfterRun) {
628
625
  this._cleanReferencesAfterRun = cleanReferencesAfterRun !== false;
629
626
  return this;
630
627
  };
@@ -634,7 +631,7 @@ Mocha.prototype.cleanReferencesAfterRun = function(cleanReferencesAfterRun) {
634
631
  * It also removes function references to tests functions and hooks, so variables trapped in closures can be cleaned by the garbage collector.
635
632
  * @public
636
633
  */
637
- Mocha.prototype.dispose = function() {
634
+ Mocha.prototype.dispose = function () {
638
635
  if (this._state === mochaStates.RUNNING) {
639
636
  throw createMochaInstanceAlreadyRunningError(
640
637
  'Cannot dispose while the mocha instance is still running tests.'
@@ -655,7 +652,7 @@ Mocha.prototype.dispose = function() {
655
652
  * @return {Mocha} this
656
653
  * @chainable
657
654
  */
658
- Mocha.prototype.fullTrace = function(fullTrace) {
655
+ Mocha.prototype.fullTrace = function (fullTrace) {
659
656
  this.options.fullTrace = fullTrace !== false;
660
657
  return this;
661
658
  };
@@ -668,7 +665,7 @@ Mocha.prototype.fullTrace = function(fullTrace) {
668
665
  * @return {Mocha} this
669
666
  * @chainable
670
667
  */
671
- Mocha.prototype.growl = function() {
668
+ Mocha.prototype.growl = function () {
672
669
  this.options.growl = this.isGrowlCapable();
673
670
  if (!this.options.growl) {
674
671
  var detail = utils.isBrowser()
@@ -717,11 +714,11 @@ Mocha.prototype._growl = growl.notify;
717
714
  * // Specify variables to be expected in global scope
718
715
  * mocha.global(['jQuery', 'MyLib']);
719
716
  */
720
- Mocha.prototype.global = function(global) {
717
+ Mocha.prototype.global = function (global) {
721
718
  this.options.global = (this.options.global || [])
722
719
  .concat(global)
723
720
  .filter(Boolean)
724
- .filter(function(elt, idx, arr) {
721
+ .filter(function (elt, idx, arr) {
725
722
  return arr.indexOf(elt) === idx;
726
723
  });
727
724
  return this;
@@ -738,7 +735,7 @@ Mocha.prototype.globals = Mocha.prototype.global;
738
735
  * @return {Mocha} this
739
736
  * @chainable
740
737
  */
741
- Mocha.prototype.color = function(color) {
738
+ Mocha.prototype.color = function (color) {
742
739
  this.options.color = color !== false;
743
740
  return this;
744
741
  };
@@ -753,7 +750,7 @@ Mocha.prototype.color = function(color) {
753
750
  * @return {Mocha} this
754
751
  * @chainable
755
752
  */
756
- Mocha.prototype.inlineDiffs = function(inlineDiffs) {
753
+ Mocha.prototype.inlineDiffs = function (inlineDiffs) {
757
754
  this.options.inlineDiffs = inlineDiffs !== false;
758
755
  return this;
759
756
  };
@@ -767,7 +764,7 @@ Mocha.prototype.inlineDiffs = function(inlineDiffs) {
767
764
  * @return {Mocha} this
768
765
  * @chainable
769
766
  */
770
- Mocha.prototype.diff = function(diff) {
767
+ Mocha.prototype.diff = function (diff) {
771
768
  this.options.diff = diff !== false;
772
769
  return this;
773
770
  };
@@ -795,7 +792,7 @@ Mocha.prototype.diff = function(diff) {
795
792
  * // Same as above but using string argument
796
793
  * mocha.timeout('1s');
797
794
  */
798
- Mocha.prototype.timeout = function(msecs) {
795
+ Mocha.prototype.timeout = function (msecs) {
799
796
  this.suite.timeout(msecs);
800
797
  return this;
801
798
  };
@@ -814,7 +811,7 @@ Mocha.prototype.timeout = function(msecs) {
814
811
  * // Allow any failed test to retry one more time
815
812
  * mocha.retries(1);
816
813
  */
817
- Mocha.prototype.retries = function(retry) {
814
+ Mocha.prototype.retries = function (retry) {
818
815
  this.suite.retries(retry);
819
816
  return this;
820
817
  };
@@ -836,7 +833,7 @@ Mocha.prototype.retries = function(retry) {
836
833
  * // Same as above but using string argument
837
834
  * mocha.slow('0.5s');
838
835
  */
839
- Mocha.prototype.slow = function(msecs) {
836
+ Mocha.prototype.slow = function (msecs) {
840
837
  this.suite.slow(msecs);
841
838
  return this;
842
839
  };
@@ -850,7 +847,7 @@ Mocha.prototype.slow = function(msecs) {
850
847
  * @return {Mocha} this
851
848
  * @chainable
852
849
  */
853
- Mocha.prototype.asyncOnly = function(asyncOnly) {
850
+ Mocha.prototype.asyncOnly = function (asyncOnly) {
854
851
  this.options.asyncOnly = asyncOnly !== false;
855
852
  return this;
856
853
  };
@@ -862,7 +859,7 @@ Mocha.prototype.asyncOnly = function(asyncOnly) {
862
859
  * @return {Mocha} this
863
860
  * @chainable
864
861
  */
865
- Mocha.prototype.noHighlighting = function() {
862
+ Mocha.prototype.noHighlighting = function () {
866
863
  this.options.noHighlighting = true;
867
864
  return this;
868
865
  };
@@ -876,7 +873,7 @@ Mocha.prototype.noHighlighting = function() {
876
873
  * @return {Mocha} this
877
874
  * @chainable
878
875
  */
879
- Mocha.prototype.allowUncaught = function(allowUncaught) {
876
+ Mocha.prototype.allowUncaught = function (allowUncaught) {
880
877
  this.options.allowUncaught = allowUncaught !== false;
881
878
  return this;
882
879
  };
@@ -907,7 +904,7 @@ Mocha.prototype.delay = function delay() {
907
904
  * @return {Mocha} this
908
905
  * @chainable
909
906
  */
910
- Mocha.prototype.dryRun = function(dryRun) {
907
+ Mocha.prototype.dryRun = function (dryRun) {
911
908
  this.options.dryRun = dryRun !== false;
912
909
  return this;
913
910
  };
@@ -921,7 +918,7 @@ Mocha.prototype.dryRun = function(dryRun) {
921
918
  * @return {Mocha} this
922
919
  * @chainable
923
920
  */
924
- Mocha.prototype.failZero = function(failZero) {
921
+ Mocha.prototype.failZero = function (failZero) {
925
922
  this.options.failZero = failZero !== false;
926
923
  return this;
927
924
  };
@@ -935,7 +932,7 @@ Mocha.prototype.failZero = function(failZero) {
935
932
  * @returns {Mocha} this
936
933
  * @chainable
937
934
  */
938
- Mocha.prototype.forbidOnly = function(forbidOnly) {
935
+ Mocha.prototype.forbidOnly = function (forbidOnly) {
939
936
  this.options.forbidOnly = forbidOnly !== false;
940
937
  return this;
941
938
  };
@@ -949,7 +946,7 @@ Mocha.prototype.forbidOnly = function(forbidOnly) {
949
946
  * @returns {Mocha} this
950
947
  * @chainable
951
948
  */
952
- Mocha.prototype.forbidPending = function(forbidPending) {
949
+ Mocha.prototype.forbidPending = function (forbidPending) {
953
950
  this.options.forbidPending = forbidPending !== false;
954
951
  return this;
955
952
  };
@@ -958,7 +955,7 @@ Mocha.prototype.forbidPending = function(forbidPending) {
958
955
  * Throws an error if mocha is in the wrong state to be able to transition to a "running" state.
959
956
  * @private
960
957
  */
961
- Mocha.prototype._guardRunningStateTransition = function() {
958
+ Mocha.prototype._guardRunningStateTransition = function () {
962
959
  if (this._state === mochaStates.RUNNING) {
963
960
  throw createMochaInstanceAlreadyRunningError(
964
961
  'Mocha instance is currently running tests, cannot start a next test run until this one is done',
@@ -1017,7 +1014,7 @@ Object.defineProperty(Mocha.prototype, 'version', {
1017
1014
  * // exit with non-zero status if there were test failures
1018
1015
  * mocha.run(failures => process.exitCode = failures ? 1 : 0);
1019
1016
  */
1020
- Mocha.prototype.run = function(fn) {
1017
+ Mocha.prototype.run = function (fn) {
1021
1018
  this._guardRunningStateTransition();
1022
1019
  this._state = mochaStates.RUNNING;
1023
1020
  if (this._previousRunner) {
@@ -1320,9 +1317,10 @@ Mocha.prototype.hasGlobalSetupFixtures = function hasGlobalSetupFixtures() {
1320
1317
  * @public
1321
1318
  * @returns {boolean}
1322
1319
  */
1323
- Mocha.prototype.hasGlobalTeardownFixtures = function hasGlobalTeardownFixtures() {
1324
- return Boolean(this.options.globalTeardown.length);
1325
- };
1320
+ Mocha.prototype.hasGlobalTeardownFixtures =
1321
+ function hasGlobalTeardownFixtures() {
1322
+ return Boolean(this.options.globalTeardown.length);
1323
+ };
1326
1324
 
1327
1325
  /**
1328
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;
@@ -56,6 +56,11 @@ exports.useColors =
56
56
 
57
57
  exports.inlineDiffs = false;
58
58
 
59
+ /**
60
+ * Truncate diffs longer than this value to avoid slow performance
61
+ */
62
+ exports.maxDiffSize = 8192;
63
+
59
64
  /**
60
65
  * Default color map.
61
66
  */
@@ -107,7 +112,7 @@ exports.symbols = {
107
112
  * @param {string} str
108
113
  * @return {string}
109
114
  */
110
- var color = (exports.color = function(type, str) {
115
+ var color = (exports.color = function (type, str) {
111
116
  if (!exports.useColors) {
112
117
  return String(str);
113
118
  }
@@ -135,23 +140,23 @@ if (isatty) {
135
140
  */
136
141
 
137
142
  exports.cursor = {
138
- hide: function() {
143
+ hide: function () {
139
144
  isatty && process.stdout.write('\u001b[?25l');
140
145
  },
141
146
 
142
- show: function() {
147
+ show: function () {
143
148
  isatty && process.stdout.write('\u001b[?25h');
144
149
  },
145
150
 
146
- deleteLine: function() {
151
+ deleteLine: function () {
147
152
  isatty && process.stdout.write('\u001b[2K');
148
153
  },
149
154
 
150
- beginningOfLine: function() {
155
+ beginningOfLine: function () {
151
156
  isatty && process.stdout.write('\u001b[0G');
152
157
  },
153
158
 
154
- CR: function() {
159
+ CR: function () {
155
160
  if (isatty) {
156
161
  exports.cursor.deleteLine();
157
162
  exports.cursor.beginningOfLine();
@@ -161,7 +166,7 @@ exports.cursor = {
161
166
  }
162
167
  };
163
168
 
164
- var showDiff = (exports.showDiff = function(err) {
169
+ var showDiff = (exports.showDiff = function (err) {
165
170
  return (
166
171
  err &&
167
172
  err.showDiff !== false &&
@@ -188,18 +193,23 @@ function stringifyDiffObjs(err) {
188
193
  * @param {string} expected
189
194
  * @return {string} Diff
190
195
  */
191
- var generateDiff = (exports.generateDiff = function(actual, expected) {
196
+
197
+ var generateDiff = (exports.generateDiff = function (actual, expected) {
192
198
  try {
193
- const diffSize = 2048;
194
- if (actual.length > diffSize) {
195
- actual = actual.substring(0, diffSize) + ' ... Lines skipped';
199
+ var maxLen = exports.maxDiffSize;
200
+ var skipped = 0;
201
+ if (maxLen > 0) {
202
+ skipped = Math.max(actual.length - maxLen, expected.length - maxLen);
203
+ actual = actual.slice(0, maxLen);
204
+ expected = expected.slice(0, maxLen);
196
205
  }
197
- if (expected.length > diffSize) {
198
- expected = expected.substring(0, diffSize) + ' ... Lines skipped';
199
- }
200
- return exports.inlineDiffs
206
+ let result = exports.inlineDiffs
201
207
  ? inlineDiff(actual, expected)
202
208
  : unifiedDiff(actual, expected);
209
+ if (skipped > 0) {
210
+ result = `${result}\n [mocha] output truncated to ${maxLen} characters, see "maxDiffSize" reporter-option\n`;
211
+ }
212
+ return result;
203
213
  } catch (err) {
204
214
  var msg =
205
215
  '\n ' +
@@ -220,10 +230,10 @@ var generateDiff = (exports.generateDiff = function(actual, expected) {
220
230
  * @param {Object[]} failures - Each is Test instance with corresponding
221
231
  * Error property
222
232
  */
223
- exports.list = function(failures) {
233
+ exports.list = function (failures) {
224
234
  var multipleErr, multipleTest;
225
235
  Base.consoleLog();
226
- failures.forEach(function(test, i) {
236
+ failures.forEach(function (test, i) {
227
237
  // format
228
238
  var fmt =
229
239
  color('error title', ' %s) %s:\n') +
@@ -282,7 +292,7 @@ exports.list = function(failures) {
282
292
 
283
293
  // indented test title
284
294
  var testTitle = '';
285
- test.titlePath().forEach(function(str, index) {
295
+ test.titlePath().forEach(function (str, index) {
286
296
  if (index !== 0) {
287
297
  testTitle += '\n ';
288
298
  }
@@ -318,7 +328,13 @@ function Base(runner, options) {
318
328
  this.runner = runner;
319
329
  this.stats = runner.stats; // assigned so Reporters keep a closer reference
320
330
 
321
- runner.on(EVENT_TEST_PASS, function(test) {
331
+ var maxDiffSizeOpt =
332
+ this.options.reporterOption && this.options.reporterOption.maxDiffSize;
333
+ if (maxDiffSizeOpt !== undefined && !isNaN(Number(maxDiffSizeOpt))) {
334
+ exports.maxDiffSize = Number(maxDiffSizeOpt);
335
+ }
336
+
337
+ runner.on(EVENT_TEST_PASS, function (test) {
322
338
  if (test.duration > test.slow()) {
323
339
  test.speed = 'slow';
324
340
  } else if (test.duration > test.slow() / 2) {
@@ -328,7 +344,7 @@ function Base(runner, options) {
328
344
  }
329
345
  });
330
346
 
331
- runner.on(EVENT_TEST_FAIL, function(test, err) {
347
+ runner.on(EVENT_TEST_FAIL, function (test, err) {
332
348
  if (showDiff(err)) {
333
349
  stringifyDiffObjs(err);
334
350
  }
@@ -348,7 +364,7 @@ function Base(runner, options) {
348
364
  * @public
349
365
  * @memberof Mocha.reporters
350
366
  */
351
- Base.prototype.epilogue = function() {
367
+ Base.prototype.epilogue = function () {
352
368
  var stats = this.stats;
353
369
  var fmt;
354
370
 
@@ -411,7 +427,7 @@ function inlineDiff(actual, expected) {
411
427
  if (lines.length > 4) {
412
428
  var width = String(lines.length).length;
413
429
  msg = lines
414
- .map(function(str, i) {
430
+ .map(function (str, i) {
415
431
  return pad(++i, width) + ' |' + ' ' + str;
416
432
  })
417
433
  .join('\n');
@@ -468,10 +484,7 @@ function unifiedDiff(actual, expected) {
468
484
  ' ' +
469
485
  colorLines('diff removed', '- actual') +
470
486
  '\n\n' +
471
- lines
472
- .map(cleanUp)
473
- .filter(notBlank)
474
- .join('\n')
487
+ lines.map(cleanUp).filter(notBlank).join('\n')
475
488
  );
476
489
  }
477
490
 
@@ -486,7 +499,7 @@ function unifiedDiff(actual, expected) {
486
499
  function errorDiff(actual, expected) {
487
500
  return diff
488
501
  .diffWordsWithSpace(actual, expected)
489
- .map(function(str) {
502
+ .map(function (str) {
490
503
  if (str.added) {
491
504
  return colorLines('diff added inline', str.value);
492
505
  }
@@ -509,7 +522,7 @@ function errorDiff(actual, expected) {
509
522
  function colorLines(name, str) {
510
523
  return str
511
524
  .split('\n')
512
- .map(function(str) {
525
+ .map(function (str) {
513
526
  return color(name, str);
514
527
  })
515
528
  .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(),