diff --git a/lib/process-adapter.js b/lib/process-adapter.js index b50f37398..5f9c0d79d 100644 --- a/lib/process-adapter.js +++ b/lib/process-adapter.js @@ -94,7 +94,7 @@ exports.installDependencyTracking = (dependencies, testPath) => { require.extensions[ext] = (module, filename) => { if (filename !== testPath) { - dependencies.push(filename); + dependencies.add(filename); } wrappedHandler(module, filename); diff --git a/lib/runner.js b/lib/runner.js index 7a561c298..45126e374 100644 --- a/lib/runner.js +++ b/lib/runner.js @@ -188,6 +188,7 @@ class Runner extends EventEmitter { const dir = path.join(path.dirname(this.file), '__snapshots__'); const relFile = path.relative(this.projectDir, this.file); this.snapshots = snapshotManager.load(dir, name, relFile, this.updateSnapshots); + this.emit('dependency', this.snapshots.snapPath); } return this.snapshots.compare(options); diff --git a/lib/snapshot-manager.js b/lib/snapshot-manager.js index e2cd3a25d..5b710df69 100644 --- a/lib/snapshot-manager.js +++ b/lib/snapshot-manager.js @@ -286,6 +286,7 @@ class Manager { this.relFile = options.relFile; this.reportFile = options.reportFile; this.snapFile = options.snapFile; + this.snapPath = options.snapPath; this.snapshotsByHash = options.snapshotsByHash; this.hasChanges = false; @@ -336,7 +337,7 @@ class Manager { return null; } - const snapPath = path.join(this.dir, this.snapFile); + const snapPath = this.snapPath; const buffer = encodeSnapshots(this.snapshotsByHash); const reportPath = path.join(this.dir, this.reportFile); @@ -356,12 +357,12 @@ class Manager { function load(dir, name, relFile, updating) { const reportFile = `${name}.md`; const snapFile = `${name}.snap`; + const snapPath = path.join(dir, snapFile); let appendOnly = !updating; let snapshotsByHash; if (!updating) { - const snapPath = path.join(dir, snapFile); const buffer = tryRead(snapPath); if (buffer) { snapshotsByHash = decodeSnapshots(buffer, snapPath); @@ -376,6 +377,7 @@ function load(dir, name, relFile, updating) { relFile, reportFile, snapFile, + snapPath, snapshotsByHash: snapshotsByHash || new Map() }); } diff --git a/lib/test-worker.js b/lib/test-worker.js index 10faa10c0..0061775f0 100644 --- a/lib/test-worker.js +++ b/lib/test-worker.js @@ -39,7 +39,7 @@ adapter.installPrecompilerHook(); const testPath = opts.file; -const dependencies = []; +const dependencies = new Set(); adapter.installDependencyTracking(dependencies, testPath); const touchedFiles = new Set(); @@ -48,6 +48,9 @@ const touchedFiles = new Set(); let runner = null; exports.setRunner = newRunner => { runner = newRunner; + runner.on('dependency', file => { + dependencies.add(file); + }); runner.on('touched', files => { for (const file of files) { touchedFiles.add(file); @@ -132,7 +135,10 @@ process.on('ava-teardown', () => { // set of dependencies is included no matter how the process exits, unless // it flat out crashes. Also include any files that AVA touched during the // test run. This allows the watcher to ignore modifications to those files. - adapter.send('teardown', {dependencies, touchedFiles: Array.from(touchedFiles)}); + adapter.send('teardown', { + dependencies: Array.from(dependencies), + touchedFiles: Array.from(touchedFiles) + }); }); process.on('ava-exit', () => { diff --git a/test/cli.js b/test/cli.js index 6e008da9a..8446a614d 100644 --- a/test/cli.js +++ b/test/cli.js @@ -333,6 +333,34 @@ test('watcher does not rerun test files when they write snapshot files', t => { }); }); +test('watcher reruns test files when snapshot dependencies change', t => { + let killed = false; + + const child = execCli(['--verbose', '--watch', '--update-snapshots', 'test.js'], {dirname: 'fixture/snapshots'}, err => { + t.ok(killed); + t.ifError(err); + t.end(); + }); + + let buffer = ''; + let passedFirst = false; + child.stderr.on('data', str => { + buffer += str; + if (/2 tests passed/.test(buffer)) { + buffer = ''; + if (passedFirst) { + child.kill(); + killed = true; + } else { + passedFirst = true; + setTimeout(() => { + touch.sync(path.join(__dirname, 'fixture/snapshots/__snapshots__/test.js.snap')); + }, 500); + } + } + }); +}); + test('`"tap": true` config is ignored when --watch is given', t => { let killed = false;