Dieses Repository beinhaltet HTML- und Javascript Code zur einer NotizenWebApp auf Basis von Web Storage. Zudem sind Mocha/Chai Tests im Browser enthalten. https://meinenotizen.netlify.app/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

mocha.js 30KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098
  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 esmUtils = utils.supportsEsModules() ? require('./esm-utils') : undefined;
  16. var createStatsCollector = require('./stats-collector');
  17. var createInvalidReporterError = errors.createInvalidReporterError;
  18. var createInvalidInterfaceError = errors.createInvalidInterfaceError;
  19. var createMochaInstanceAlreadyDisposedError =
  20. errors.createMochaInstanceAlreadyDisposedError;
  21. var createMochaInstanceAlreadyRunningError =
  22. errors.createMochaInstanceAlreadyRunningError;
  23. var EVENT_FILE_PRE_REQUIRE = Suite.constants.EVENT_FILE_PRE_REQUIRE;
  24. var EVENT_FILE_POST_REQUIRE = Suite.constants.EVENT_FILE_POST_REQUIRE;
  25. var EVENT_FILE_REQUIRE = Suite.constants.EVENT_FILE_REQUIRE;
  26. var sQuote = utils.sQuote;
  27. exports = module.exports = Mocha;
  28. /**
  29. * A Mocha instance is a finite state machine.
  30. * These are the states it can be in.
  31. */
  32. var mochaStates = utils.defineConstants({
  33. /**
  34. * Initial state of the mocha instance
  35. */
  36. INIT: 'init',
  37. /**
  38. * Mocha instance is running tests
  39. */
  40. RUNNING: 'running',
  41. /**
  42. * Mocha instance is done running tests and references to test functions and hooks are cleaned.
  43. * You can reset this state by unloading the test files.
  44. */
  45. REFERENCES_CLEANED: 'referencesCleaned',
  46. /**
  47. * Mocha instance is disposed and can no longer be used.
  48. */
  49. DISPOSED: 'disposed'
  50. });
  51. /**
  52. * To require local UIs and reporters when running in node.
  53. */
  54. if (!process.browser && typeof module.paths !== 'undefined') {
  55. var cwd = utils.cwd();
  56. module.paths.push(cwd, path.join(cwd, 'node_modules'));
  57. }
  58. /**
  59. * Expose internals.
  60. */
  61. /**
  62. * @public
  63. * @class utils
  64. * @memberof Mocha
  65. */
  66. exports.utils = utils;
  67. exports.interfaces = require('./interfaces');
  68. /**
  69. * @public
  70. * @memberof Mocha
  71. */
  72. exports.reporters = builtinReporters;
  73. exports.Runnable = require('./runnable');
  74. exports.Context = require('./context');
  75. /**
  76. *
  77. * @memberof Mocha
  78. */
  79. exports.Runner = require('./runner');
  80. exports.Suite = Suite;
  81. exports.Hook = require('./hook');
  82. exports.Test = require('./test');
  83. /**
  84. * Constructs a new Mocha instance with `options`.
  85. *
  86. * @public
  87. * @class Mocha
  88. * @param {Object} [options] - Settings object.
  89. * @param {boolean} [options.allowUncaught] - Propagate uncaught errors?
  90. * @param {boolean} [options.asyncOnly] - Force `done` callback or promise?
  91. * @param {boolean} [options.bail] - Bail after first test failure?
  92. * @param {boolean} [options.checkLeaks] - Check for global variable leaks?
  93. * @param {boolean} [options.color] - Color TTY output from reporter?
  94. * @param {boolean} [options.delay] - Delay root suite execution?
  95. * @param {boolean} [options.diff] - Show diff on failure?
  96. * @param {string} [options.fgrep] - Test filter given string.
  97. * @param {boolean} [options.forbidOnly] - Tests marked `only` fail the suite?
  98. * @param {boolean} [options.forbidPending] - Pending tests fail the suite?
  99. * @param {boolean} [options.fullTrace] - Full stacktrace upon failure?
  100. * @param {string[]} [options.global] - Variables expected in global scope.
  101. * @param {RegExp|string} [options.grep] - Test filter given regular expression.
  102. * @param {boolean} [options.growl] - Enable desktop notifications?
  103. * @param {boolean} [options.inlineDiffs] - Display inline diffs?
  104. * @param {boolean} [options.invert] - Invert test filter matches?
  105. * @param {boolean} [options.noHighlighting] - Disable syntax highlighting?
  106. * @param {string|constructor} [options.reporter] - Reporter name or constructor.
  107. * @param {Object} [options.reporterOption] - Reporter settings object.
  108. * @param {number} [options.retries] - Number of times to retry failed tests.
  109. * @param {number} [options.slow] - Slow threshold value.
  110. * @param {number|string} [options.timeout] - Timeout threshold value.
  111. * @param {string} [options.ui] - Interface name.
  112. * @param {MochaRootHookObject} [options.rootHooks] - Hooks to bootstrap the root
  113. * suite with
  114. */
  115. function Mocha(options) {
  116. options = utils.assign({}, mocharc, options || {});
  117. this.files = [];
  118. this.options = options;
  119. // root suite
  120. this.suite = new exports.Suite('', new exports.Context(), true);
  121. this._cleanReferencesAfterRun = true;
  122. this.grep(options.grep)
  123. .fgrep(options.fgrep)
  124. .ui(options.ui)
  125. .reporter(
  126. options.reporter,
  127. options.reporterOption || options.reporterOptions // reporterOptions was previously the only way to specify options to reporter
  128. )
  129. .slow(options.slow)
  130. .global(options.global);
  131. // this guard exists because Suite#timeout does not consider `undefined` to be valid input
  132. if (typeof options.timeout !== 'undefined') {
  133. this.timeout(options.timeout === false ? 0 : options.timeout);
  134. }
  135. if ('retries' in options) {
  136. this.retries(options.retries);
  137. }
  138. [
  139. 'allowUncaught',
  140. 'asyncOnly',
  141. 'bail',
  142. 'checkLeaks',
  143. 'color',
  144. 'delay',
  145. 'diff',
  146. 'forbidOnly',
  147. 'forbidPending',
  148. 'fullTrace',
  149. 'growl',
  150. 'inlineDiffs',
  151. 'invert'
  152. ].forEach(function(opt) {
  153. if (options[opt]) {
  154. this[opt]();
  155. }
  156. }, this);
  157. if (options.rootHooks) {
  158. this.rootHooks(options.rootHooks);
  159. }
  160. }
  161. /**
  162. * Enables or disables bailing on the first failure.
  163. *
  164. * @public
  165. * @see [CLI option](../#-bail-b)
  166. * @param {boolean} [bail=true] - Whether to bail on first error.
  167. * @returns {Mocha} this
  168. * @chainable
  169. */
  170. Mocha.prototype.bail = function(bail) {
  171. this.suite.bail(bail !== false);
  172. return this;
  173. };
  174. /**
  175. * @summary
  176. * Adds `file` to be loaded for execution.
  177. *
  178. * @description
  179. * Useful for generic setup code that must be included within test suite.
  180. *
  181. * @public
  182. * @see [CLI option](../#-file-filedirectoryglob)
  183. * @param {string} file - Pathname of file to be loaded.
  184. * @returns {Mocha} this
  185. * @chainable
  186. */
  187. Mocha.prototype.addFile = function(file) {
  188. this.files.push(file);
  189. return this;
  190. };
  191. /**
  192. * Sets reporter to `reporter`, defaults to "spec".
  193. *
  194. * @public
  195. * @see [CLI option](../#-reporter-name-r-name)
  196. * @see [Reporters](../#reporters)
  197. * @param {String|Function} reporter - Reporter name or constructor.
  198. * @param {Object} [reporterOptions] - Options used to configure the reporter.
  199. * @returns {Mocha} this
  200. * @chainable
  201. * @throws {Error} if requested reporter cannot be loaded
  202. * @example
  203. *
  204. * // Use XUnit reporter and direct its output to file
  205. * mocha.reporter('xunit', { output: '/path/to/testspec.xunit.xml' });
  206. */
  207. Mocha.prototype.reporter = function(reporter, reporterOptions) {
  208. if (typeof reporter === 'function') {
  209. this._reporter = reporter;
  210. } else {
  211. reporter = reporter || 'spec';
  212. var _reporter;
  213. // Try to load a built-in reporter.
  214. if (builtinReporters[reporter]) {
  215. _reporter = builtinReporters[reporter];
  216. }
  217. // Try to load reporters from process.cwd() and node_modules
  218. if (!_reporter) {
  219. try {
  220. _reporter = require(reporter);
  221. } catch (err) {
  222. if (
  223. err.code === 'MODULE_NOT_FOUND' ||
  224. err.message.indexOf('Cannot find module') >= 0
  225. ) {
  226. // Try to load reporters from a path (absolute or relative)
  227. try {
  228. _reporter = require(path.resolve(utils.cwd(), reporter));
  229. } catch (_err) {
  230. _err.code === 'MODULE_NOT_FOUND' ||
  231. _err.message.indexOf('Cannot find module') >= 0
  232. ? utils.warn(sQuote(reporter) + ' reporter not found')
  233. : utils.warn(
  234. sQuote(reporter) +
  235. ' reporter blew up with error:\n' +
  236. err.stack
  237. );
  238. }
  239. } else {
  240. utils.warn(
  241. sQuote(reporter) + ' reporter blew up with error:\n' + err.stack
  242. );
  243. }
  244. }
  245. }
  246. if (!_reporter) {
  247. throw createInvalidReporterError(
  248. 'invalid reporter ' + sQuote(reporter),
  249. reporter
  250. );
  251. }
  252. this._reporter = _reporter;
  253. }
  254. this.options.reporterOption = reporterOptions;
  255. // alias option name is used in public reporters xunit/tap/progress
  256. this.options.reporterOptions = reporterOptions;
  257. return this;
  258. };
  259. /**
  260. * Sets test UI `name`, defaults to "bdd".
  261. *
  262. * @public
  263. * @see [CLI option](../#-ui-name-u-name)
  264. * @see [Interface DSLs](../#interfaces)
  265. * @param {string|Function} [ui=bdd] - Interface name or class.
  266. * @returns {Mocha} this
  267. * @chainable
  268. * @throws {Error} if requested interface cannot be loaded
  269. */
  270. Mocha.prototype.ui = function(ui) {
  271. var bindInterface;
  272. if (typeof ui === 'function') {
  273. bindInterface = ui;
  274. } else {
  275. ui = ui || 'bdd';
  276. bindInterface = exports.interfaces[ui];
  277. if (!bindInterface) {
  278. try {
  279. bindInterface = require(ui);
  280. } catch (err) {
  281. throw createInvalidInterfaceError(
  282. 'invalid interface ' + sQuote(ui),
  283. ui
  284. );
  285. }
  286. }
  287. }
  288. bindInterface(this.suite);
  289. this.suite.on(EVENT_FILE_PRE_REQUIRE, function(context) {
  290. exports.afterEach = context.afterEach || context.teardown;
  291. exports.after = context.after || context.suiteTeardown;
  292. exports.beforeEach = context.beforeEach || context.setup;
  293. exports.before = context.before || context.suiteSetup;
  294. exports.describe = context.describe || context.suite;
  295. exports.it = context.it || context.test;
  296. exports.xit = context.xit || (context.test && context.test.skip);
  297. exports.setup = context.setup || context.beforeEach;
  298. exports.suiteSetup = context.suiteSetup || context.before;
  299. exports.suiteTeardown = context.suiteTeardown || context.after;
  300. exports.suite = context.suite || context.describe;
  301. exports.teardown = context.teardown || context.afterEach;
  302. exports.test = context.test || context.it;
  303. exports.run = context.run;
  304. });
  305. return this;
  306. };
  307. /**
  308. * Loads `files` prior to execution. Does not support ES Modules.
  309. *
  310. * @description
  311. * The implementation relies on Node's `require` to execute
  312. * the test interface functions and will be subject to its cache.
  313. * Supports only CommonJS modules. To load ES modules, use Mocha#loadFilesAsync.
  314. *
  315. * @private
  316. * @see {@link Mocha#addFile}
  317. * @see {@link Mocha#run}
  318. * @see {@link Mocha#unloadFiles}
  319. * @see {@link Mocha#loadFilesAsync}
  320. * @param {Function} [fn] - Callback invoked upon completion.
  321. */
  322. Mocha.prototype.loadFiles = function(fn) {
  323. var self = this;
  324. var suite = this.suite;
  325. this.files.forEach(function(file) {
  326. file = path.resolve(file);
  327. suite.emit(EVENT_FILE_PRE_REQUIRE, global, file, self);
  328. suite.emit(EVENT_FILE_REQUIRE, require(file), file, self);
  329. suite.emit(EVENT_FILE_POST_REQUIRE, global, file, self);
  330. });
  331. fn && fn();
  332. };
  333. /**
  334. * Loads `files` prior to execution. Supports Node ES Modules.
  335. *
  336. * @description
  337. * The implementation relies on Node's `require` and `import` to execute
  338. * the test interface functions and will be subject to its cache.
  339. * Supports both CJS and ESM modules.
  340. *
  341. * @public
  342. * @see {@link Mocha#addFile}
  343. * @see {@link Mocha#run}
  344. * @see {@link Mocha#unloadFiles}
  345. * @returns {Promise}
  346. * @example
  347. *
  348. * // loads ESM (and CJS) test files asynchronously, then runs root suite
  349. * mocha.loadFilesAsync()
  350. * .then(() => mocha.run(failures => process.exitCode = failures ? 1 : 0))
  351. * .catch(() => process.exitCode = 1);
  352. */
  353. Mocha.prototype.loadFilesAsync = function() {
  354. var self = this;
  355. var suite = this.suite;
  356. this.loadAsync = true;
  357. if (!esmUtils) {
  358. return new Promise(function(resolve) {
  359. self.loadFiles(resolve);
  360. });
  361. }
  362. return esmUtils.loadFilesAsync(
  363. this.files,
  364. function(file) {
  365. suite.emit(EVENT_FILE_PRE_REQUIRE, global, file, self);
  366. },
  367. function(file, resultModule) {
  368. suite.emit(EVENT_FILE_REQUIRE, resultModule, file, self);
  369. suite.emit(EVENT_FILE_POST_REQUIRE, global, file, self);
  370. }
  371. );
  372. };
  373. /**
  374. * Removes a previously loaded file from Node's `require` cache.
  375. *
  376. * @private
  377. * @static
  378. * @see {@link Mocha#unloadFiles}
  379. * @param {string} file - Pathname of file to be unloaded.
  380. */
  381. Mocha.unloadFile = function(file) {
  382. delete require.cache[require.resolve(file)];
  383. };
  384. /**
  385. * Unloads `files` from Node's `require` cache.
  386. *
  387. * @description
  388. * This allows required files to be "freshly" reloaded, providing the ability
  389. * to reuse a Mocha instance programmatically.
  390. * Note: does not clear ESM module files from the cache
  391. *
  392. * <strong>Intended for consumers &mdash; not used internally</strong>
  393. *
  394. * @public
  395. * @see {@link Mocha#run}
  396. * @returns {Mocha} this
  397. * @chainable
  398. */
  399. Mocha.prototype.unloadFiles = function() {
  400. if (this._state === mochaStates.DISPOSED) {
  401. throw createMochaInstanceAlreadyDisposedError(
  402. 'Mocha instance is already disposed, it cannot be used again.',
  403. this._cleanReferencesAfterRun,
  404. this
  405. );
  406. }
  407. this.files.forEach(function(file) {
  408. Mocha.unloadFile(file);
  409. });
  410. this._state = mochaStates.INIT;
  411. return this;
  412. };
  413. /**
  414. * Sets `grep` filter after escaping RegExp special characters.
  415. *
  416. * @public
  417. * @see {@link Mocha#grep}
  418. * @param {string} str - Value to be converted to a regexp.
  419. * @returns {Mocha} this
  420. * @chainable
  421. * @example
  422. *
  423. * // Select tests whose full title begins with `"foo"` followed by a period
  424. * mocha.fgrep('foo.');
  425. */
  426. Mocha.prototype.fgrep = function(str) {
  427. if (!str) {
  428. return this;
  429. }
  430. return this.grep(new RegExp(escapeRe(str)));
  431. };
  432. /**
  433. * @summary
  434. * Sets `grep` filter used to select specific tests for execution.
  435. *
  436. * @description
  437. * If `re` is a regexp-like string, it will be converted to regexp.
  438. * The regexp is tested against the full title of each test (i.e., the
  439. * name of the test preceded by titles of each its ancestral suites).
  440. * As such, using an <em>exact-match</em> fixed pattern against the
  441. * test name itself will not yield any matches.
  442. * <br>
  443. * <strong>Previous filter value will be overwritten on each call!</strong>
  444. *
  445. * @public
  446. * @see [CLI option](../#-grep-regexp-g-regexp)
  447. * @see {@link Mocha#fgrep}
  448. * @see {@link Mocha#invert}
  449. * @param {RegExp|String} re - Regular expression used to select tests.
  450. * @return {Mocha} this
  451. * @chainable
  452. * @example
  453. *
  454. * // Select tests whose full title contains `"match"`, ignoring case
  455. * mocha.grep(/match/i);
  456. * @example
  457. *
  458. * // Same as above but with regexp-like string argument
  459. * mocha.grep('/match/i');
  460. * @example
  461. *
  462. * // ## Anti-example
  463. * // Given embedded test `it('only-this-test')`...
  464. * mocha.grep('/^only-this-test$/'); // NO! Use `.only()` to do this!
  465. */
  466. Mocha.prototype.grep = function(re) {
  467. if (utils.isString(re)) {
  468. // extract args if it's regex-like, i.e: [string, pattern, flag]
  469. var arg = re.match(/^\/(.*)\/(g|i|)$|.*/);
  470. this.options.grep = new RegExp(arg[1] || arg[0], arg[2]);
  471. } else {
  472. this.options.grep = re;
  473. }
  474. return this;
  475. };
  476. /**
  477. * Inverts `grep` matches.
  478. *
  479. * @public
  480. * @see {@link Mocha#grep}
  481. * @return {Mocha} this
  482. * @chainable
  483. * @example
  484. *
  485. * // Select tests whose full title does *not* contain `"match"`, ignoring case
  486. * mocha.grep(/match/i).invert();
  487. */
  488. Mocha.prototype.invert = function() {
  489. this.options.invert = true;
  490. return this;
  491. };
  492. /**
  493. * Enables or disables ignoring global leaks.
  494. *
  495. * @deprecated since v7.0.0
  496. * @public
  497. * @see {@link Mocha#checkLeaks}
  498. * @param {boolean} [ignoreLeaks=false] - Whether to ignore global leaks.
  499. * @return {Mocha} this
  500. * @chainable
  501. */
  502. Mocha.prototype.ignoreLeaks = function(ignoreLeaks) {
  503. utils.deprecate(
  504. '"ignoreLeaks()" is DEPRECATED, please use "checkLeaks()" instead.'
  505. );
  506. this.options.checkLeaks = !ignoreLeaks;
  507. return this;
  508. };
  509. /**
  510. * Enables or disables checking for global variables leaked while running tests.
  511. *
  512. * @public
  513. * @see [CLI option](../#-check-leaks)
  514. * @param {boolean} [checkLeaks=true] - Whether to check for global variable leaks.
  515. * @return {Mocha} this
  516. * @chainable
  517. */
  518. Mocha.prototype.checkLeaks = function(checkLeaks) {
  519. this.options.checkLeaks = checkLeaks !== false;
  520. return this;
  521. };
  522. /**
  523. * Enables or disables whether or not to dispose after each test run.
  524. * Disable this to ensure you can run the test suite multiple times.
  525. * If disabled, be sure to dispose mocha when you're done to prevent memory leaks.
  526. * @public
  527. * @see {@link Mocha#dispose}
  528. * @param {boolean} cleanReferencesAfterRun
  529. * @return {Mocha} this
  530. * @chainable
  531. */
  532. Mocha.prototype.cleanReferencesAfterRun = function(cleanReferencesAfterRun) {
  533. this._cleanReferencesAfterRun = cleanReferencesAfterRun !== false;
  534. return this;
  535. };
  536. /**
  537. * Manually dispose this mocha instance. Mark this instance as `disposed` and unable to run more tests.
  538. * It also removes function references to tests functions and hooks, so variables trapped in closures can be cleaned by the garbage collector.
  539. * @public
  540. */
  541. Mocha.prototype.dispose = function() {
  542. if (this._state === mochaStates.RUNNING) {
  543. throw createMochaInstanceAlreadyRunningError(
  544. 'Cannot dispose while the mocha instance is still running tests.'
  545. );
  546. }
  547. this.unloadFiles();
  548. this._previousRunner && this._previousRunner.dispose();
  549. this.suite.dispose();
  550. this._state = mochaStates.DISPOSED;
  551. };
  552. /**
  553. * Displays full stack trace upon test failure.
  554. *
  555. * @public
  556. * @see [CLI option](../#-full-trace)
  557. * @param {boolean} [fullTrace=true] - Whether to print full stacktrace upon failure.
  558. * @return {Mocha} this
  559. * @chainable
  560. */
  561. Mocha.prototype.fullTrace = function(fullTrace) {
  562. this.options.fullTrace = fullTrace !== false;
  563. return this;
  564. };
  565. /**
  566. * Enables desktop notification support if prerequisite software installed.
  567. *
  568. * @public
  569. * @see [CLI option](../#-growl-g)
  570. * @return {Mocha} this
  571. * @chainable
  572. */
  573. Mocha.prototype.growl = function() {
  574. this.options.growl = this.isGrowlCapable();
  575. if (!this.options.growl) {
  576. var detail = process.browser
  577. ? 'notification support not available in this browser...'
  578. : 'notification support prerequisites not installed...';
  579. console.error(detail + ' cannot enable!');
  580. }
  581. return this;
  582. };
  583. /**
  584. * @summary
  585. * Determines if Growl support seems likely.
  586. *
  587. * @description
  588. * <strong>Not available when run in browser.</strong>
  589. *
  590. * @private
  591. * @see {@link Growl#isCapable}
  592. * @see {@link Mocha#growl}
  593. * @return {boolean} whether Growl support can be expected
  594. */
  595. Mocha.prototype.isGrowlCapable = growl.isCapable;
  596. /**
  597. * Implements desktop notifications using a pseudo-reporter.
  598. *
  599. * @private
  600. * @see {@link Mocha#growl}
  601. * @see {@link Growl#notify}
  602. * @param {Runner} runner - Runner instance.
  603. */
  604. Mocha.prototype._growl = growl.notify;
  605. /**
  606. * Specifies whitelist of variable names to be expected in global scope.
  607. *
  608. * @public
  609. * @see [CLI option](../#-global-variable-name)
  610. * @see {@link Mocha#checkLeaks}
  611. * @param {String[]|String} global - Accepted global variable name(s).
  612. * @return {Mocha} this
  613. * @chainable
  614. * @example
  615. *
  616. * // Specify variables to be expected in global scope
  617. * mocha.global(['jQuery', 'MyLib']);
  618. */
  619. Mocha.prototype.global = function(global) {
  620. this.options.global = (this.options.global || [])
  621. .concat(global)
  622. .filter(Boolean)
  623. .filter(function(elt, idx, arr) {
  624. return arr.indexOf(elt) === idx;
  625. });
  626. return this;
  627. };
  628. // for backwards compability, 'globals' is an alias of 'global'
  629. Mocha.prototype.globals = Mocha.prototype.global;
  630. /**
  631. * Enables or disables TTY color output by screen-oriented reporters.
  632. *
  633. * @deprecated since v7.0.0
  634. * @public
  635. * @see {@link Mocha#color}
  636. * @param {boolean} colors - Whether to enable color output.
  637. * @return {Mocha} this
  638. * @chainable
  639. */
  640. Mocha.prototype.useColors = function(colors) {
  641. utils.deprecate('"useColors()" is DEPRECATED, please use "color()" instead.');
  642. if (colors !== undefined) {
  643. this.options.color = colors;
  644. }
  645. return this;
  646. };
  647. /**
  648. * Enables or disables TTY color output by screen-oriented reporters.
  649. *
  650. * @public
  651. * @see [CLI option](../#-color-c-colors)
  652. * @param {boolean} [color=true] - Whether to enable color output.
  653. * @return {Mocha} this
  654. * @chainable
  655. */
  656. Mocha.prototype.color = function(color) {
  657. this.options.color = color !== false;
  658. return this;
  659. };
  660. /**
  661. * Determines if reporter should use inline diffs (rather than +/-)
  662. * in test failure output.
  663. *
  664. * @deprecated since v7.0.0
  665. * @public
  666. * @see {@link Mocha#inlineDiffs}
  667. * @param {boolean} [inlineDiffs=false] - Whether to use inline diffs.
  668. * @return {Mocha} this
  669. * @chainable
  670. */
  671. Mocha.prototype.useInlineDiffs = function(inlineDiffs) {
  672. utils.deprecate(
  673. '"useInlineDiffs()" is DEPRECATED, please use "inlineDiffs()" instead.'
  674. );
  675. this.options.inlineDiffs = inlineDiffs !== undefined && inlineDiffs;
  676. return this;
  677. };
  678. /**
  679. * Enables or disables reporter to use inline diffs (rather than +/-)
  680. * in test failure output.
  681. *
  682. * @public
  683. * @see [CLI option](../#-inline-diffs)
  684. * @param {boolean} [inlineDiffs=true] - Whether to use inline diffs.
  685. * @return {Mocha} this
  686. * @chainable
  687. */
  688. Mocha.prototype.inlineDiffs = function(inlineDiffs) {
  689. this.options.inlineDiffs = inlineDiffs !== false;
  690. return this;
  691. };
  692. /**
  693. * Determines if reporter should include diffs in test failure output.
  694. *
  695. * @deprecated since v7.0.0
  696. * @public
  697. * @see {@link Mocha#diff}
  698. * @param {boolean} [hideDiff=false] - Whether to hide diffs.
  699. * @return {Mocha} this
  700. * @chainable
  701. */
  702. Mocha.prototype.hideDiff = function(hideDiff) {
  703. utils.deprecate('"hideDiff()" is DEPRECATED, please use "diff()" instead.');
  704. this.options.diff = !(hideDiff === true);
  705. return this;
  706. };
  707. /**
  708. * Enables or disables reporter to include diff in test failure output.
  709. *
  710. * @public
  711. * @see [CLI option](../#-diff)
  712. * @param {boolean} [diff=true] - Whether to show diff on failure.
  713. * @return {Mocha} this
  714. * @chainable
  715. */
  716. Mocha.prototype.diff = function(diff) {
  717. this.options.diff = diff !== false;
  718. return this;
  719. };
  720. /**
  721. * @summary
  722. * Sets timeout threshold value.
  723. *
  724. * @description
  725. * A string argument can use shorthand (such as "2s") and will be converted.
  726. * If the value is `0`, timeouts will be disabled.
  727. *
  728. * @public
  729. * @see [CLI option](../#-timeout-ms-t-ms)
  730. * @see [Timeouts](../#timeouts)
  731. * @see {@link Mocha#enableTimeouts}
  732. * @param {number|string} msecs - Timeout threshold value.
  733. * @return {Mocha} this
  734. * @chainable
  735. * @example
  736. *
  737. * // Sets timeout to one second
  738. * mocha.timeout(1000);
  739. * @example
  740. *
  741. * // Same as above but using string argument
  742. * mocha.timeout('1s');
  743. */
  744. Mocha.prototype.timeout = function(msecs) {
  745. this.suite.timeout(msecs);
  746. return this;
  747. };
  748. /**
  749. * Sets the number of times to retry failed tests.
  750. *
  751. * @public
  752. * @see [CLI option](../#-retries-n)
  753. * @see [Retry Tests](../#retry-tests)
  754. * @param {number} retry - Number of times to retry failed tests.
  755. * @return {Mocha} this
  756. * @chainable
  757. * @example
  758. *
  759. * // Allow any failed test to retry one more time
  760. * mocha.retries(1);
  761. */
  762. Mocha.prototype.retries = function(n) {
  763. this.suite.retries(n);
  764. return this;
  765. };
  766. /**
  767. * Sets slowness threshold value.
  768. *
  769. * @public
  770. * @see [CLI option](../#-slow-ms-s-ms)
  771. * @param {number} msecs - Slowness threshold value.
  772. * @return {Mocha} this
  773. * @chainable
  774. * @example
  775. *
  776. * // Sets "slow" threshold to half a second
  777. * mocha.slow(500);
  778. * @example
  779. *
  780. * // Same as above but using string argument
  781. * mocha.slow('0.5s');
  782. */
  783. Mocha.prototype.slow = function(msecs) {
  784. this.suite.slow(msecs);
  785. return this;
  786. };
  787. /**
  788. * Enables or disables timeouts.
  789. *
  790. * @public
  791. * @see [CLI option](../#-timeout-ms-t-ms)
  792. * @param {boolean} enableTimeouts - Whether to enable timeouts.
  793. * @return {Mocha} this
  794. * @chainable
  795. */
  796. Mocha.prototype.enableTimeouts = function(enableTimeouts) {
  797. this.suite.enableTimeouts(
  798. arguments.length && enableTimeouts !== undefined ? enableTimeouts : true
  799. );
  800. return this;
  801. };
  802. /**
  803. * Forces all tests to either accept a `done` callback or return a promise.
  804. *
  805. * @public
  806. * @see [CLI option](../#-async-only-a)
  807. * @param {boolean} [asyncOnly=true] - Wether to force `done` callback or promise.
  808. * @return {Mocha} this
  809. * @chainable
  810. */
  811. Mocha.prototype.asyncOnly = function(asyncOnly) {
  812. this.options.asyncOnly = asyncOnly !== false;
  813. return this;
  814. };
  815. /**
  816. * Disables syntax highlighting (in browser).
  817. *
  818. * @public
  819. * @return {Mocha} this
  820. * @chainable
  821. */
  822. Mocha.prototype.noHighlighting = function() {
  823. this.options.noHighlighting = true;
  824. return this;
  825. };
  826. /**
  827. * Enables or disables uncaught errors to propagate.
  828. *
  829. * @public
  830. * @see [CLI option](../#-allow-uncaught)
  831. * @param {boolean} [allowUncaught=true] - Whether to propagate uncaught errors.
  832. * @return {Mocha} this
  833. * @chainable
  834. */
  835. Mocha.prototype.allowUncaught = function(allowUncaught) {
  836. this.options.allowUncaught = allowUncaught !== false;
  837. return this;
  838. };
  839. /**
  840. * @summary
  841. * Delays root suite execution.
  842. *
  843. * @description
  844. * Used to perform asynch operations before any suites are run.
  845. *
  846. * @public
  847. * @see [delayed root suite](../#delayed-root-suite)
  848. * @returns {Mocha} this
  849. * @chainable
  850. */
  851. Mocha.prototype.delay = function delay() {
  852. this.options.delay = true;
  853. return this;
  854. };
  855. /**
  856. * Causes tests marked `only` to fail the suite.
  857. *
  858. * @public
  859. * @see [CLI option](../#-forbid-only)
  860. * @param {boolean} [forbidOnly=true] - Whether tests marked `only` fail the suite.
  861. * @returns {Mocha} this
  862. * @chainable
  863. */
  864. Mocha.prototype.forbidOnly = function(forbidOnly) {
  865. this.options.forbidOnly = forbidOnly !== false;
  866. return this;
  867. };
  868. /**
  869. * Causes pending tests and tests marked `skip` to fail the suite.
  870. *
  871. * @public
  872. * @see [CLI option](../#-forbid-pending)
  873. * @param {boolean} [forbidPending=true] - Whether pending tests fail the suite.
  874. * @returns {Mocha} this
  875. * @chainable
  876. */
  877. Mocha.prototype.forbidPending = function(forbidPending) {
  878. this.options.forbidPending = forbidPending !== false;
  879. return this;
  880. };
  881. /**
  882. * Throws an error if mocha is in the wrong state to be able to transition to a "running" state.
  883. */
  884. Mocha.prototype._guardRunningStateTransition = function() {
  885. if (this._state === mochaStates.RUNNING) {
  886. throw createMochaInstanceAlreadyRunningError(
  887. 'Mocha instance is currently running tests, cannot start a next test run until this one is done',
  888. this
  889. );
  890. }
  891. if (
  892. this._state === mochaStates.DISPOSED ||
  893. this._state === mochaStates.REFERENCES_CLEANED
  894. ) {
  895. throw createMochaInstanceAlreadyDisposedError(
  896. 'Mocha instance is already disposed, cannot start a new test run. Please create a new mocha instance. Be sure to set disable `cleanReferencesAfterRun` when you want to reuse the same mocha instance for multiple test runs.',
  897. this._cleanReferencesAfterRun,
  898. this
  899. );
  900. }
  901. };
  902. /**
  903. * Mocha version as specified by "package.json".
  904. *
  905. * @name Mocha#version
  906. * @type string
  907. * @readonly
  908. */
  909. Object.defineProperty(Mocha.prototype, 'version', {
  910. value: require('../package.json').version,
  911. configurable: false,
  912. enumerable: true,
  913. writable: false
  914. });
  915. /**
  916. * Callback to be invoked when test execution is complete.
  917. *
  918. * @callback DoneCB
  919. * @param {number} failures - Number of failures that occurred.
  920. */
  921. /**
  922. * Runs root suite and invokes `fn()` when complete.
  923. *
  924. * @description
  925. * To run tests multiple times (or to run tests in files that are
  926. * already in the `require` cache), make sure to clear them from
  927. * the cache first!
  928. *
  929. * @public
  930. * @see {@link Mocha#unloadFiles}
  931. * @see {@link Runner#run}
  932. * @param {DoneCB} [fn] - Callback invoked when test execution completed.
  933. * @returns {Runner} runner instance
  934. * @example
  935. *
  936. * // exit with non-zero status if there were test failures
  937. * mocha.run(failures => process.exitCode = failures ? 1 : 0);
  938. */
  939. Mocha.prototype.run = function(fn) {
  940. this._guardRunningStateTransition();
  941. this._state = mochaStates.RUNNING;
  942. if (this._previousRunner) {
  943. this._previousRunner.dispose();
  944. this.suite.reset();
  945. }
  946. if (this.files.length && !this.loadAsync) {
  947. this.loadFiles();
  948. }
  949. var self = this;
  950. var suite = this.suite;
  951. var options = this.options;
  952. options.files = this.files;
  953. var runner = new exports.Runner(suite, {
  954. delay: options.delay,
  955. cleanReferencesAfterRun: this._cleanReferencesAfterRun
  956. });
  957. createStatsCollector(runner);
  958. var reporter = new this._reporter(runner, options);
  959. runner.checkLeaks = options.checkLeaks === true;
  960. runner.fullStackTrace = options.fullTrace;
  961. runner.asyncOnly = options.asyncOnly;
  962. runner.allowUncaught = options.allowUncaught;
  963. runner.forbidOnly = options.forbidOnly;
  964. runner.forbidPending = options.forbidPending;
  965. if (options.grep) {
  966. runner.grep(options.grep, options.invert);
  967. }
  968. if (options.global) {
  969. runner.globals(options.global);
  970. }
  971. if (options.growl) {
  972. this._growl(runner);
  973. }
  974. if (options.color !== undefined) {
  975. exports.reporters.Base.useColors = options.color;
  976. }
  977. exports.reporters.Base.inlineDiffs = options.inlineDiffs;
  978. exports.reporters.Base.hideDiff = !options.diff;
  979. function done(failures) {
  980. self._previousRunner = runner;
  981. if (self._cleanReferencesAfterRun) {
  982. self._state = mochaStates.REFERENCES_CLEANED;
  983. } else {
  984. self._state = mochaStates.INIT;
  985. }
  986. fn = fn || utils.noop;
  987. if (reporter.done) {
  988. reporter.done(failures, fn);
  989. } else {
  990. fn(failures);
  991. }
  992. }
  993. return runner.run(done);
  994. };
  995. /**
  996. * Assigns hooks to the root suite
  997. * @param {MochaRootHookObject} [hooks] - Hooks to assign to root suite
  998. * @chainable
  999. */
  1000. Mocha.prototype.rootHooks = function rootHooks(hooks) {
  1001. if (utils.type(hooks) === 'object') {
  1002. var beforeAll = [].concat(hooks.beforeAll || []);
  1003. var beforeEach = [].concat(hooks.beforeEach || []);
  1004. var afterAll = [].concat(hooks.afterAll || []);
  1005. var afterEach = [].concat(hooks.afterEach || []);
  1006. var rootSuite = this.suite;
  1007. beforeAll.forEach(function(hook) {
  1008. rootSuite.beforeAll(hook);
  1009. });
  1010. beforeEach.forEach(function(hook) {
  1011. rootSuite.beforeEach(hook);
  1012. });
  1013. afterAll.forEach(function(hook) {
  1014. rootSuite.afterAll(hook);
  1015. });
  1016. afterEach.forEach(function(hook) {
  1017. rootSuite.afterEach(hook);
  1018. });
  1019. }
  1020. return this;
  1021. };
  1022. /**
  1023. * An alternative way to define root hooks that works with parallel runs.
  1024. * @typedef {Object} MochaRootHookObject
  1025. * @property {Function|Function[]} [beforeAll] - "Before all" hook(s)
  1026. * @property {Function|Function[]} [beforeEach] - "Before each" hook(s)
  1027. * @property {Function|Function[]} [afterAll] - "After all" hook(s)
  1028. * @property {Function|Function[]} [afterEach] - "After each" hook(s)
  1029. */
  1030. /**
  1031. * An function that returns a {@link MochaRootHookObject}, either sync or async.
  1032. * @callback MochaRootHookFunction
  1033. * @returns {MochaRootHookObject|Promise<MochaRootHookObject>}
  1034. */