aboutsummaryrefslogtreecommitdiff
path: root/node_modules/ava/lib/watcher.js
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/ava/lib/watcher.js')
-rw-r--r--node_modules/ava/lib/watcher.js54
1 files changed, 45 insertions, 9 deletions
diff --git a/node_modules/ava/lib/watcher.js b/node_modules/ava/lib/watcher.js
index 3d7094ffb..c90c810f0 100644
--- a/node_modules/ava/lib/watcher.js
+++ b/node_modules/ava/lib/watcher.js
@@ -16,18 +16,23 @@ function rethrowAsync(err) {
});
}
+const MIN_DEBOUNCE_DELAY = 10;
+const INITIAL_DEBOUNCE_DELAY = 100;
+
class Debouncer {
constructor(watcher) {
this.watcher = watcher;
this.timer = null;
this.repeat = false;
}
- debounce() {
+ debounce(delay) {
if (this.timer) {
this.again = true;
return;
}
+ delay = delay ? Math.max(delay, MIN_DEBOUNCE_DELAY) : INITIAL_DEBOUNCE_DELAY;
+
const timer = setTimeout(() => {
this.watcher.busy.then(() => {
// Do nothing if debouncing was canceled while waiting for the busy
@@ -39,14 +44,14 @@ class Debouncer {
if (this.again) {
this.timer = null;
this.again = false;
- this.debounce();
+ this.debounce(delay / 2);
} else {
this.watcher.runAfterChanges();
this.timer = null;
this.again = false;
}
});
- }, 10);
+ }, delay);
this.timer = timer;
}
@@ -79,7 +84,8 @@ class Watcher {
this.clearLogOnNextRun = true;
this.runVector = 0;
- this.run = specificFiles => {
+ this.previousFiles = files;
+ this.run = (specificFiles, updateSnapshots) => {
if (this.runVector > 0) {
const cleared = this.clearLogOnNextRun && logger.clear();
if (!cleared) {
@@ -111,7 +117,9 @@ class Watcher {
}
}
- this.busy = api.run(specificFiles || files, {runOnlyExclusive})
+ this.touchedFiles.clear();
+ this.previousFiles = specificFiles || files;
+ this.busy = api.run(this.previousFiles, {runOnlyExclusive, updateSnapshots: updateSnapshots === true})
.then(runStatus => {
runStatus.previousFailCount = this.sumPreviousFailures(currentVector);
logger.finish(runStatus);
@@ -125,6 +133,9 @@ class Watcher {
this.testDependencies = [];
this.trackTestDependencies(api, sources);
+ this.touchedFiles = new Set();
+ this.trackTouchedFiles(api);
+
this.filesWithExclusiveTests = [];
this.trackExclusivity(api);
@@ -179,6 +190,15 @@ class Watcher {
this.testDependencies.push(new TestDependency(file, sources));
}
}
+ trackTouchedFiles(api) {
+ api.on('test-run', runStatus => {
+ runStatus.on('touchedFiles', files => {
+ for (const file of files) {
+ this.touchedFiles.add(nodePath.relative(process.cwd(), file));
+ }
+ });
+ });
+ }
trackExclusivity(api) {
api.on('stats', stats => {
this.updateExclusivity(stats.file, stats.hasExclusive);
@@ -255,7 +275,7 @@ class Watcher {
stdin.on('data', data => {
data = data.trim().toLowerCase();
- if (data !== 'r' && data !== 'rs') {
+ if (data !== 'r' && data !== 'rs' && data !== 'u') {
return;
}
@@ -267,7 +287,11 @@ class Watcher {
// the busy promise to fulfil
this.debouncer.cancel();
this.clearLogOnNextRun = false;
- this.rerunAll();
+ if (data === 'u') {
+ this.updatePreviousSnapshots();
+ } else {
+ this.rerunAll();
+ }
});
});
}
@@ -275,11 +299,22 @@ class Watcher {
this.dirtyStates = {};
this.run();
}
+ updatePreviousSnapshots() {
+ this.dirtyStates = {};
+ this.run(this.previousFiles, true);
+ }
runAfterChanges() {
const dirtyStates = this.dirtyStates;
this.dirtyStates = {};
- const dirtyPaths = Object.keys(dirtyStates);
+ const dirtyPaths = Object.keys(dirtyStates).filter(path => {
+ if (this.touchedFiles.has(path)) {
+ debug('Ignoring known touched file %s', path);
+ this.touchedFiles.delete(path);
+ return false;
+ }
+ return true;
+ });
const dirtyTests = dirtyPaths.filter(this.avaFiles.isTest);
const dirtySources = diff(dirtyPaths, dirtyTests);
const addedOrChangedTests = dirtyTests.filter(path => dirtyStates[path] !== 'unlink');
@@ -309,7 +344,8 @@ class Watcher {
// Rerun all tests if source files were changed that could not be traced to
// specific tests
if (testsBySource.length !== dirtySources.length) {
- debug('Sources remain that cannot be traced to specific tests. Rerunning all tests');
+ debug('Sources remain that cannot be traced to specific tests: %O', dirtySources);
+ debug('Rerunning all tests');
this.run();
return;
}