mocha 8.0.1 → 8.1.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.
@@ -6,15 +6,24 @@
6
6
  * Module dependencies.
7
7
  */
8
8
 
9
- var tty = require('tty');
10
9
  var diff = require('diff');
11
10
  var milliseconds = require('ms');
12
11
  var utils = require('../utils');
13
- var supportsColor = utils.isBrowser() ? null : require('supports-color');
12
+ var supportsColor = require('supports-color');
14
13
  var constants = require('../runner').constants;
15
14
  var EVENT_TEST_PASS = constants.EVENT_TEST_PASS;
16
15
  var EVENT_TEST_FAIL = constants.EVENT_TEST_FAIL;
17
16
 
17
+ var isBrowser = require('../utils').isBrowser;
18
+
19
+ function getBrowserWindowSize() {
20
+ if ('innerHeight' in global) {
21
+ return [global.innerHeight, global.innerWidth];
22
+ }
23
+ // In a Web Worker, the DOM Window is not available.
24
+ return [640, 480];
25
+ }
26
+
18
27
  /**
19
28
  * Expose `Base`.
20
29
  */
@@ -25,7 +34,7 @@ exports = module.exports = Base;
25
34
  * Check if both stdio streams are associated with a tty.
26
35
  */
27
36
 
28
- var isatty = process.stdout.isTTY && process.stderr.isTTY;
37
+ var isatty = isBrowser ? true : process.stdout.isTTY && process.stderr.isTTY;
29
38
 
30
39
  /**
31
40
  * Save log references to avoid tests interfering (see GH-3604).
@@ -69,7 +78,9 @@ exports.colors = {
69
78
  light: 90,
70
79
  'diff gutter': 90,
71
80
  'diff added': 32,
72
- 'diff removed': 31
81
+ 'diff removed': 31,
82
+ 'diff added inline': '30;42',
83
+ 'diff removed inline': '30;41'
73
84
  };
74
85
 
75
86
  /**
@@ -118,9 +129,11 @@ exports.window = {
118
129
  };
119
130
 
120
131
  if (isatty) {
121
- exports.window.width = process.stdout.getWindowSize
122
- ? process.stdout.getWindowSize(1)[0]
123
- : tty.getWindowSize()[1];
132
+ if (isBrowser) {
133
+ exports.window.width = getBrowserWindowSize()[1];
134
+ } else {
135
+ exports.window.width = process.stdout.getWindowSize(1)[0];
136
+ }
124
137
  }
125
138
 
126
139
  /**
@@ -406,9 +419,9 @@ function inlineDiff(actual, expected) {
406
419
  // legend
407
420
  msg =
408
421
  '\n' +
409
- color('diff removed', 'actual') +
422
+ color('diff removed inline', 'actual') +
410
423
  ' ' +
411
- color('diff added', 'expected') +
424
+ color('diff added inline', 'expected') +
412
425
  '\n\n' +
413
426
  msg +
414
427
  '\n';
@@ -474,10 +487,10 @@ function errorDiff(actual, expected) {
474
487
  .diffWordsWithSpace(actual, expected)
475
488
  .map(function(str) {
476
489
  if (str.added) {
477
- return colorLines('diff added', str.value);
490
+ return colorLines('diff added inline', str.value);
478
491
  }
479
492
  if (str.removed) {
480
- return colorLines('diff removed', str.value);
493
+ return colorLines('diff removed inline', str.value);
481
494
  }
482
495
  return str.value;
483
496
  })
package/lib/runnable.js CHANGED
@@ -11,6 +11,7 @@ var createMultipleDoneError = errors.createMultipleDoneError;
11
11
 
12
12
  /**
13
13
  * Save timer references to avoid Sinon interfering (see GH-237).
14
+ * @private
14
15
  */
15
16
  var Date = global.Date;
16
17
  var setTimeout = global.setTimeout;
package/lib/runner.js CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  /**
4
4
  * Module dependencies.
5
+ * @private
5
6
  */
6
7
  var util = require('util');
7
8
  var EventEmitter = require('events').EventEmitter;
@@ -31,6 +32,7 @@ var createFatalError = errors.createFatalError;
31
32
 
32
33
  /**
33
34
  * Non-enumerable globals.
35
+ * @private
34
36
  * @readonly
35
37
  */
36
38
  var globals = [
@@ -358,6 +360,19 @@ Runner.prototype.checkGlobals = function(test) {
358
360
  /**
359
361
  * Fail the given `test`.
360
362
  *
363
+ * If `test` is a hook, failures work in the following pattern:
364
+ * - If bail, run corresponding `after each` and `after` hooks,
365
+ * then exit
366
+ * - Failed `before` hook skips all tests in a suite and subsuites,
367
+ * but jumps to corresponding `after` hook
368
+ * - Failed `before each` hook skips remaining tests in a
369
+ * suite and jumps to corresponding `after each` hook,
370
+ * which is run only once
371
+ * - Failed `after` hook does not alter execution order
372
+ * - Failed `after each` hook skips remaining tests in a
373
+ * suite and subsuites, but executes other `after each`
374
+ * hooks
375
+ *
361
376
  * @private
362
377
  * @param {Runnable} test
363
378
  * @param {Error} err
@@ -396,44 +411,6 @@ Runner.prototype.fail = function(test, err, force) {
396
411
  this.emit(constants.EVENT_TEST_FAIL, test, err);
397
412
  };
398
413
 
399
- /**
400
- * Fail the given `hook` with `err`.
401
- *
402
- * Hook failures work in the following pattern:
403
- * - If bail, run corresponding `after each` and `after` hooks,
404
- * then exit
405
- * - Failed `before` hook skips all tests in a suite and subsuites,
406
- * but jumps to corresponding `after` hook
407
- * - Failed `before each` hook skips remaining tests in a
408
- * suite and jumps to corresponding `after each` hook,
409
- * which is run only once
410
- * - Failed `after` hook does not alter execution order
411
- * - Failed `after each` hook skips remaining tests in a
412
- * suite and subsuites, but executes other `after each`
413
- * hooks
414
- *
415
- * @private
416
- * @param {Hook} hook
417
- * @param {Error} err
418
- */
419
- Runner.prototype.failHook = function(hook, err) {
420
- hook.originalTitle = hook.originalTitle || hook.title;
421
- if (hook.ctx && hook.ctx.currentTest) {
422
- hook.title =
423
- hook.originalTitle + ' for ' + dQuote(hook.ctx.currentTest.title);
424
- } else {
425
- var parentTitle;
426
- if (hook.parent.title) {
427
- parentTitle = hook.parent.title;
428
- } else {
429
- parentTitle = hook.parent.root ? '{root}' : '';
430
- }
431
- hook.title = hook.originalTitle + ' in ' + dQuote(parentTitle);
432
- }
433
-
434
- this.fail(hook, err);
435
- };
436
-
437
414
  /**
438
415
  * Run hook `name` callbacks and then invoke `fn()`.
439
416
  *
@@ -462,13 +439,15 @@ Runner.prototype.hook = function(name, fn) {
462
439
  hook.ctx.currentTest = self.test;
463
440
  }
464
441
 
442
+ setHookTitle(hook);
443
+
465
444
  hook.allowUncaught = self.allowUncaught;
466
445
 
467
446
  self.emit(constants.EVENT_HOOK_BEGIN, hook);
468
447
 
469
448
  if (!hook.listeners('error').length) {
470
449
  self._addEventListener(hook, 'error', function(err) {
471
- self.failHook(hook, err);
450
+ self.fail(hook, err);
472
451
  });
473
452
  }
474
453
 
@@ -502,18 +481,35 @@ Runner.prototype.hook = function(name, fn) {
502
481
  } else {
503
482
  hook.pending = false;
504
483
  var errForbid = createUnsupportedError('`this.skip` forbidden');
505
- self.failHook(hook, errForbid);
484
+ self.fail(hook, errForbid);
506
485
  return fn(errForbid);
507
486
  }
508
487
  } else if (err) {
509
- self.failHook(hook, err);
488
+ self.fail(hook, err);
510
489
  // stop executing hooks, notify callee of hook err
511
490
  return fn(err);
512
491
  }
513
492
  self.emit(constants.EVENT_HOOK_END, hook);
514
493
  delete hook.ctx.currentTest;
494
+ setHookTitle(hook);
515
495
  next(++i);
516
496
  });
497
+
498
+ function setHookTitle(hook) {
499
+ hook.originalTitle = hook.originalTitle || hook.title;
500
+ if (hook.ctx && hook.ctx.currentTest) {
501
+ hook.title =
502
+ hook.originalTitle + ' for ' + dQuote(hook.ctx.currentTest.title);
503
+ } else {
504
+ var parentTitle;
505
+ if (hook.parent.title) {
506
+ parentTitle = hook.parent.title;
507
+ } else {
508
+ parentTitle = hook.parent.root ? '{root}' : '';
509
+ }
510
+ hook.title = hook.originalTitle + ' in ' + dQuote(parentTitle);
511
+ }
512
+ }
517
513
  }
518
514
 
519
515
  Runner.immediately(function() {
package/lib/suite.js CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  /**
4
4
  * Module dependencies.
5
+ * @private
5
6
  */
6
7
  var EventEmitter = require('events').EventEmitter;
7
8
  var Hook = require('./hook');
package/lib/utils.js CHANGED
@@ -9,14 +9,9 @@
9
9
  * Module dependencies.
10
10
  */
11
11
 
12
- var fs = require('fs');
13
12
  var path = require('path');
14
13
  var util = require('util');
15
- var glob = require('glob');
16
14
  var he = require('he');
17
- var errors = require('./errors');
18
- var createNoFilesMatchPatternError = errors.createNoFilesMatchPatternError;
19
- var createMissingArgumentError = errors.createMissingArgumentError;
20
15
 
21
16
  var assign = (exports.assign = require('object.assign').getPolyfill());
22
17
 
@@ -96,67 +91,6 @@ exports.clean = function(str) {
96
91
  return str.trim();
97
92
  };
98
93
 
99
- /**
100
- * Parse the given `qs`.
101
- *
102
- * @private
103
- * @param {string} qs
104
- * @return {Object}
105
- */
106
- exports.parseQuery = function(qs) {
107
- return qs
108
- .replace('?', '')
109
- .split('&')
110
- .reduce(function(obj, pair) {
111
- var i = pair.indexOf('=');
112
- var key = pair.slice(0, i);
113
- var val = pair.slice(++i);
114
-
115
- // Due to how the URLSearchParams API treats spaces
116
- obj[key] = decodeURIComponent(val.replace(/\+/g, '%20'));
117
-
118
- return obj;
119
- }, {});
120
- };
121
-
122
- /**
123
- * Highlight the given string of `js`.
124
- *
125
- * @private
126
- * @param {string} js
127
- * @return {string}
128
- */
129
- function highlight(js) {
130
- return js
131
- .replace(/</g, '&lt;')
132
- .replace(/>/g, '&gt;')
133
- .replace(/\/\/(.*)/gm, '<span class="comment">//$1</span>')
134
- .replace(/('.*?')/gm, '<span class="string">$1</span>')
135
- .replace(/(\d+\.\d+)/gm, '<span class="number">$1</span>')
136
- .replace(/(\d+)/gm, '<span class="number">$1</span>')
137
- .replace(
138
- /\bnew[ \t]+(\w+)/gm,
139
- '<span class="keyword">new</span> <span class="init">$1</span>'
140
- )
141
- .replace(
142
- /\b(function|new|throw|return|var|if|else)\b/gm,
143
- '<span class="keyword">$1</span>'
144
- );
145
- }
146
-
147
- /**
148
- * Highlight the contents of tag `name`.
149
- *
150
- * @private
151
- * @param {string} name
152
- */
153
- exports.highlightTags = function(name) {
154
- var code = document.getElementById('mocha').getElementsByTagName(name);
155
- for (var i = 0, len = code.length; i < len; ++i) {
156
- code[i].innerHTML = highlight(code[i].innerHTML);
157
- }
158
- };
159
-
160
94
  /**
161
95
  * If a value could have properties, and has none, this function is called,
162
96
  * which returns a string representation of the empty value.
@@ -444,140 +378,6 @@ exports.canonicalize = function canonicalize(value, stack, typeHint) {
444
378
  return canonicalizedObj;
445
379
  };
446
380
 
447
- /**
448
- * Determines if pathname has a matching file extension.
449
- *
450
- * @private
451
- * @param {string} pathname - Pathname to check for match.
452
- * @param {string[]} exts - List of file extensions (sans period).
453
- * @return {boolean} whether file extension matches.
454
- * @example
455
- * hasMatchingExtname('foo.html', ['js', 'css']); // => false
456
- */
457
- function hasMatchingExtname(pathname, exts) {
458
- var suffix = path.extname(pathname).slice(1);
459
- return exts.some(function(element) {
460
- return suffix === element;
461
- });
462
- }
463
-
464
- /**
465
- * Determines if pathname would be a "hidden" file (or directory) on UN*X.
466
- *
467
- * @description
468
- * On UN*X, pathnames beginning with a full stop (aka dot) are hidden during
469
- * typical usage. Dotfiles, plain-text configuration files, are prime examples.
470
- *
471
- * @see {@link http://xahlee.info/UnixResource_dir/writ/unix_origin_of_dot_filename.html|Origin of Dot File Names}
472
- *
473
- * @private
474
- * @param {string} pathname - Pathname to check for match.
475
- * @return {boolean} whether pathname would be considered a hidden file.
476
- * @example
477
- * isHiddenOnUnix('.profile'); // => true
478
- */
479
- function isHiddenOnUnix(pathname) {
480
- return path.basename(pathname)[0] === '.';
481
- }
482
-
483
- /**
484
- * Lookup file names at the given `path`.
485
- *
486
- * @description
487
- * Filenames are returned in _traversal_ order by the OS/filesystem.
488
- * **Make no assumption that the names will be sorted in any fashion.**
489
- *
490
- * @public
491
- * @param {string} filepath - Base path to start searching from.
492
- * @param {string[]} [extensions=[]] - File extensions to look for.
493
- * @param {boolean} [recursive=false] - Whether to recurse into subdirectories.
494
- * @return {string[]} An array of paths.
495
- * @throws {Error} if no files match pattern.
496
- * @throws {TypeError} if `filepath` is directory and `extensions` not provided.
497
- */
498
- exports.lookupFiles = function lookupFiles(filepath, extensions, recursive) {
499
- extensions = extensions || [];
500
- recursive = recursive || false;
501
- var files = [];
502
- var stat;
503
-
504
- if (!fs.existsSync(filepath)) {
505
- var pattern;
506
- if (glob.hasMagic(filepath)) {
507
- // Handle glob as is without extensions
508
- pattern = filepath;
509
- } else {
510
- // glob pattern e.g. 'filepath+(.js|.ts)'
511
- var strExtensions = extensions
512
- .map(function(v) {
513
- return '.' + v;
514
- })
515
- .join('|');
516
- pattern = filepath + '+(' + strExtensions + ')';
517
- }
518
- files = glob.sync(pattern, {nodir: true});
519
- if (!files.length) {
520
- throw createNoFilesMatchPatternError(
521
- 'Cannot find any files matching pattern ' + exports.dQuote(filepath),
522
- filepath
523
- );
524
- }
525
- return files;
526
- }
527
-
528
- // Handle file
529
- try {
530
- stat = fs.statSync(filepath);
531
- if (stat.isFile()) {
532
- return filepath;
533
- }
534
- } catch (err) {
535
- // ignore error
536
- return;
537
- }
538
-
539
- // Handle directory
540
- fs.readdirSync(filepath).forEach(function(dirent) {
541
- var pathname = path.join(filepath, dirent);
542
- var stat;
543
-
544
- try {
545
- stat = fs.statSync(pathname);
546
- if (stat.isDirectory()) {
547
- if (recursive) {
548
- files = files.concat(lookupFiles(pathname, extensions, recursive));
549
- }
550
- return;
551
- }
552
- } catch (err) {
553
- // ignore error
554
- return;
555
- }
556
- if (!extensions.length) {
557
- throw createMissingArgumentError(
558
- util.format(
559
- 'Argument %s required when argument %s is a directory',
560
- exports.sQuote('extensions'),
561
- exports.sQuote('filepath')
562
- ),
563
- 'extensions',
564
- 'array'
565
- );
566
- }
567
-
568
- if (
569
- !stat.isFile() ||
570
- !hasMatchingExtname(pathname, extensions) ||
571
- isHiddenOnUnix(pathname)
572
- ) {
573
- return;
574
- }
575
- files.push(pathname);
576
- });
577
-
578
- return files;
579
- };
580
-
581
381
  /**
582
382
  * process.emitWarning or a polyfill
583
383
  * @see https://nodejs.org/api/process.html#process_process_emitwarning_warning_options
@@ -804,7 +604,7 @@ exports.defineConstants = function(obj) {
804
604
  * Whether current version of Node support ES modules
805
605
  *
806
606
  * @description
807
- * Versions prior to 10 did not support ES Modules, and version 10 has an old incompatibile version of ESM.
607
+ * Versions prior to 10 did not support ES Modules, and version 10 has an old incompatible version of ESM.
808
608
  * This function returns whether Node.JS has ES Module supports that is compatible with Mocha's needs,
809
609
  * which is version >=12.11.
810
610
  *