diff --git a/lib/worker/subprocess.js b/lib/worker/subprocess.js index 4a31fdb32..90b829d6a 100644 --- a/lib/worker/subprocess.js +++ b/lib/worker/subprocess.js @@ -105,7 +105,6 @@ ipc.options.then(options => { // Install before processing options.require, so if helpers are added to the // require configuration the *compiled* helper will be loaded. - dependencyTracking.install(testPath); precompilerHook.install(); try { @@ -120,6 +119,10 @@ ipc.options.then(options => { } catch (_) {} } + // Install dependency tracker after the require configuration has been evaluated + // to make sure we also track dependencies with custom require hooks + dependencyTracking.install(testPath); + require(testPath); if (accessedRunner) { diff --git a/test/fixture/watcher/with-custom-ext-dependencies/ava.config.js b/test/fixture/watcher/with-custom-ext-dependencies/ava.config.js new file mode 100644 index 000000000..f68647003 --- /dev/null +++ b/test/fixture/watcher/with-custom-ext-dependencies/ava.config.js @@ -0,0 +1,3 @@ +export default { + sources: ['source.custom-ext', 'setup.js'] +}; diff --git a/test/fixture/watcher/with-custom-ext-dependencies/package.json b/test/fixture/watcher/with-custom-ext-dependencies/package.json new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/test/fixture/watcher/with-custom-ext-dependencies/package.json @@ -0,0 +1 @@ +{} diff --git a/test/fixture/watcher/with-custom-ext-dependencies/setup.js b/test/fixture/watcher/with-custom-ext-dependencies/setup.js new file mode 100644 index 000000000..b53dd5153 --- /dev/null +++ b/test/fixture/watcher/with-custom-ext-dependencies/setup.js @@ -0,0 +1,9 @@ +'use strict'; + +const fs = require('fs'); + +// eslint-disable-next-line node/no-deprecated-api +require.extensions['.custom-ext'] = function (module, filename) { + const content = fs.readFileSync(filename, 'utf8'); + module._compile(content, filename); +}; diff --git a/test/fixture/watcher/with-custom-ext-dependencies/source.custom-ext b/test/fixture/watcher/with-custom-ext-dependencies/source.custom-ext new file mode 100644 index 000000000..80b9ab875 --- /dev/null +++ b/test/fixture/watcher/with-custom-ext-dependencies/source.custom-ext @@ -0,0 +1,2 @@ +'use strict'; +module.exports = true; diff --git a/test/fixture/watcher/with-custom-ext-dependencies/test-1.js b/test/fixture/watcher/with-custom-ext-dependencies/test-1.js new file mode 100644 index 000000000..fdc5398a8 --- /dev/null +++ b/test/fixture/watcher/with-custom-ext-dependencies/test-1.js @@ -0,0 +1,6 @@ +import test from '../../../..'; +import dependency from './source.custom-ext'; + +test('works', t => { + t.truthy(dependency); +}); diff --git a/test/fixture/watcher/with-custom-ext-dependencies/test-2.js b/test/fixture/watcher/with-custom-ext-dependencies/test-2.js new file mode 100644 index 000000000..a7b86803a --- /dev/null +++ b/test/fixture/watcher/with-custom-ext-dependencies/test-2.js @@ -0,0 +1,5 @@ +import test from '../../../..'; + +test('works', t => { + t.pass(); +}); diff --git a/test/integration/watcher.js b/test/integration/watcher.js index c501f3237..69a2adce9 100644 --- a/test/integration/watcher.js +++ b/test/integration/watcher.js @@ -82,6 +82,54 @@ test('watcher reruns test files when source dependencies change', t => { }); }); +test('watcher reruns ONLY test files that depend on a changed source with custom extension', t => { + let killed = false; + + const child = execCli(['--verbose', '--require', './setup.js', '--watch', 'test-1.js', 'test-2.js'], {dirname: 'fixture/watcher/with-custom-ext-dependencies', env: {CI: ''}}, err => { + t.ok(killed); + t.ifError(err); + t.end(); + }); + + let buffer = ''; + let passedFirst = false; + child.stdout.on('data', str => { + buffer += str; + if (buffer.includes('2 tests passed') && !passedFirst) { + touch.sync(path.join(__dirname, '../fixture/watcher/with-custom-ext-dependencies/source.custom-ext')); + buffer = ''; + passedFirst = true; + } else if (buffer.includes('1 test passed') && !killed) { + child.kill(); + killed = true; + } + }); +}); + +test('watcher reruns all tests when one of the configured files in the `require` option changes', t => { + let killed = false; + + const child = execCli(['--verbose', '--require', './setup.js', '--watch', 'test-1.js', 'test-2.js'], {dirname: 'fixture/watcher/with-custom-ext-dependencies', env: {CI: ''}}, err => { + t.ok(killed); + t.ifError(err); + t.end(); + }); + + let buffer = ''; + let passedFirst = false; + child.stdout.on('data', str => { + buffer += str; + if (buffer.includes('2 tests passed') && !passedFirst) { + touch.sync(path.join(__dirname, '../fixture/watcher/with-custom-ext-dependencies/setup.js')); + buffer = ''; + passedFirst = true; + } else if (buffer.includes('2 tests passed') && !killed) { + child.kill(); + killed = true; + } + }); +}); + test('watcher does not rerun test files when they write snapshot files', t => { let killed = false;