Skip to content

Commit f95f4bc

Browse files
committed
Require opt-in to AVA 5's watcher, remove chokidar from dependencies
1 parent 918b044 commit f95f4bc

File tree

9 files changed

+70
-58
lines changed

9 files changed

+70
-58
lines changed

docs/recipes/watch-mode.md

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,15 @@ Translations: [Français](https://github.com/avajs/ava-docs/blob/main/fr_FR/docs
44

55
AVA comes with an intelligent watch mode. It watches for files to change and runs just those tests that are affected.
66

7+
AVA 6 is introducing a new watch mode that relies on recurse file watching in Node.js. To use the old watch mode, set the `watcher` configuration to `ava5+chokidar` and install [`chokidar`] alongside AVA:
8+
9+
`ava.config.mjs`:
10+
```js
11+
export default {
12+
watcher: 'ava5+chokidar'
13+
}
14+
```
15+
716
## Running tests with watch mode enabled
817

918
You can enable watch mode using the `--watch` or `-w` flags:
@@ -16,7 +25,9 @@ Please note that integrated debugging and the TAP reporter are unavailable when
1625

1726
## Requirements
1827

19-
AVA uses [`chokidar`] as the file watcher. Note that even if you see warnings about optional dependencies failing during install, it will still work fine. Please refer to the *[Install Troubleshooting]* section of `chokidar` documentation for how to resolve the installation problems with chokidar.
28+
AVA 5 uses [`chokidar`] as the file watcher. Note that even if you see warnings about optional dependencies failing during install, it will still work fine. Please refer to the *[Install Troubleshooting]* section of `chokidar` documentation for how to resolve the installation problems with chokidar.
29+
30+
The same applies with AVA 6 when using the `ava5+chokidar` watcher. However you'll need to install `chokidar` separately.
2031

2132
## Ignoring changes
2233

@@ -30,7 +41,9 @@ If your tests write to disk they may trigger the watcher to rerun your tests. Co
3041

3142
AVA tracks which source files your test files depend on. If you change such a dependency only the test file that depends on it will be rerun. AVA will rerun all tests if it cannot determine which test file depends on the changed source file.
3243

33-
Dependency tracking works for required modules. Custom extensions and transpilers are supported, provided you [added them in your `package.json` or `ava.config.*` file][config], and not from inside your test file. Files accessed using the `fs` module are not tracked.
44+
AVA 5 (and the `ava5+chokidar` watcher in AVA 6) spies on `require()` calls to track dependencies. Custom extensions and transpilers are supported, provided you [added them in your `package.json` or `ava.config.*` file][config], and not from inside your test file.
45+
46+
Files accessed using the `fs` module are not tracked.
3447

3548
## Watch mode and the `.only` modifier
3649

lib/watcher.js renamed to lib/ava5-watcher.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -169,11 +169,16 @@ export default class Watcher {
169169
trackTestDependencies(api) {
170170
api.on('run', plan => {
171171
plan.status.on('stateChange', evt => {
172-
if (evt.type !== 'dependencies') {
172+
let dependencies;
173+
if (evt.type === 'dependencies') {
174+
dependencies = evt.dependencies;
175+
} else if (evt.type === 'accessed-snapshots') {
176+
dependencies = [evt.filename];
177+
} else {
173178
return;
174179
}
175180

176-
const dependencies = evt.dependencies.filter(filePath => {
181+
dependencies = dependencies.filter(filePath => {
177182
const {isIgnoredByWatcher} = classify(filePath, this.globs);
178183
return !isIgnoredByWatcher;
179184
});

lib/cli.js

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ import pkg from './pkg.cjs';
2525
import providerManager from './provider-manager.js';
2626
import DefaultReporter from './reporters/default.js';
2727
import TapReporter from './reporters/tap.js';
28-
import Watcher from './watcher.js';
2928

3029
function exit(message) {
3130
console.error(`\n ${chalk.red(figures.cross)} ${message}`);
@@ -415,6 +414,7 @@ export default async function loadCli() { // eslint-disable-line complexity
415414
concurrency: combined.concurrency || 0,
416415
workerThreads: combined.workerThreads !== false,
417416
debug,
417+
enableAva5DependencyTracking: argv.watch && conf.watcher === 'ava5+chokidar',
418418
environmentVariables,
419419
experiments,
420420
extensions,
@@ -476,15 +476,24 @@ export default async function loadCli() { // eslint-disable-line complexity
476476
});
477477

478478
if (argv.watch) {
479-
const watcher = new Watcher({
480-
api,
481-
filter,
482-
globs,
483-
projectDir,
484-
providers,
485-
reporter,
486-
});
487-
watcher.observeStdin(process.stdin);
479+
if (Object.hasOwn(conf, 'watcher')) {
480+
if (conf.watcher === 'ava5+chokidar') {
481+
const {default: Watcher} = await import('./ava5-watcher.js');
482+
const watcher = new Watcher({
483+
api,
484+
filter,
485+
globs,
486+
projectDir,
487+
providers,
488+
reporter,
489+
});
490+
watcher.observeStdin(process.stdin);
491+
} else {
492+
exit('The "watcher" option must be set to "ava5+chokidar"');
493+
}
494+
} else {
495+
exit('TODO');
496+
}
488497
} else {
489498
let debugWithoutSpecificFile = false;
490499
api.on('run', plan => {

lib/runner.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ export default class Runner extends Emittery {
209209
updating: this.updateSnapshots,
210210
});
211211
if (snapshots.snapPath !== undefined) {
212-
this.emit('dependency', snapshots.snapPath);
212+
this.emit('accessed-snapshots', snapshots.snapPath);
213213
}
214214

215215
this._snapshots = snapshots;

lib/worker/base.js

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,9 @@ import providerManager from '../provider-manager.js';
1414
import Runner from '../runner.js';
1515
import serializeError from '../serialize-error.js';
1616

17+
// TODO: Delete along with ava5+chokidar watcher.
18+
import dependencyTracking from './ava5-dependency-tracker.js';
1719
import channel from './channel.cjs';
18-
import dependencyTracking from './dependency-tracker.js';
1920
import lineNumberSelection from './line-numbers.js';
2021
import {set as setOptions} from './options.cjs';
2122
import {flags, refs, sharedWorkerTeardowns} from './state.cjs';
@@ -99,7 +100,11 @@ const run = async options => {
99100
runner.interrupt();
100101
});
101102

102-
runner.on('dependency', dependencyTracking.track);
103+
runner.on('accessed-snapshots', filename => channel.send({type: 'accessed-snapshots', filename}));
104+
if (options.enableAva5DependencyTracking) {
105+
runner.on('dependency', dependencyTracking.track);
106+
}
107+
103108
runner.on('stateChange', state => channel.send(state));
104109

105110
runner.on('error', error => {
@@ -229,9 +234,11 @@ const run = async options => {
229234
}
230235
}
231236

232-
// Install dependency tracker after the require configuration has been evaluated
233-
// to make sure we also track dependencies with custom require hooks
234-
dependencyTracking.install(require.extensions, testPath);
237+
if (options.enableAva5DependencyTracking) {
238+
// Install dependency tracker after the require configuration has been evaluated
239+
// to make sure we also track dependencies with custom require hooks
240+
dependencyTracking.install(require.extensions, testPath);
241+
}
235242

236243
if (options.debug && options.debug.port !== undefined && options.debug.host !== undefined) {
237244
// If an inspector was active when the main process started, and is

package-lock.json

Lines changed: 11 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,6 @@
8989
"callsites": "^4.0.0",
9090
"cbor": "^8.1.0",
9191
"chalk": "^5.2.0",
92-
"chokidar": "^3.5.3",
9392
"chunkd": "^2.0.1",
9493
"ci-info": "^3.8.0",
9594
"ci-parallel-vars": "^1.0.1",
@@ -142,11 +141,15 @@
142141
"zen-observable": "^0.10.0"
143142
},
144143
"peerDependencies": {
145-
"@ava/typescript": "*"
144+
"@ava/typescript": "*",
145+
"chokidar": "^3.5.3"
146146
},
147147
"peerDependenciesMeta": {
148148
"@ava/typescript": {
149149
"optional": true
150+
},
151+
"chokidar": {
152+
"optional": true
150153
}
151154
},
152155
"volta": {

test-tap/api.js

Lines changed: 0 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -418,40 +418,6 @@ for (const opt of options) {
418418
});
419419
});
420420

421-
test(`emits dependencies for test files - workerThreads: ${opt.workerThreads}`, async t => {
422-
t.plan(8);
423-
424-
const api = await apiCreator({
425-
...opt,
426-
files: ['test-tap/fixture/with-dependencies/*test*.cjs'],
427-
require: [path.resolve('test-tap/fixture/with-dependencies/require-custom.cjs')],
428-
});
429-
430-
const testFiles = new Set([
431-
path.resolve('test-tap/fixture/with-dependencies/no-tests.cjs'),
432-
path.resolve('test-tap/fixture/with-dependencies/test.cjs'),
433-
path.resolve('test-tap/fixture/with-dependencies/test-failure.cjs'),
434-
path.resolve('test-tap/fixture/with-dependencies/test-uncaught-exception.cjs'),
435-
]);
436-
437-
const sourceFiles = [
438-
path.resolve('test-tap/fixture/with-dependencies/dep-1.js'),
439-
path.resolve('test-tap/fixture/with-dependencies/dep-2.js'),
440-
path.resolve('test-tap/fixture/with-dependencies/dep-3.custom'),
441-
];
442-
443-
api.on('run', plan => {
444-
plan.status.on('stateChange', evt => {
445-
if (evt.type === 'dependencies') {
446-
t.ok(testFiles.has(evt.testFile));
447-
t.strictSame(evt.dependencies.filter(dep => !dep.endsWith('.snap')).slice(-3), sourceFiles);
448-
}
449-
});
450-
});
451-
452-
return api.run();
453-
});
454-
455421
test(`verify test count - workerThreads: ${opt.workerThreads}`, async t => {
456422
t.plan(4);
457423

0 commit comments

Comments
 (0)