diff --git a/docs/README.md b/docs/README.md index 0a069dff03..582e5354c7 100644 --- a/docs/README.md +++ b/docs/README.md @@ -22,8 +22,8 @@ - The content lives in `docs/index.md`; everything else is markup, scripts, assets, etc. - This file (`docs/README.md`) should *not* be included in the build. -- `docs/index.md` may be mutated upon build, depending on what `scripts/docs-update-toc.js` does. If it updates the table of contents (because of your changes), **you must commit `docs/index.md`**. -- `docs/_site/` is where the generated static site lives (and is what you see at [mochajs.org](https://mochajs.org)). It is *not* under version control. +- `docs/_dist` and `docs/api` are where the deployed site lives. `docs/_site` is essentially a build step. These three directories are *not* under version control. +- See `package-scripts.js` for details on what the builds are actually doing; especially see [markdown-magic](https://npm.im/markdown-magic) for how we're dynamically inserting information into `docs/index.md`. ## License diff --git a/lib/cli/run-helpers.js b/lib/cli/run-helpers.js index d020768aed..3afa7143d3 100644 --- a/lib/cli/run-helpers.js +++ b/lib/cli/run-helpers.js @@ -190,21 +190,12 @@ exports.handleFiles = ({ * @param {Options} [opts] - Options * @param {string[]} [opts.files] - List of test files * @param {boolean} [opts.exit] - Whether or not to force-exit after tests are complete + * @returns {Runner} * @private */ exports.singleRun = (mocha, {files = [], exit = false} = {}) => { mocha.files = files; - const runner = mocha.run(exit ? exitMocha : exitMochaLater); - - process.on('SIGINT', () => { - debug('aborting runner'); - runner.abort(); - - // This is a hack: - // Instead of `process.exit(130)`, set runner.failures to 130 (exit code for SIGINT) - // The amount of failures will be emitted as error code later - runner.failures = 130; - }); + return mocha.run(exit ? exitMocha : exitMochaLater); }; /** diff --git a/lib/mocha.js b/lib/mocha.js index 0478f2c1b3..cce2bb9b2f 100644 --- a/lib/mocha.js +++ b/lib/mocha.js @@ -120,7 +120,7 @@ function Mocha(options) { if ('enableTimeouts' in options) { utils.deprecate( - 'enableTimeouts is DEPRECATED and will be removed from a future version of Mocha. Instead, use "timeouts: false" to disable timeouts.' + 'enableTimeouts is DEPRECATED and will be removed from a future version of Mocha. Instead, use "timeout: false" to disable timeouts.' ); } this.timeout( diff --git a/lib/runner.js b/lib/runner.js index e88b11cda3..948f198128 100644 --- a/lib/runner.js +++ b/lib/runner.js @@ -579,6 +579,8 @@ Runner.prototype.runTests = function(suite, fn) { clonedTest.currentRetry(retry + 1); tests.unshift(clonedTest); + self.emit('retry', test, err); + // Early return + hook trigger so that it doesn't // increment the count wrong return self.hookUp('afterEach', next); diff --git a/lib/stats-collector.js b/lib/stats-collector.js index 1c1491ca81..0afa10f1cd 100644 --- a/lib/stats-collector.js +++ b/lib/stats-collector.js @@ -1,8 +1,15 @@ 'use strict'; +/** + * Provides a factory function for a {@link StatsCollector} object. + * @private + * @module + */ + /** * Test statistics collector. * + * @private * @typedef {Object} StatsCollector * @property {number} suites - integer count of suites run. * @property {number} tests - integer count of tests run. @@ -15,14 +22,16 @@ */ /** - * Provides stats such as test duration, - * number of tests passed / failed etc. + * Provides stats such as test duration, number of tests passed / failed etc., by listening for events emitted by `runner`. * - * @public - * @memberof Mocha - * @param {Runner} runner + * @private + * @param {Runner} runner - Runner instance + * @throws {TypeError} If falsy `runner` */ function createStatsCollector(runner) { + /** + * @type StatsCollector + */ var stats = { suites: 0, tests: 0, diff --git a/test/unit/runner.spec.js b/test/unit/runner.spec.js index e7273eaf11..50af94aa5d 100644 --- a/test/unit/runner.spec.js +++ b/test/unit/runner.spec.js @@ -393,6 +393,36 @@ describe('Runner', function() { }); }); + describe('.run(fn)', function() { + it('should emit "retry" when a retryable test fails', function(done) { + var retries = 2; + var retryableFails = 0; + var err = new Error('bear error'); + + var test = new Test('im a test about bears', function() { + if (retryableFails < retries) { + throw err; + } + }); + + suite.retries(retries); + suite.addTest(test); + + runner.on('retry', function(testClone, testErr) { + retryableFails += 1; + expect(testClone.title, 'to be', test.title); + expect(testErr, 'to be', err); + }); + + runner.run(function(failures) { + expect(failures, 'to be', 0); + expect(retryableFails, 'to be', retries); + + done(); + }); + }); + }); + describe('allowUncaught', function() { it('should allow unhandled errors to propagate through', function(done) { var newRunner = new Runner(suite);