mocha 6.1.0 → 6.1.4

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 (61) hide show
  1. package/CHANGELOG.md +1776 -1751
  2. package/LICENSE +22 -22
  3. package/README.md +105 -105
  4. package/bin/_mocha +10 -10
  5. package/bin/mocha +149 -149
  6. package/bin/options.js +10 -10
  7. package/browser-entry.js +191 -191
  8. package/index.js +3 -3
  9. package/lib/browser/growl.js +168 -168
  10. package/lib/browser/progress.js +119 -119
  11. package/lib/browser/template.html +18 -18
  12. package/lib/browser/tty.js +13 -13
  13. package/lib/cli/cli.js +69 -69
  14. package/lib/cli/commands.js +13 -13
  15. package/lib/cli/config.js +101 -101
  16. package/lib/cli/index.js +9 -9
  17. package/lib/cli/init.js +37 -37
  18. package/lib/cli/node-flags.js +86 -86
  19. package/lib/cli/one-and-dones.js +70 -70
  20. package/lib/cli/options.js +347 -347
  21. package/lib/cli/run-helpers.js +337 -337
  22. package/lib/cli/run-option-metadata.js +76 -76
  23. package/lib/cli/run.js +297 -297
  24. package/lib/context.js +101 -101
  25. package/lib/errors.js +141 -141
  26. package/lib/growl.js +136 -136
  27. package/lib/hook.js +46 -46
  28. package/lib/interfaces/bdd.js +118 -118
  29. package/lib/interfaces/common.js +191 -191
  30. package/lib/interfaces/exports.js +60 -60
  31. package/lib/interfaces/index.js +6 -6
  32. package/lib/interfaces/qunit.js +99 -99
  33. package/lib/interfaces/tdd.js +107 -107
  34. package/lib/mocha.js +843 -843
  35. package/lib/mocharc.json +10 -10
  36. package/lib/pending.js +12 -12
  37. package/lib/reporters/base.js +491 -491
  38. package/lib/reporters/doc.js +85 -85
  39. package/lib/reporters/dot.js +81 -81
  40. package/lib/reporters/html.js +390 -390
  41. package/lib/reporters/index.js +19 -19
  42. package/lib/reporters/json-stream.js +90 -90
  43. package/lib/reporters/json.js +135 -135
  44. package/lib/reporters/landing.js +108 -108
  45. package/lib/reporters/list.js +78 -78
  46. package/lib/reporters/markdown.js +112 -112
  47. package/lib/reporters/min.js +52 -52
  48. package/lib/reporters/nyan.js +276 -276
  49. package/lib/reporters/progress.js +104 -104
  50. package/lib/reporters/spec.js +99 -99
  51. package/lib/reporters/tap.js +294 -294
  52. package/lib/reporters/xunit.js +216 -216
  53. package/lib/runnable.js +496 -496
  54. package/lib/runner.js +1049 -1049
  55. package/lib/stats-collector.js +83 -83
  56. package/lib/suite.js +642 -642
  57. package/lib/test.js +51 -51
  58. package/lib/utils.js +897 -897
  59. package/mocha.css +326 -326
  60. package/mocha.js +8170 -8476
  61. package/package.json +630 -628
package/lib/mocha.js CHANGED
@@ -1,843 +1,843 @@
1
- 'use strict';
2
-
3
- /*!
4
- * mocha
5
- * Copyright(c) 2011 TJ Holowaychuk <tj@vision-media.ca>
6
- * MIT Licensed
7
- */
8
-
9
- var escapeRe = require('escape-string-regexp');
10
- var path = require('path');
11
- var builtinReporters = require('./reporters');
12
- var growl = require('./growl');
13
- var utils = require('./utils');
14
- var mocharc = require('./mocharc.json');
15
- var errors = require('./errors');
16
- var Suite = require('./suite');
17
- var createStatsCollector = require('./stats-collector');
18
- var createInvalidReporterError = errors.createInvalidReporterError;
19
- var createInvalidInterfaceError = errors.createInvalidInterfaceError;
20
- var EVENT_FILE_PRE_REQUIRE = Suite.constants.EVENT_FILE_PRE_REQUIRE;
21
- var EVENT_FILE_POST_REQUIRE = Suite.constants.EVENT_FILE_POST_REQUIRE;
22
- var EVENT_FILE_REQUIRE = Suite.constants.EVENT_FILE_REQUIRE;
23
- var sQuote = utils.sQuote;
24
-
25
- exports = module.exports = Mocha;
26
-
27
- /**
28
- * To require local UIs and reporters when running in node.
29
- */
30
-
31
- if (!process.browser) {
32
- var cwd = process.cwd();
33
- module.paths.push(cwd, path.join(cwd, 'node_modules'));
34
- }
35
-
36
- /**
37
- * Expose internals.
38
- */
39
-
40
- /**
41
- * @public
42
- * @class utils
43
- * @memberof Mocha
44
- */
45
- exports.utils = utils;
46
- exports.interfaces = require('./interfaces');
47
- /**
48
- * @public
49
- * @memberof Mocha
50
- */
51
- exports.reporters = builtinReporters;
52
- exports.Runnable = require('./runnable');
53
- exports.Context = require('./context');
54
- /**
55
- *
56
- * @memberof Mocha
57
- */
58
- exports.Runner = require('./runner');
59
- exports.Suite = Suite;
60
- exports.Hook = require('./hook');
61
- exports.Test = require('./test');
62
-
63
- /**
64
- * Constructs a new Mocha instance with `options`.
65
- *
66
- * @public
67
- * @class Mocha
68
- * @param {Object} [options] - Settings object.
69
- * @param {boolean} [options.allowUncaught] - Propagate uncaught errors?
70
- * @param {boolean} [options.asyncOnly] - Force `done` callback or promise?
71
- * @param {boolean} [options.bail] - Bail after first test failure?
72
- * @param {boolean} [options.checkLeaks] - If true, check leaks.
73
- * @param {boolean} [options.delay] - Delay root suite execution?
74
- * @param {boolean} [options.enableTimeouts] - Enable timeouts?
75
- * @param {string} [options.fgrep] - Test filter given string.
76
- * @param {boolean} [options.forbidOnly] - Tests marked `only` fail the suite?
77
- * @param {boolean} [options.forbidPending] - Pending tests fail the suite?
78
- * @param {boolean} [options.fullStackTrace] - Full stacktrace upon failure?
79
- * @param {string[]} [options.global] - Variables expected in global scope.
80
- * @param {RegExp|string} [options.grep] - Test filter given regular expression.
81
- * @param {boolean} [options.growl] - Enable desktop notifications?
82
- * @param {boolean} [options.hideDiff] - Suppress diffs from failures?
83
- * @param {boolean} [options.ignoreLeaks] - Ignore global leaks?
84
- * @param {boolean} [options.invert] - Invert test filter matches?
85
- * @param {boolean} [options.noHighlighting] - Disable syntax highlighting?
86
- * @param {string} [options.reporter] - Reporter name.
87
- * @param {Object} [options.reporterOption] - Reporter settings object.
88
- * @param {number} [options.retries] - Number of times to retry failed tests.
89
- * @param {number} [options.slow] - Slow threshold value.
90
- * @param {number|string} [options.timeout] - Timeout threshold value.
91
- * @param {string} [options.ui] - Interface name.
92
- * @param {boolean} [options.color] - Color TTY output from reporter?
93
- * @param {boolean} [options.useInlineDiffs] - Use inline diffs?
94
- */
95
- function Mocha(options) {
96
- options = utils.assign({}, mocharc, options || {});
97
- this.files = [];
98
- this.options = options;
99
- // root suite
100
- this.suite = new exports.Suite('', new exports.Context(), true);
101
-
102
- if ('useColors' in options) {
103
- utils.deprecate(
104
- 'useColors is DEPRECATED and will be removed from a future version of Mocha. Instead, use the "color" option'
105
- );
106
- options.color = 'color' in options ? options.color : options.useColors;
107
- }
108
-
109
- this.grep(options.grep)
110
- .fgrep(options.fgrep)
111
- .ui(options.ui)
112
- .bail(options.bail)
113
- .reporter(options.reporter, options.reporterOptions)
114
- .useColors(options.color)
115
- .slow(options.slow)
116
- .useInlineDiffs(options.inlineDiffs)
117
- .globals(options.globals);
118
-
119
- if ('enableTimeouts' in options) {
120
- utils.deprecate(
121
- 'enableTimeouts is DEPRECATED and will be removed from a future version of Mocha. Instead, use "timeout: false" to disable timeouts.'
122
- );
123
- if (options.enableTimeouts === false) {
124
- this.timeout(0);
125
- }
126
- }
127
-
128
- // this guard exists because Suite#timeout does not consider `undefined` to be valid input
129
- if (typeof options.timeout !== 'undefined') {
130
- this.timeout(options.timeout === false ? 0 : options.timeout);
131
- }
132
-
133
- if ('retries' in options) {
134
- this.retries(options.retries);
135
- }
136
-
137
- if ('diff' in options) {
138
- this.hideDiff(!options.diff);
139
- }
140
-
141
- [
142
- 'allowUncaught',
143
- 'asyncOnly',
144
- 'checkLeaks',
145
- 'delay',
146
- 'forbidOnly',
147
- 'forbidPending',
148
- 'fullTrace',
149
- 'growl',
150
- 'invert'
151
- ].forEach(function(opt) {
152
- if (options[opt]) {
153
- this[opt]();
154
- }
155
- }, this);
156
- }
157
-
158
- /**
159
- * Enables or disables bailing on the first failure.
160
- *
161
- * @public
162
- * @see {@link https://mochajs.org/#-b---bail|CLI option}
163
- * @param {boolean} [bail=true] - Whether to bail on first error.
164
- * @returns {Mocha} this
165
- * @chainable
166
- */
167
- Mocha.prototype.bail = function(bail) {
168
- if (!arguments.length) {
169
- bail = true;
170
- }
171
- this.suite.bail(bail);
172
- return this;
173
- };
174
-
175
- /**
176
- * @summary
177
- * Adds `file` to be loaded for execution.
178
- *
179
- * @description
180
- * Useful for generic setup code that must be included within test suite.
181
- *
182
- * @public
183
- * @see {@link https://mochajs.org/#--file-file|CLI option}
184
- * @param {string} file - Pathname of file to be loaded.
185
- * @returns {Mocha} this
186
- * @chainable
187
- */
188
- Mocha.prototype.addFile = function(file) {
189
- this.files.push(file);
190
- return this;
191
- };
192
-
193
- /**
194
- * Sets reporter to `reporter`, defaults to "spec".
195
- *
196
- * @public
197
- * @see {@link https://mochajs.org/#-r---reporter-name|CLI option}
198
- * @see {@link https://mochajs.org/#reporters|Reporters}
199
- * @param {String|Function} reporter - Reporter name or constructor.
200
- * @param {Object} [reporterOptions] - Options used to configure the reporter.
201
- * @returns {Mocha} this
202
- * @chainable
203
- * @throws {Error} if requested reporter cannot be loaded
204
- * @example
205
- *
206
- * // Use XUnit reporter and direct its output to file
207
- * mocha.reporter('xunit', { output: '/path/to/testspec.xunit.xml' });
208
- */
209
- Mocha.prototype.reporter = function(reporter, reporterOptions) {
210
- if (typeof reporter === 'function') {
211
- this._reporter = reporter;
212
- } else {
213
- reporter = reporter || 'spec';
214
- var _reporter;
215
- // Try to load a built-in reporter.
216
- if (builtinReporters[reporter]) {
217
- _reporter = builtinReporters[reporter];
218
- }
219
- // Try to load reporters from process.cwd() and node_modules
220
- if (!_reporter) {
221
- try {
222
- _reporter = require(reporter);
223
- } catch (err) {
224
- if (
225
- err.code !== 'MODULE_NOT_FOUND' ||
226
- err.message.indexOf('Cannot find module') !== -1
227
- ) {
228
- // Try to load reporters from a path (absolute or relative)
229
- try {
230
- _reporter = require(path.resolve(process.cwd(), reporter));
231
- } catch (_err) {
232
- _err.code !== 'MODULE_NOT_FOUND' ||
233
- _err.message.indexOf('Cannot find module') !== -1
234
- ? console.warn(sQuote(reporter) + ' reporter not found')
235
- : console.warn(
236
- sQuote(reporter) +
237
- ' reporter blew up with error:\n' +
238
- err.stack
239
- );
240
- }
241
- } else {
242
- console.warn(
243
- sQuote(reporter) + ' reporter blew up with error:\n' + err.stack
244
- );
245
- }
246
- }
247
- }
248
- if (!_reporter) {
249
- throw createInvalidReporterError(
250
- 'invalid reporter ' + sQuote(reporter),
251
- reporter
252
- );
253
- }
254
- this._reporter = _reporter;
255
- }
256
- this.options.reporterOptions = reporterOptions;
257
- return this;
258
- };
259
-
260
- /**
261
- * Sets test UI `name`, defaults to "bdd".
262
- *
263
- * @public
264
- * @see {@link https://mochajs.org/#-u---ui-name|CLI option}
265
- * @see {@link https://mochajs.org/#interfaces|Interface DSLs}
266
- * @param {string|Function} [ui=bdd] - Interface name or class.
267
- * @returns {Mocha} this
268
- * @chainable
269
- * @throws {Error} if requested interface cannot be loaded
270
- */
271
- Mocha.prototype.ui = function(ui) {
272
- var bindInterface;
273
- if (typeof ui === 'function') {
274
- bindInterface = ui;
275
- } else {
276
- ui = ui || 'bdd';
277
- bindInterface = exports.interfaces[ui];
278
- if (!bindInterface) {
279
- try {
280
- bindInterface = require(ui);
281
- } catch (err) {
282
- throw createInvalidInterfaceError(
283
- 'invalid interface ' + sQuote(ui),
284
- ui
285
- );
286
- }
287
- }
288
- }
289
- bindInterface(this.suite);
290
-
291
- this.suite.on(EVENT_FILE_PRE_REQUIRE, function(context) {
292
- exports.afterEach = context.afterEach || context.teardown;
293
- exports.after = context.after || context.suiteTeardown;
294
- exports.beforeEach = context.beforeEach || context.setup;
295
- exports.before = context.before || context.suiteSetup;
296
- exports.describe = context.describe || context.suite;
297
- exports.it = context.it || context.test;
298
- exports.xit = context.xit || (context.test && context.test.skip);
299
- exports.setup = context.setup || context.beforeEach;
300
- exports.suiteSetup = context.suiteSetup || context.before;
301
- exports.suiteTeardown = context.suiteTeardown || context.after;
302
- exports.suite = context.suite || context.describe;
303
- exports.teardown = context.teardown || context.afterEach;
304
- exports.test = context.test || context.it;
305
- exports.run = context.run;
306
- });
307
-
308
- return this;
309
- };
310
-
311
- /**
312
- * Loads `files` prior to execution.
313
- *
314
- * @description
315
- * The implementation relies on Node's `require` to execute
316
- * the test interface functions and will be subject to its cache.
317
- *
318
- * @private
319
- * @see {@link Mocha#addFile}
320
- * @see {@link Mocha#run}
321
- * @see {@link Mocha#unloadFiles}
322
- * @param {Function} [fn] - Callback invoked upon completion.
323
- */
324
- Mocha.prototype.loadFiles = function(fn) {
325
- var self = this;
326
- var suite = this.suite;
327
- this.files.forEach(function(file) {
328
- file = path.resolve(file);
329
- suite.emit(EVENT_FILE_PRE_REQUIRE, global, file, self);
330
- suite.emit(EVENT_FILE_REQUIRE, require(file), file, self);
331
- suite.emit(EVENT_FILE_POST_REQUIRE, global, file, self);
332
- });
333
- fn && fn();
334
- };
335
-
336
- /**
337
- * Removes a previously loaded file from Node's `require` cache.
338
- *
339
- * @private
340
- * @static
341
- * @see {@link Mocha#unloadFiles}
342
- * @param {string} file - Pathname of file to be unloaded.
343
- */
344
- Mocha.unloadFile = function(file) {
345
- delete require.cache[require.resolve(file)];
346
- };
347
-
348
- /**
349
- * Unloads `files` from Node's `require` cache.
350
- *
351
- * @description
352
- * This allows files to be "freshly" reloaded, providing the ability
353
- * to reuse a Mocha instance programmatically.
354
- *
355
- * <strong>Intended for consumers &mdash; not used internally</strong>
356
- *
357
- * @public
358
- * @see {@link Mocha.unloadFile}
359
- * @see {@link Mocha#loadFiles}
360
- * @see {@link Mocha#run}
361
- * @returns {Mocha} this
362
- * @chainable
363
- */
364
- Mocha.prototype.unloadFiles = function() {
365
- this.files.forEach(Mocha.unloadFile);
366
- return this;
367
- };
368
-
369
- /**
370
- * Sets `grep` filter after escaping RegExp special characters.
371
- *
372
- * @public
373
- * @see {@link Mocha#grep}
374
- * @param {string} str - Value to be converted to a regexp.
375
- * @returns {Mocha} this
376
- * @chainable
377
- * @example
378
- *
379
- * // Select tests whose full title begins with `"foo"` followed by a period
380
- * mocha.fgrep('foo.');
381
- */
382
- Mocha.prototype.fgrep = function(str) {
383
- if (!str) {
384
- return this;
385
- }
386
- return this.grep(new RegExp(escapeRe(str)));
387
- };
388
-
389
- /**
390
- * @summary
391
- * Sets `grep` filter used to select specific tests for execution.
392
- *
393
- * @description
394
- * If `re` is a regexp-like string, it will be converted to regexp.
395
- * The regexp is tested against the full title of each test (i.e., the
396
- * name of the test preceded by titles of each its ancestral suites).
397
- * As such, using an <em>exact-match</em> fixed pattern against the
398
- * test name itself will not yield any matches.
399
- * <br>
400
- * <strong>Previous filter value will be overwritten on each call!</strong>
401
- *
402
- * @public
403
- * @see {@link https://mochajs.org/#-g---grep-pattern|CLI option}
404
- * @see {@link Mocha#fgrep}
405
- * @see {@link Mocha#invert}
406
- * @param {RegExp|String} re - Regular expression used to select tests.
407
- * @return {Mocha} this
408
- * @chainable
409
- * @example
410
- *
411
- * // Select tests whose full title contains `"match"`, ignoring case
412
- * mocha.grep(/match/i);
413
- * @example
414
- *
415
- * // Same as above but with regexp-like string argument
416
- * mocha.grep('/match/i');
417
- * @example
418
- *
419
- * // ## Anti-example
420
- * // Given embedded test `it('only-this-test')`...
421
- * mocha.grep('/^only-this-test$/'); // NO! Use `.only()` to do this!
422
- */
423
- Mocha.prototype.grep = function(re) {
424
- if (utils.isString(re)) {
425
- // extract args if it's regex-like, i.e: [string, pattern, flag]
426
- var arg = re.match(/^\/(.*)\/(g|i|)$|.*/);
427
- this.options.grep = new RegExp(arg[1] || arg[0], arg[2]);
428
- } else {
429
- this.options.grep = re;
430
- }
431
- return this;
432
- };
433
-
434
- /**
435
- * Inverts `grep` matches.
436
- *
437
- * @public
438
- * @see {@link Mocha#grep}
439
- * @return {Mocha} this
440
- * @chainable
441
- * @example
442
- *
443
- * // Select tests whose full title does *not* contain `"match"`, ignoring case
444
- * mocha.grep(/match/i).invert();
445
- */
446
- Mocha.prototype.invert = function() {
447
- this.options.invert = true;
448
- return this;
449
- };
450
-
451
- /**
452
- * Enables or disables ignoring global leaks.
453
- *
454
- * @public
455
- * @see {@link Mocha#checkLeaks}
456
- * @param {boolean} ignoreLeaks - Whether to ignore global leaks.
457
- * @return {Mocha} this
458
- * @chainable
459
- * @example
460
- *
461
- * // Ignore global leaks
462
- * mocha.ignoreLeaks(true);
463
- */
464
- Mocha.prototype.ignoreLeaks = function(ignoreLeaks) {
465
- this.options.ignoreLeaks = Boolean(ignoreLeaks);
466
- return this;
467
- };
468
-
469
- /**
470
- * Enables checking for global variables leaked while running tests.
471
- *
472
- * @public
473
- * @see {@link https://mochajs.org/#--check-leaks|CLI option}
474
- * @see {@link Mocha#ignoreLeaks}
475
- * @return {Mocha} this
476
- * @chainable
477
- */
478
- Mocha.prototype.checkLeaks = function() {
479
- this.options.ignoreLeaks = false;
480
- return this;
481
- };
482
-
483
- /**
484
- * Displays full stack trace upon test failure.
485
- *
486
- * @public
487
- * @return {Mocha} this
488
- * @chainable
489
- */
490
- Mocha.prototype.fullTrace = function() {
491
- this.options.fullStackTrace = true;
492
- return this;
493
- };
494
-
495
- /**
496
- * Enables desktop notification support if prerequisite software installed.
497
- *
498
- * @public
499
- * @see {@link Mocha#isGrowlCapable}
500
- * @see {@link Mocha#_growl}
501
- * @return {Mocha} this
502
- * @chainable
503
- */
504
- Mocha.prototype.growl = function() {
505
- this.options.growl = this.isGrowlCapable();
506
- if (!this.options.growl) {
507
- var detail = process.browser
508
- ? 'notification support not available in this browser...'
509
- : 'notification support prerequisites not installed...';
510
- console.error(detail + ' cannot enable!');
511
- }
512
- return this;
513
- };
514
-
515
- /**
516
- * @summary
517
- * Determines if Growl support seems likely.
518
- *
519
- * @description
520
- * <strong>Not available when run in browser.</strong>
521
- *
522
- * @private
523
- * @see {@link Growl#isCapable}
524
- * @see {@link Mocha#growl}
525
- * @return {boolean} whether Growl support can be expected
526
- */
527
- Mocha.prototype.isGrowlCapable = growl.isCapable;
528
-
529
- /**
530
- * Implements desktop notifications using a pseudo-reporter.
531
- *
532
- * @private
533
- * @see {@link Mocha#growl}
534
- * @see {@link Growl#notify}
535
- * @param {Runner} runner - Runner instance.
536
- */
537
- Mocha.prototype._growl = growl.notify;
538
-
539
- /**
540
- * Specifies whitelist of variable names to be expected in global scope.
541
- *
542
- * @public
543
- * @see {@link https://mochajs.org/#--globals-names|CLI option}
544
- * @see {@link Mocha#checkLeaks}
545
- * @param {String[]|String} globals - Accepted global variable name(s).
546
- * @return {Mocha} this
547
- * @chainable
548
- * @example
549
- *
550
- * // Specify variables to be expected in global scope
551
- * mocha.globals(['jQuery', 'MyLib']);
552
- */
553
- Mocha.prototype.globals = function(globals) {
554
- this.options.globals = (this.options.globals || [])
555
- .concat(globals)
556
- .filter(Boolean);
557
- return this;
558
- };
559
-
560
- /**
561
- * Enables or disables TTY color output by screen-oriented reporters.
562
- *
563
- * @public
564
- * @param {boolean} colors - Whether to enable color output.
565
- * @return {Mocha} this
566
- * @chainable
567
- */
568
- Mocha.prototype.useColors = function(colors) {
569
- if (colors !== undefined) {
570
- this.options.useColors = colors;
571
- }
572
- return this;
573
- };
574
-
575
- /**
576
- * Determines if reporter should use inline diffs (rather than +/-)
577
- * in test failure output.
578
- *
579
- * @public
580
- * @param {boolean} inlineDiffs - Whether to use inline diffs.
581
- * @return {Mocha} this
582
- * @chainable
583
- */
584
- Mocha.prototype.useInlineDiffs = function(inlineDiffs) {
585
- this.options.useInlineDiffs = inlineDiffs !== undefined && inlineDiffs;
586
- return this;
587
- };
588
-
589
- /**
590
- * Determines if reporter should include diffs in test failure output.
591
- *
592
- * @public
593
- * @param {boolean} hideDiff - Whether to hide diffs.
594
- * @return {Mocha} this
595
- * @chainable
596
- */
597
- Mocha.prototype.hideDiff = function(hideDiff) {
598
- this.options.hideDiff = hideDiff !== undefined && hideDiff;
599
- return this;
600
- };
601
-
602
- /**
603
- * @summary
604
- * Sets timeout threshold value.
605
- *
606
- * @description
607
- * A string argument can use shorthand (such as "2s") and will be converted.
608
- * If the value is `0`, timeouts will be disabled.
609
- *
610
- * @public
611
- * @see {@link https://mochajs.org/#-t---timeout-ms|CLI option}
612
- * @see {@link https://mochajs.org/#--no-timeouts|CLI option}
613
- * @see {@link https://mochajs.org/#timeouts|Timeouts}
614
- * @see {@link Mocha#enableTimeouts}
615
- * @param {number|string} msecs - Timeout threshold value.
616
- * @return {Mocha} this
617
- * @chainable
618
- * @example
619
- *
620
- * // Sets timeout to one second
621
- * mocha.timeout(1000);
622
- * @example
623
- *
624
- * // Same as above but using string argument
625
- * mocha.timeout('1s');
626
- */
627
- Mocha.prototype.timeout = function(msecs) {
628
- this.suite.timeout(msecs);
629
- return this;
630
- };
631
-
632
- /**
633
- * Sets the number of times to retry failed tests.
634
- *
635
- * @public
636
- * @see {@link https://mochajs.org/#retry-tests|Retry Tests}
637
- * @param {number} retry - Number of times to retry failed tests.
638
- * @return {Mocha} this
639
- * @chainable
640
- * @example
641
- *
642
- * // Allow any failed test to retry one more time
643
- * mocha.retries(1);
644
- */
645
- Mocha.prototype.retries = function(n) {
646
- this.suite.retries(n);
647
- return this;
648
- };
649
-
650
- /**
651
- * Sets slowness threshold value.
652
- *
653
- * @public
654
- * @see {@link https://mochajs.org/#-s---slow-ms|CLI option}
655
- * @param {number} msecs - Slowness threshold value.
656
- * @return {Mocha} this
657
- * @chainable
658
- * @example
659
- *
660
- * // Sets "slow" threshold to half a second
661
- * mocha.slow(500);
662
- * @example
663
- *
664
- * // Same as above but using string argument
665
- * mocha.slow('0.5s');
666
- */
667
- Mocha.prototype.slow = function(msecs) {
668
- this.suite.slow(msecs);
669
- return this;
670
- };
671
-
672
- /**
673
- * Enables or disables timeouts.
674
- *
675
- * @public
676
- * @see {@link https://mochajs.org/#-t---timeout-ms|CLI option}
677
- * @see {@link https://mochajs.org/#--no-timeouts|CLI option}
678
- * @param {boolean} enableTimeouts - Whether to enable timeouts.
679
- * @return {Mocha} this
680
- * @chainable
681
- */
682
- Mocha.prototype.enableTimeouts = function(enableTimeouts) {
683
- this.suite.enableTimeouts(
684
- arguments.length && enableTimeouts !== undefined ? enableTimeouts : true
685
- );
686
- return this;
687
- };
688
-
689
- /**
690
- * Forces all tests to either accept a `done` callback or return a promise.
691
- *
692
- * @public
693
- * @return {Mocha} this
694
- * @chainable
695
- */
696
- Mocha.prototype.asyncOnly = function() {
697
- this.options.asyncOnly = true;
698
- return this;
699
- };
700
-
701
- /**
702
- * Disables syntax highlighting (in browser).
703
- *
704
- * @public
705
- * @return {Mocha} this
706
- * @chainable
707
- */
708
- Mocha.prototype.noHighlighting = function() {
709
- this.options.noHighlighting = true;
710
- return this;
711
- };
712
-
713
- /**
714
- * Enables uncaught errors to propagate (in browser).
715
- *
716
- * @public
717
- * @return {Mocha} this
718
- * @chainable
719
- */
720
- Mocha.prototype.allowUncaught = function() {
721
- this.options.allowUncaught = true;
722
- return this;
723
- };
724
-
725
- /**
726
- * @summary
727
- * Delays root suite execution.
728
- *
729
- * @description
730
- * Used to perform asynch operations before any suites are run.
731
- *
732
- * @public
733
- * @see {@link https://mochajs.org/#delayed-root-suite|delayed root suite}
734
- * @returns {Mocha} this
735
- * @chainable
736
- */
737
- Mocha.prototype.delay = function delay() {
738
- this.options.delay = true;
739
- return this;
740
- };
741
-
742
- /**
743
- * Causes tests marked `only` to fail the suite.
744
- *
745
- * @public
746
- * @returns {Mocha} this
747
- * @chainable
748
- */
749
- Mocha.prototype.forbidOnly = function() {
750
- this.options.forbidOnly = true;
751
- return this;
752
- };
753
-
754
- /**
755
- * Causes pending tests and tests marked `skip` to fail the suite.
756
- *
757
- * @public
758
- * @returns {Mocha} this
759
- * @chainable
760
- */
761
- Mocha.prototype.forbidPending = function() {
762
- this.options.forbidPending = true;
763
- return this;
764
- };
765
-
766
- /**
767
- * Mocha version as specified by "package.json".
768
- *
769
- * @name Mocha#version
770
- * @type string
771
- * @readonly
772
- */
773
- Object.defineProperty(Mocha.prototype, 'version', {
774
- value: require('../package.json').version,
775
- configurable: false,
776
- enumerable: true,
777
- writable: false
778
- });
779
-
780
- /**
781
- * Callback to be invoked when test execution is complete.
782
- *
783
- * @callback DoneCB
784
- * @param {number} failures - Number of failures that occurred.
785
- */
786
-
787
- /**
788
- * Runs root suite and invokes `fn()` when complete.
789
- *
790
- * @description
791
- * To run tests multiple times (or to run tests in files that are
792
- * already in the `require` cache), make sure to clear them from
793
- * the cache first!
794
- *
795
- * @public
796
- * @see {@link Mocha#loadFiles}
797
- * @see {@link Mocha#unloadFiles}
798
- * @see {@link Runner#run}
799
- * @param {DoneCB} [fn] - Callback invoked when test execution completed.
800
- * @return {Runner} runner instance
801
- */
802
- Mocha.prototype.run = function(fn) {
803
- if (this.files.length) {
804
- this.loadFiles();
805
- }
806
- var suite = this.suite;
807
- var options = this.options;
808
- options.files = this.files;
809
- var runner = new exports.Runner(suite, options.delay);
810
- createStatsCollector(runner);
811
- var reporter = new this._reporter(runner, options);
812
- runner.ignoreLeaks = options.ignoreLeaks !== false;
813
- runner.fullStackTrace = options.fullStackTrace;
814
- runner.asyncOnly = options.asyncOnly;
815
- runner.allowUncaught = options.allowUncaught;
816
- runner.forbidOnly = options.forbidOnly;
817
- runner.forbidPending = options.forbidPending;
818
- if (options.grep) {
819
- runner.grep(options.grep, options.invert);
820
- }
821
- if (options.globals) {
822
- runner.globals(options.globals);
823
- }
824
- if (options.growl) {
825
- this._growl(runner);
826
- }
827
- if (options.useColors !== undefined) {
828
- exports.reporters.Base.useColors = options.useColors;
829
- }
830
- exports.reporters.Base.inlineDiffs = options.useInlineDiffs;
831
- exports.reporters.Base.hideDiff = options.hideDiff;
832
-
833
- function done(failures) {
834
- fn = fn || utils.noop;
835
- if (reporter.done) {
836
- reporter.done(failures, fn);
837
- } else {
838
- fn(failures);
839
- }
840
- }
841
-
842
- return runner.run(done);
843
- };
1
+ 'use strict';
2
+
3
+ /*!
4
+ * mocha
5
+ * Copyright(c) 2011 TJ Holowaychuk <tj@vision-media.ca>
6
+ * MIT Licensed
7
+ */
8
+
9
+ var escapeRe = require('escape-string-regexp');
10
+ var path = require('path');
11
+ var builtinReporters = require('./reporters');
12
+ var growl = require('./growl');
13
+ var utils = require('./utils');
14
+ var mocharc = require('./mocharc.json');
15
+ var errors = require('./errors');
16
+ var Suite = require('./suite');
17
+ var createStatsCollector = require('./stats-collector');
18
+ var createInvalidReporterError = errors.createInvalidReporterError;
19
+ var createInvalidInterfaceError = errors.createInvalidInterfaceError;
20
+ var EVENT_FILE_PRE_REQUIRE = Suite.constants.EVENT_FILE_PRE_REQUIRE;
21
+ var EVENT_FILE_POST_REQUIRE = Suite.constants.EVENT_FILE_POST_REQUIRE;
22
+ var EVENT_FILE_REQUIRE = Suite.constants.EVENT_FILE_REQUIRE;
23
+ var sQuote = utils.sQuote;
24
+
25
+ exports = module.exports = Mocha;
26
+
27
+ /**
28
+ * To require local UIs and reporters when running in node.
29
+ */
30
+
31
+ if (!process.browser) {
32
+ var cwd = process.cwd();
33
+ module.paths.push(cwd, path.join(cwd, 'node_modules'));
34
+ }
35
+
36
+ /**
37
+ * Expose internals.
38
+ */
39
+
40
+ /**
41
+ * @public
42
+ * @class utils
43
+ * @memberof Mocha
44
+ */
45
+ exports.utils = utils;
46
+ exports.interfaces = require('./interfaces');
47
+ /**
48
+ * @public
49
+ * @memberof Mocha
50
+ */
51
+ exports.reporters = builtinReporters;
52
+ exports.Runnable = require('./runnable');
53
+ exports.Context = require('./context');
54
+ /**
55
+ *
56
+ * @memberof Mocha
57
+ */
58
+ exports.Runner = require('./runner');
59
+ exports.Suite = Suite;
60
+ exports.Hook = require('./hook');
61
+ exports.Test = require('./test');
62
+
63
+ /**
64
+ * Constructs a new Mocha instance with `options`.
65
+ *
66
+ * @public
67
+ * @class Mocha
68
+ * @param {Object} [options] - Settings object.
69
+ * @param {boolean} [options.allowUncaught] - Propagate uncaught errors?
70
+ * @param {boolean} [options.asyncOnly] - Force `done` callback or promise?
71
+ * @param {boolean} [options.bail] - Bail after first test failure?
72
+ * @param {boolean} [options.checkLeaks] - If true, check leaks.
73
+ * @param {boolean} [options.delay] - Delay root suite execution?
74
+ * @param {boolean} [options.enableTimeouts] - Enable timeouts?
75
+ * @param {string} [options.fgrep] - Test filter given string.
76
+ * @param {boolean} [options.forbidOnly] - Tests marked `only` fail the suite?
77
+ * @param {boolean} [options.forbidPending] - Pending tests fail the suite?
78
+ * @param {boolean} [options.fullStackTrace] - Full stacktrace upon failure?
79
+ * @param {string[]} [options.global] - Variables expected in global scope.
80
+ * @param {RegExp|string} [options.grep] - Test filter given regular expression.
81
+ * @param {boolean} [options.growl] - Enable desktop notifications?
82
+ * @param {boolean} [options.hideDiff] - Suppress diffs from failures?
83
+ * @param {boolean} [options.ignoreLeaks] - Ignore global leaks?
84
+ * @param {boolean} [options.invert] - Invert test filter matches?
85
+ * @param {boolean} [options.noHighlighting] - Disable syntax highlighting?
86
+ * @param {string} [options.reporter] - Reporter name.
87
+ * @param {Object} [options.reporterOption] - Reporter settings object.
88
+ * @param {number} [options.retries] - Number of times to retry failed tests.
89
+ * @param {number} [options.slow] - Slow threshold value.
90
+ * @param {number|string} [options.timeout] - Timeout threshold value.
91
+ * @param {string} [options.ui] - Interface name.
92
+ * @param {boolean} [options.color] - Color TTY output from reporter?
93
+ * @param {boolean} [options.useInlineDiffs] - Use inline diffs?
94
+ */
95
+ function Mocha(options) {
96
+ options = utils.assign({}, mocharc, options || {});
97
+ this.files = [];
98
+ this.options = options;
99
+ // root suite
100
+ this.suite = new exports.Suite('', new exports.Context(), true);
101
+
102
+ if ('useColors' in options) {
103
+ utils.deprecate(
104
+ 'useColors is DEPRECATED and will be removed from a future version of Mocha. Instead, use the "color" option'
105
+ );
106
+ options.color = 'color' in options ? options.color : options.useColors;
107
+ }
108
+
109
+ this.grep(options.grep)
110
+ .fgrep(options.fgrep)
111
+ .ui(options.ui)
112
+ .bail(options.bail)
113
+ .reporter(options.reporter, options.reporterOptions)
114
+ .useColors(options.color)
115
+ .slow(options.slow)
116
+ .useInlineDiffs(options.inlineDiffs)
117
+ .globals(options.globals);
118
+
119
+ if ('enableTimeouts' in options) {
120
+ utils.deprecate(
121
+ 'enableTimeouts is DEPRECATED and will be removed from a future version of Mocha. Instead, use "timeout: false" to disable timeouts.'
122
+ );
123
+ if (options.enableTimeouts === false) {
124
+ this.timeout(0);
125
+ }
126
+ }
127
+
128
+ // this guard exists because Suite#timeout does not consider `undefined` to be valid input
129
+ if (typeof options.timeout !== 'undefined') {
130
+ this.timeout(options.timeout === false ? 0 : options.timeout);
131
+ }
132
+
133
+ if ('retries' in options) {
134
+ this.retries(options.retries);
135
+ }
136
+
137
+ if ('diff' in options) {
138
+ this.hideDiff(!options.diff);
139
+ }
140
+
141
+ [
142
+ 'allowUncaught',
143
+ 'asyncOnly',
144
+ 'checkLeaks',
145
+ 'delay',
146
+ 'forbidOnly',
147
+ 'forbidPending',
148
+ 'fullTrace',
149
+ 'growl',
150
+ 'invert'
151
+ ].forEach(function(opt) {
152
+ if (options[opt]) {
153
+ this[opt]();
154
+ }
155
+ }, this);
156
+ }
157
+
158
+ /**
159
+ * Enables or disables bailing on the first failure.
160
+ *
161
+ * @public
162
+ * @see {@link https://mochajs.org/#-b---bail|CLI option}
163
+ * @param {boolean} [bail=true] - Whether to bail on first error.
164
+ * @returns {Mocha} this
165
+ * @chainable
166
+ */
167
+ Mocha.prototype.bail = function(bail) {
168
+ if (!arguments.length) {
169
+ bail = true;
170
+ }
171
+ this.suite.bail(bail);
172
+ return this;
173
+ };
174
+
175
+ /**
176
+ * @summary
177
+ * Adds `file` to be loaded for execution.
178
+ *
179
+ * @description
180
+ * Useful for generic setup code that must be included within test suite.
181
+ *
182
+ * @public
183
+ * @see {@link https://mochajs.org/#--file-file|CLI option}
184
+ * @param {string} file - Pathname of file to be loaded.
185
+ * @returns {Mocha} this
186
+ * @chainable
187
+ */
188
+ Mocha.prototype.addFile = function(file) {
189
+ this.files.push(file);
190
+ return this;
191
+ };
192
+
193
+ /**
194
+ * Sets reporter to `reporter`, defaults to "spec".
195
+ *
196
+ * @public
197
+ * @see {@link https://mochajs.org/#-r---reporter-name|CLI option}
198
+ * @see {@link https://mochajs.org/#reporters|Reporters}
199
+ * @param {String|Function} reporter - Reporter name or constructor.
200
+ * @param {Object} [reporterOptions] - Options used to configure the reporter.
201
+ * @returns {Mocha} this
202
+ * @chainable
203
+ * @throws {Error} if requested reporter cannot be loaded
204
+ * @example
205
+ *
206
+ * // Use XUnit reporter and direct its output to file
207
+ * mocha.reporter('xunit', { output: '/path/to/testspec.xunit.xml' });
208
+ */
209
+ Mocha.prototype.reporter = function(reporter, reporterOptions) {
210
+ if (typeof reporter === 'function') {
211
+ this._reporter = reporter;
212
+ } else {
213
+ reporter = reporter || 'spec';
214
+ var _reporter;
215
+ // Try to load a built-in reporter.
216
+ if (builtinReporters[reporter]) {
217
+ _reporter = builtinReporters[reporter];
218
+ }
219
+ // Try to load reporters from process.cwd() and node_modules
220
+ if (!_reporter) {
221
+ try {
222
+ _reporter = require(reporter);
223
+ } catch (err) {
224
+ if (
225
+ err.code !== 'MODULE_NOT_FOUND' ||
226
+ err.message.indexOf('Cannot find module') !== -1
227
+ ) {
228
+ // Try to load reporters from a path (absolute or relative)
229
+ try {
230
+ _reporter = require(path.resolve(process.cwd(), reporter));
231
+ } catch (_err) {
232
+ _err.code !== 'MODULE_NOT_FOUND' ||
233
+ _err.message.indexOf('Cannot find module') !== -1
234
+ ? console.warn(sQuote(reporter) + ' reporter not found')
235
+ : console.warn(
236
+ sQuote(reporter) +
237
+ ' reporter blew up with error:\n' +
238
+ err.stack
239
+ );
240
+ }
241
+ } else {
242
+ console.warn(
243
+ sQuote(reporter) + ' reporter blew up with error:\n' + err.stack
244
+ );
245
+ }
246
+ }
247
+ }
248
+ if (!_reporter) {
249
+ throw createInvalidReporterError(
250
+ 'invalid reporter ' + sQuote(reporter),
251
+ reporter
252
+ );
253
+ }
254
+ this._reporter = _reporter;
255
+ }
256
+ this.options.reporterOptions = reporterOptions;
257
+ return this;
258
+ };
259
+
260
+ /**
261
+ * Sets test UI `name`, defaults to "bdd".
262
+ *
263
+ * @public
264
+ * @see {@link https://mochajs.org/#-u---ui-name|CLI option}
265
+ * @see {@link https://mochajs.org/#interfaces|Interface DSLs}
266
+ * @param {string|Function} [ui=bdd] - Interface name or class.
267
+ * @returns {Mocha} this
268
+ * @chainable
269
+ * @throws {Error} if requested interface cannot be loaded
270
+ */
271
+ Mocha.prototype.ui = function(ui) {
272
+ var bindInterface;
273
+ if (typeof ui === 'function') {
274
+ bindInterface = ui;
275
+ } else {
276
+ ui = ui || 'bdd';
277
+ bindInterface = exports.interfaces[ui];
278
+ if (!bindInterface) {
279
+ try {
280
+ bindInterface = require(ui);
281
+ } catch (err) {
282
+ throw createInvalidInterfaceError(
283
+ 'invalid interface ' + sQuote(ui),
284
+ ui
285
+ );
286
+ }
287
+ }
288
+ }
289
+ bindInterface(this.suite);
290
+
291
+ this.suite.on(EVENT_FILE_PRE_REQUIRE, function(context) {
292
+ exports.afterEach = context.afterEach || context.teardown;
293
+ exports.after = context.after || context.suiteTeardown;
294
+ exports.beforeEach = context.beforeEach || context.setup;
295
+ exports.before = context.before || context.suiteSetup;
296
+ exports.describe = context.describe || context.suite;
297
+ exports.it = context.it || context.test;
298
+ exports.xit = context.xit || (context.test && context.test.skip);
299
+ exports.setup = context.setup || context.beforeEach;
300
+ exports.suiteSetup = context.suiteSetup || context.before;
301
+ exports.suiteTeardown = context.suiteTeardown || context.after;
302
+ exports.suite = context.suite || context.describe;
303
+ exports.teardown = context.teardown || context.afterEach;
304
+ exports.test = context.test || context.it;
305
+ exports.run = context.run;
306
+ });
307
+
308
+ return this;
309
+ };
310
+
311
+ /**
312
+ * Loads `files` prior to execution.
313
+ *
314
+ * @description
315
+ * The implementation relies on Node's `require` to execute
316
+ * the test interface functions and will be subject to its cache.
317
+ *
318
+ * @private
319
+ * @see {@link Mocha#addFile}
320
+ * @see {@link Mocha#run}
321
+ * @see {@link Mocha#unloadFiles}
322
+ * @param {Function} [fn] - Callback invoked upon completion.
323
+ */
324
+ Mocha.prototype.loadFiles = function(fn) {
325
+ var self = this;
326
+ var suite = this.suite;
327
+ this.files.forEach(function(file) {
328
+ file = path.resolve(file);
329
+ suite.emit(EVENT_FILE_PRE_REQUIRE, global, file, self);
330
+ suite.emit(EVENT_FILE_REQUIRE, require(file), file, self);
331
+ suite.emit(EVENT_FILE_POST_REQUIRE, global, file, self);
332
+ });
333
+ fn && fn();
334
+ };
335
+
336
+ /**
337
+ * Removes a previously loaded file from Node's `require` cache.
338
+ *
339
+ * @private
340
+ * @static
341
+ * @see {@link Mocha#unloadFiles}
342
+ * @param {string} file - Pathname of file to be unloaded.
343
+ */
344
+ Mocha.unloadFile = function(file) {
345
+ delete require.cache[require.resolve(file)];
346
+ };
347
+
348
+ /**
349
+ * Unloads `files` from Node's `require` cache.
350
+ *
351
+ * @description
352
+ * This allows files to be "freshly" reloaded, providing the ability
353
+ * to reuse a Mocha instance programmatically.
354
+ *
355
+ * <strong>Intended for consumers &mdash; not used internally</strong>
356
+ *
357
+ * @public
358
+ * @see {@link Mocha.unloadFile}
359
+ * @see {@link Mocha#loadFiles}
360
+ * @see {@link Mocha#run}
361
+ * @returns {Mocha} this
362
+ * @chainable
363
+ */
364
+ Mocha.prototype.unloadFiles = function() {
365
+ this.files.forEach(Mocha.unloadFile);
366
+ return this;
367
+ };
368
+
369
+ /**
370
+ * Sets `grep` filter after escaping RegExp special characters.
371
+ *
372
+ * @public
373
+ * @see {@link Mocha#grep}
374
+ * @param {string} str - Value to be converted to a regexp.
375
+ * @returns {Mocha} this
376
+ * @chainable
377
+ * @example
378
+ *
379
+ * // Select tests whose full title begins with `"foo"` followed by a period
380
+ * mocha.fgrep('foo.');
381
+ */
382
+ Mocha.prototype.fgrep = function(str) {
383
+ if (!str) {
384
+ return this;
385
+ }
386
+ return this.grep(new RegExp(escapeRe(str)));
387
+ };
388
+
389
+ /**
390
+ * @summary
391
+ * Sets `grep` filter used to select specific tests for execution.
392
+ *
393
+ * @description
394
+ * If `re` is a regexp-like string, it will be converted to regexp.
395
+ * The regexp is tested against the full title of each test (i.e., the
396
+ * name of the test preceded by titles of each its ancestral suites).
397
+ * As such, using an <em>exact-match</em> fixed pattern against the
398
+ * test name itself will not yield any matches.
399
+ * <br>
400
+ * <strong>Previous filter value will be overwritten on each call!</strong>
401
+ *
402
+ * @public
403
+ * @see {@link https://mochajs.org/#-g---grep-pattern|CLI option}
404
+ * @see {@link Mocha#fgrep}
405
+ * @see {@link Mocha#invert}
406
+ * @param {RegExp|String} re - Regular expression used to select tests.
407
+ * @return {Mocha} this
408
+ * @chainable
409
+ * @example
410
+ *
411
+ * // Select tests whose full title contains `"match"`, ignoring case
412
+ * mocha.grep(/match/i);
413
+ * @example
414
+ *
415
+ * // Same as above but with regexp-like string argument
416
+ * mocha.grep('/match/i');
417
+ * @example
418
+ *
419
+ * // ## Anti-example
420
+ * // Given embedded test `it('only-this-test')`...
421
+ * mocha.grep('/^only-this-test$/'); // NO! Use `.only()` to do this!
422
+ */
423
+ Mocha.prototype.grep = function(re) {
424
+ if (utils.isString(re)) {
425
+ // extract args if it's regex-like, i.e: [string, pattern, flag]
426
+ var arg = re.match(/^\/(.*)\/(g|i|)$|.*/);
427
+ this.options.grep = new RegExp(arg[1] || arg[0], arg[2]);
428
+ } else {
429
+ this.options.grep = re;
430
+ }
431
+ return this;
432
+ };
433
+
434
+ /**
435
+ * Inverts `grep` matches.
436
+ *
437
+ * @public
438
+ * @see {@link Mocha#grep}
439
+ * @return {Mocha} this
440
+ * @chainable
441
+ * @example
442
+ *
443
+ * // Select tests whose full title does *not* contain `"match"`, ignoring case
444
+ * mocha.grep(/match/i).invert();
445
+ */
446
+ Mocha.prototype.invert = function() {
447
+ this.options.invert = true;
448
+ return this;
449
+ };
450
+
451
+ /**
452
+ * Enables or disables ignoring global leaks.
453
+ *
454
+ * @public
455
+ * @see {@link Mocha#checkLeaks}
456
+ * @param {boolean} ignoreLeaks - Whether to ignore global leaks.
457
+ * @return {Mocha} this
458
+ * @chainable
459
+ * @example
460
+ *
461
+ * // Ignore global leaks
462
+ * mocha.ignoreLeaks(true);
463
+ */
464
+ Mocha.prototype.ignoreLeaks = function(ignoreLeaks) {
465
+ this.options.ignoreLeaks = Boolean(ignoreLeaks);
466
+ return this;
467
+ };
468
+
469
+ /**
470
+ * Enables checking for global variables leaked while running tests.
471
+ *
472
+ * @public
473
+ * @see {@link https://mochajs.org/#--check-leaks|CLI option}
474
+ * @see {@link Mocha#ignoreLeaks}
475
+ * @return {Mocha} this
476
+ * @chainable
477
+ */
478
+ Mocha.prototype.checkLeaks = function() {
479
+ this.options.ignoreLeaks = false;
480
+ return this;
481
+ };
482
+
483
+ /**
484
+ * Displays full stack trace upon test failure.
485
+ *
486
+ * @public
487
+ * @return {Mocha} this
488
+ * @chainable
489
+ */
490
+ Mocha.prototype.fullTrace = function() {
491
+ this.options.fullStackTrace = true;
492
+ return this;
493
+ };
494
+
495
+ /**
496
+ * Enables desktop notification support if prerequisite software installed.
497
+ *
498
+ * @public
499
+ * @see {@link Mocha#isGrowlCapable}
500
+ * @see {@link Mocha#_growl}
501
+ * @return {Mocha} this
502
+ * @chainable
503
+ */
504
+ Mocha.prototype.growl = function() {
505
+ this.options.growl = this.isGrowlCapable();
506
+ if (!this.options.growl) {
507
+ var detail = process.browser
508
+ ? 'notification support not available in this browser...'
509
+ : 'notification support prerequisites not installed...';
510
+ console.error(detail + ' cannot enable!');
511
+ }
512
+ return this;
513
+ };
514
+
515
+ /**
516
+ * @summary
517
+ * Determines if Growl support seems likely.
518
+ *
519
+ * @description
520
+ * <strong>Not available when run in browser.</strong>
521
+ *
522
+ * @private
523
+ * @see {@link Growl#isCapable}
524
+ * @see {@link Mocha#growl}
525
+ * @return {boolean} whether Growl support can be expected
526
+ */
527
+ Mocha.prototype.isGrowlCapable = growl.isCapable;
528
+
529
+ /**
530
+ * Implements desktop notifications using a pseudo-reporter.
531
+ *
532
+ * @private
533
+ * @see {@link Mocha#growl}
534
+ * @see {@link Growl#notify}
535
+ * @param {Runner} runner - Runner instance.
536
+ */
537
+ Mocha.prototype._growl = growl.notify;
538
+
539
+ /**
540
+ * Specifies whitelist of variable names to be expected in global scope.
541
+ *
542
+ * @public
543
+ * @see {@link https://mochajs.org/#--globals-names|CLI option}
544
+ * @see {@link Mocha#checkLeaks}
545
+ * @param {String[]|String} globals - Accepted global variable name(s).
546
+ * @return {Mocha} this
547
+ * @chainable
548
+ * @example
549
+ *
550
+ * // Specify variables to be expected in global scope
551
+ * mocha.globals(['jQuery', 'MyLib']);
552
+ */
553
+ Mocha.prototype.globals = function(globals) {
554
+ this.options.globals = (this.options.globals || [])
555
+ .concat(globals)
556
+ .filter(Boolean);
557
+ return this;
558
+ };
559
+
560
+ /**
561
+ * Enables or disables TTY color output by screen-oriented reporters.
562
+ *
563
+ * @public
564
+ * @param {boolean} colors - Whether to enable color output.
565
+ * @return {Mocha} this
566
+ * @chainable
567
+ */
568
+ Mocha.prototype.useColors = function(colors) {
569
+ if (colors !== undefined) {
570
+ this.options.useColors = colors;
571
+ }
572
+ return this;
573
+ };
574
+
575
+ /**
576
+ * Determines if reporter should use inline diffs (rather than +/-)
577
+ * in test failure output.
578
+ *
579
+ * @public
580
+ * @param {boolean} inlineDiffs - Whether to use inline diffs.
581
+ * @return {Mocha} this
582
+ * @chainable
583
+ */
584
+ Mocha.prototype.useInlineDiffs = function(inlineDiffs) {
585
+ this.options.useInlineDiffs = inlineDiffs !== undefined && inlineDiffs;
586
+ return this;
587
+ };
588
+
589
+ /**
590
+ * Determines if reporter should include diffs in test failure output.
591
+ *
592
+ * @public
593
+ * @param {boolean} hideDiff - Whether to hide diffs.
594
+ * @return {Mocha} this
595
+ * @chainable
596
+ */
597
+ Mocha.prototype.hideDiff = function(hideDiff) {
598
+ this.options.hideDiff = hideDiff !== undefined && hideDiff;
599
+ return this;
600
+ };
601
+
602
+ /**
603
+ * @summary
604
+ * Sets timeout threshold value.
605
+ *
606
+ * @description
607
+ * A string argument can use shorthand (such as "2s") and will be converted.
608
+ * If the value is `0`, timeouts will be disabled.
609
+ *
610
+ * @public
611
+ * @see {@link https://mochajs.org/#-t---timeout-ms|CLI option}
612
+ * @see {@link https://mochajs.org/#--no-timeouts|CLI option}
613
+ * @see {@link https://mochajs.org/#timeouts|Timeouts}
614
+ * @see {@link Mocha#enableTimeouts}
615
+ * @param {number|string} msecs - Timeout threshold value.
616
+ * @return {Mocha} this
617
+ * @chainable
618
+ * @example
619
+ *
620
+ * // Sets timeout to one second
621
+ * mocha.timeout(1000);
622
+ * @example
623
+ *
624
+ * // Same as above but using string argument
625
+ * mocha.timeout('1s');
626
+ */
627
+ Mocha.prototype.timeout = function(msecs) {
628
+ this.suite.timeout(msecs);
629
+ return this;
630
+ };
631
+
632
+ /**
633
+ * Sets the number of times to retry failed tests.
634
+ *
635
+ * @public
636
+ * @see {@link https://mochajs.org/#retry-tests|Retry Tests}
637
+ * @param {number} retry - Number of times to retry failed tests.
638
+ * @return {Mocha} this
639
+ * @chainable
640
+ * @example
641
+ *
642
+ * // Allow any failed test to retry one more time
643
+ * mocha.retries(1);
644
+ */
645
+ Mocha.prototype.retries = function(n) {
646
+ this.suite.retries(n);
647
+ return this;
648
+ };
649
+
650
+ /**
651
+ * Sets slowness threshold value.
652
+ *
653
+ * @public
654
+ * @see {@link https://mochajs.org/#-s---slow-ms|CLI option}
655
+ * @param {number} msecs - Slowness threshold value.
656
+ * @return {Mocha} this
657
+ * @chainable
658
+ * @example
659
+ *
660
+ * // Sets "slow" threshold to half a second
661
+ * mocha.slow(500);
662
+ * @example
663
+ *
664
+ * // Same as above but using string argument
665
+ * mocha.slow('0.5s');
666
+ */
667
+ Mocha.prototype.slow = function(msecs) {
668
+ this.suite.slow(msecs);
669
+ return this;
670
+ };
671
+
672
+ /**
673
+ * Enables or disables timeouts.
674
+ *
675
+ * @public
676
+ * @see {@link https://mochajs.org/#-t---timeout-ms|CLI option}
677
+ * @see {@link https://mochajs.org/#--no-timeouts|CLI option}
678
+ * @param {boolean} enableTimeouts - Whether to enable timeouts.
679
+ * @return {Mocha} this
680
+ * @chainable
681
+ */
682
+ Mocha.prototype.enableTimeouts = function(enableTimeouts) {
683
+ this.suite.enableTimeouts(
684
+ arguments.length && enableTimeouts !== undefined ? enableTimeouts : true
685
+ );
686
+ return this;
687
+ };
688
+
689
+ /**
690
+ * Forces all tests to either accept a `done` callback or return a promise.
691
+ *
692
+ * @public
693
+ * @return {Mocha} this
694
+ * @chainable
695
+ */
696
+ Mocha.prototype.asyncOnly = function() {
697
+ this.options.asyncOnly = true;
698
+ return this;
699
+ };
700
+
701
+ /**
702
+ * Disables syntax highlighting (in browser).
703
+ *
704
+ * @public
705
+ * @return {Mocha} this
706
+ * @chainable
707
+ */
708
+ Mocha.prototype.noHighlighting = function() {
709
+ this.options.noHighlighting = true;
710
+ return this;
711
+ };
712
+
713
+ /**
714
+ * Enables uncaught errors to propagate (in browser).
715
+ *
716
+ * @public
717
+ * @return {Mocha} this
718
+ * @chainable
719
+ */
720
+ Mocha.prototype.allowUncaught = function() {
721
+ this.options.allowUncaught = true;
722
+ return this;
723
+ };
724
+
725
+ /**
726
+ * @summary
727
+ * Delays root suite execution.
728
+ *
729
+ * @description
730
+ * Used to perform asynch operations before any suites are run.
731
+ *
732
+ * @public
733
+ * @see {@link https://mochajs.org/#delayed-root-suite|delayed root suite}
734
+ * @returns {Mocha} this
735
+ * @chainable
736
+ */
737
+ Mocha.prototype.delay = function delay() {
738
+ this.options.delay = true;
739
+ return this;
740
+ };
741
+
742
+ /**
743
+ * Causes tests marked `only` to fail the suite.
744
+ *
745
+ * @public
746
+ * @returns {Mocha} this
747
+ * @chainable
748
+ */
749
+ Mocha.prototype.forbidOnly = function() {
750
+ this.options.forbidOnly = true;
751
+ return this;
752
+ };
753
+
754
+ /**
755
+ * Causes pending tests and tests marked `skip` to fail the suite.
756
+ *
757
+ * @public
758
+ * @returns {Mocha} this
759
+ * @chainable
760
+ */
761
+ Mocha.prototype.forbidPending = function() {
762
+ this.options.forbidPending = true;
763
+ return this;
764
+ };
765
+
766
+ /**
767
+ * Mocha version as specified by "package.json".
768
+ *
769
+ * @name Mocha#version
770
+ * @type string
771
+ * @readonly
772
+ */
773
+ Object.defineProperty(Mocha.prototype, 'version', {
774
+ value: require('../package.json').version,
775
+ configurable: false,
776
+ enumerable: true,
777
+ writable: false
778
+ });
779
+
780
+ /**
781
+ * Callback to be invoked when test execution is complete.
782
+ *
783
+ * @callback DoneCB
784
+ * @param {number} failures - Number of failures that occurred.
785
+ */
786
+
787
+ /**
788
+ * Runs root suite and invokes `fn()` when complete.
789
+ *
790
+ * @description
791
+ * To run tests multiple times (or to run tests in files that are
792
+ * already in the `require` cache), make sure to clear them from
793
+ * the cache first!
794
+ *
795
+ * @public
796
+ * @see {@link Mocha#loadFiles}
797
+ * @see {@link Mocha#unloadFiles}
798
+ * @see {@link Runner#run}
799
+ * @param {DoneCB} [fn] - Callback invoked when test execution completed.
800
+ * @return {Runner} runner instance
801
+ */
802
+ Mocha.prototype.run = function(fn) {
803
+ if (this.files.length) {
804
+ this.loadFiles();
805
+ }
806
+ var suite = this.suite;
807
+ var options = this.options;
808
+ options.files = this.files;
809
+ var runner = new exports.Runner(suite, options.delay);
810
+ createStatsCollector(runner);
811
+ var reporter = new this._reporter(runner, options);
812
+ runner.ignoreLeaks = options.ignoreLeaks !== false;
813
+ runner.fullStackTrace = options.fullStackTrace;
814
+ runner.asyncOnly = options.asyncOnly;
815
+ runner.allowUncaught = options.allowUncaught;
816
+ runner.forbidOnly = options.forbidOnly;
817
+ runner.forbidPending = options.forbidPending;
818
+ if (options.grep) {
819
+ runner.grep(options.grep, options.invert);
820
+ }
821
+ if (options.globals) {
822
+ runner.globals(options.globals);
823
+ }
824
+ if (options.growl) {
825
+ this._growl(runner);
826
+ }
827
+ if (options.useColors !== undefined) {
828
+ exports.reporters.Base.useColors = options.useColors;
829
+ }
830
+ exports.reporters.Base.inlineDiffs = options.useInlineDiffs;
831
+ exports.reporters.Base.hideDiff = options.hideDiff;
832
+
833
+ function done(failures) {
834
+ fn = fn || utils.noop;
835
+ if (reporter.done) {
836
+ reporter.done(failures, fn);
837
+ } else {
838
+ fn(failures);
839
+ }
840
+ }
841
+
842
+ return runner.run(done);
843
+ };