mocha.js 22 KB

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