From edc09bf147bef3a40cd5557fb797808136b7d3da Mon Sep 17 00:00:00 2001 From: indieisaconcept Date: Sun, 26 Jul 2020 12:07:58 +1000 Subject: [PATCH] Ensure root level hooks are called when running in watch mode ## Rationale Tests with root level hooks are ignored when running in watch mode. This occurs on initial & subsequent runs. ## Changes - updated `lib/cli/run-watch` to re-initialise rootHooks As we have swapped out the root suite it is necessary to re-initialize root level hooks again. - Extended integration tests for watch to take into consideration hooks ## Refs - mochajs/mocha/issues/4347 --- lib/cli/watch-run.js | 8 ++++ .../fixtures/options/watch/hook.fixture.js | 7 ++++ test/integration/options/watch.spec.js | 37 +++++++++++++++++++ 3 files changed, 52 insertions(+) create mode 100644 test/integration/fixtures/options/watch/hook.fixture.js diff --git a/lib/cli/watch-run.js b/lib/cli/watch-run.js index a3135c791a..0fb214d92e 100644 --- a/lib/cli/watch-run.js +++ b/lib/cli/watch-run.js @@ -59,6 +59,10 @@ exports.watchParallelRun = ( // in `createRerunner`), we need to call `mocha.ui()` again to set up the context/globals. newMocha.ui(newMocha.options.ui); + // we need to call `newMocha.rootHooks` to set up rootHooks for the new + // suite + newMocha.rootHooks(newMocha.options.rootHooks); + // in parallel mode, the main Mocha process doesn't actually load the // files. this flag prevents `mocha.run()` from autoloading. newMocha.lazyLoadFiles(true); @@ -118,6 +122,10 @@ exports.watchRun = (mocha, {watchFiles, watchIgnore}, fileCollectParams) => { // in `createRerunner`), we need to call `mocha.ui()` again to set up the context/globals. newMocha.ui(newMocha.options.ui); + // we need to call `newMocha.rootHooks` to set up rootHooks for the new + // suite + newMocha.rootHooks(newMocha.options.rootHooks); + return newMocha; }, afterRun({watcher}) { diff --git a/test/integration/fixtures/options/watch/hook.fixture.js b/test/integration/fixtures/options/watch/hook.fixture.js new file mode 100644 index 0000000000..3463761f3a --- /dev/null +++ b/test/integration/fixtures/options/watch/hook.fixture.js @@ -0,0 +1,7 @@ +module.exports = { + mochaHooks: { + [""]: function() { + throw new Error(" Hook Error"); + }, + }, +}; diff --git a/test/integration/options/watch.spec.js b/test/integration/options/watch.spec.js index 55ea345ab7..822b28b6da 100644 --- a/test/integration/options/watch.spec.js +++ b/test/integration/options/watch.spec.js @@ -275,6 +275,43 @@ describe('--watch', function() { expect(results[1].tests, 'to have length', 2); }); }); + + describe('with required hooks', function() { + /** + * Helper for setting up hook tests + * + * @param {string} hookName name of hook to test + * @return {function} + */ + function setupHookTest(hookName) { + return function() { + const testFile = path.join(tempDir, 'test.js'); + const hookFile = path.join(tempDir, 'hook.js'); + + copyFixture('__default__', testFile); + copyFixture('options/watch/hook', hookFile); + + replaceFileContents(hookFile, '', hookName); + + return runMochaWatch( + [testFile, '--require', hookFile], + tempDir, + () => { + touchFile(testFile); + } + ).then(results => { + expect(results.length, 'to equal', 2); + expect(results[0].failures, 'to have length', 1); + expect(results[1].failures, 'to have length', 1); + }); + }; + } + + it('mochaHooks.beforeAll runs as expected', setupHookTest('beforeAll')); + it('mochaHooks.beforeEach runs as expected', setupHookTest('beforeEach')); + it('mochaHooks.afterAll runs as expected', setupHookTest('afterAll')); + it('mochaHooks.afterEach runs as expected', setupHookTest('afterEach')); + }); }); });