Skip to content

doc, test: update --watch for linux recursive watch #55256

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions doc/api/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -2854,10 +2854,6 @@ This flag cannot be combined with
node --watch-path=./src --watch-path=./tests index.js
```

This option is only supported on macOS and Windows.
An `ERR_FEATURE_UNAVAILABLE_ON_PLATFORM` exception will be thrown
when the option is used on a platform that does not support it.

### `--watch-preserve-output`

<!-- YAML
Expand Down
23 changes: 12 additions & 11 deletions doc/api/errors.md
Original file line number Diff line number Diff line change
Expand Up @@ -1252,17 +1252,6 @@ for the JS engine are not set up properly.
A `Promise` that was callbackified via `util.callbackify()` was rejected with a
falsy value.

<a id="ERR_FEATURE_UNAVAILABLE_ON_PLATFORM"></a>

### `ERR_FEATURE_UNAVAILABLE_ON_PLATFORM`

<!-- YAML
added: v14.0.0
-->

Used when a feature that is not available
to the current platform which is running Node.js is used.

<a id="ERR_FS_CP_DIR_TO_NON_DIR"></a>

### `ERR_FS_CP_DIR_TO_NON_DIR`
Expand Down Expand Up @@ -3299,6 +3288,18 @@ An incompatible combination of options was passed to [`crypto.scrypt()`][] or
[`crypto.scryptSync()`][]. New versions of Node.js use the error code
[`ERR_INCOMPATIBLE_OPTION_PAIR`][] instead, which is consistent with other APIs.

<a id="ERR_FEATURE_UNAVAILABLE_ON_PLATFORM"></a>

### `ERR_FEATURE_UNAVAILABLE_ON_PLATFORM`

<!-- YAML
added: v14.0.0
removed: v19.1.0
-->

Used when a feature that is not available
to the current platform which is running Node.js is used.

<a id="ERR_FS_INVALID_SYMLINK_TYPE"></a>

### `ERR_FS_INVALID_SYMLINK_TYPE`
Expand Down
4 changes: 0 additions & 4 deletions lib/internal/errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -1202,10 +1202,6 @@ E('ERR_FALSY_VALUE_REJECTION', function(reason) {
this.reason = reason;
return 'Promise was rejected with falsy value';
}, Error, HideStackFramesError);
E('ERR_FEATURE_UNAVAILABLE_ON_PLATFORM',
'The feature %s is unavailable on the current platform' +
', which is being used to run Node.js',
TypeError);
E('ERR_FS_CP_DIR_TO_NON_DIR',
'Cannot overwrite non-directory with directory', SystemError);
E('ERR_FS_CP_EEXIST', 'Target already exists', SystemError);
Expand Down
114 changes: 54 additions & 60 deletions test/parallel/test-watch-mode-files_watcher.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -93,14 +93,13 @@ describe('watch mode file watcher', () => {
assert.ok(changesCount < 5);
});

it('should ignore files in watched directory if they are not filtered',
{ skip: !supportsRecursiveWatching }, async () => {
watcher.on('changed', common.mustNotCall());
watcher.watchPath(tmpdir.path);
writeFileSync(tmpdir.resolve('file3'), '1');
// Wait for this long to make sure changes are not triggered
await setTimeout(1000);
});
it('should ignore files in watched directory if they are not filtered', async () => {
watcher.on('changed', common.mustNotCall());
watcher.watchPath(tmpdir.path);
writeFileSync(tmpdir.resolve('file3'), '1');
// Wait for this long to make sure changes are not triggered
await setTimeout(1000);
});

it('should allow clearing filters', async () => {
const file = tmpdir.resolve('file4');
Expand All @@ -118,58 +117,53 @@ describe('watch mode file watcher', () => {
assert.strictEqual(changesCount, 1);
});

it('should watch all files in watched path when in "all" mode',
{ skip: !supportsRecursiveWatching }, async () => {
watcher = new FilesWatcher({ debounce: 100, mode: 'all' });
watcher.on('changed', () => changesCount++);

const file = tmpdir.resolve('file5');
watcher.watchPath(tmpdir.path);

const changed = once(watcher, 'changed');
await setTimeout(common.platformTimeout(100)); // avoid throttling
writeFileSync(file, 'changed');
await changed;
assert.strictEqual(changesCount, 1);
});

it('should ruse existing watcher if it exists',
{ skip: !supportsRecursiveWatching }, () => {
assert.deepStrictEqual(watcher.watchedPaths, []);
watcher.watchPath(tmpdir.path);
assert.deepStrictEqual(watcher.watchedPaths, [tmpdir.path]);
watcher.watchPath(tmpdir.path);
assert.deepStrictEqual(watcher.watchedPaths, [tmpdir.path]);
});

it('should ruse existing watcher of a parent directory',
{ skip: !supportsRecursiveWatching }, () => {
assert.deepStrictEqual(watcher.watchedPaths, []);
watcher.watchPath(tmpdir.path);
assert.deepStrictEqual(watcher.watchedPaths, [tmpdir.path]);
watcher.watchPath(tmpdir.resolve('subdirectory'));
assert.deepStrictEqual(watcher.watchedPaths, [tmpdir.path]);
});

it('should remove existing watcher if adding a parent directory watcher',
{ skip: !supportsRecursiveWatching }, () => {
assert.deepStrictEqual(watcher.watchedPaths, []);
const subdirectory = tmpdir.resolve('subdirectory');
mkdirSync(subdirectory);
watcher.watchPath(subdirectory);
assert.deepStrictEqual(watcher.watchedPaths, [subdirectory]);
watcher.watchPath(tmpdir.path);
assert.deepStrictEqual(watcher.watchedPaths, [tmpdir.path]);
});

it('should clear all watchers when calling clear',
{ skip: !supportsRecursiveWatching }, () => {
assert.deepStrictEqual(watcher.watchedPaths, []);
watcher.watchPath(tmpdir.path);
assert.deepStrictEqual(watcher.watchedPaths, [tmpdir.path]);
watcher.clear();
assert.deepStrictEqual(watcher.watchedPaths, []);
});
it('should watch all files in watched path when in "all" mode', async () => {
watcher = new FilesWatcher({ debounce: 100, mode: 'all' });
watcher.on('changed', () => changesCount++);

const file = tmpdir.resolve('file5');
watcher.watchPath(tmpdir.path);

const changed = once(watcher, 'changed');
await setTimeout(common.platformTimeout(100)); // avoid throttling
writeFileSync(file, 'changed');
await changed;
assert.strictEqual(changesCount, 1);
});

it('should ruse existing watcher if it exists', () => {
assert.deepStrictEqual(watcher.watchedPaths, []);
watcher.watchPath(tmpdir.path);
assert.deepStrictEqual(watcher.watchedPaths, [tmpdir.path]);
watcher.watchPath(tmpdir.path);
assert.deepStrictEqual(watcher.watchedPaths, [tmpdir.path]);
});

it('should ruse existing watcher of a parent directory', () => {
assert.deepStrictEqual(watcher.watchedPaths, []);
watcher.watchPath(tmpdir.path);
assert.deepStrictEqual(watcher.watchedPaths, [tmpdir.path]);
watcher.watchPath(tmpdir.resolve('subdirectory'));
assert.deepStrictEqual(watcher.watchedPaths, [tmpdir.path]);
});

it('should remove existing watcher if adding a parent directory watcher', () => {
assert.deepStrictEqual(watcher.watchedPaths, []);
const subdirectory = tmpdir.resolve('subdirectory');
mkdirSync(subdirectory);
watcher.watchPath(subdirectory);
assert.deepStrictEqual(watcher.watchedPaths, [subdirectory]);
watcher.watchPath(tmpdir.path);
assert.deepStrictEqual(watcher.watchedPaths, [tmpdir.path]);
});

it('should clear all watchers when calling clear', () => {
assert.deepStrictEqual(watcher.watchedPaths, []);
watcher.watchPath(tmpdir.path);
assert.deepStrictEqual(watcher.watchedPaths, [tmpdir.path]);
watcher.clear();
assert.deepStrictEqual(watcher.watchedPaths, []);
});

it('should watch files from subprocess IPC events', async () => {
const file = fixtures.path('watch-mode/ipc.js');
Expand Down
37 changes: 9 additions & 28 deletions test/sequential/test-watch-mode.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -259,9 +259,7 @@ describe('watch mode', { concurrency: !process.env.TEST_PARALLEL, timeout: 60_00
]);
});

it('should watch changes to a file with watch-path', {
skip: !supportsRecursive,
}, async () => {
it('should watch changes to a file with watch-path', async () => {
const dir = tmpdir.resolve('subdir1');
mkdirSync(dir);
const file = createTmpFile();
Expand All @@ -280,9 +278,7 @@ describe('watch mode', { concurrency: !process.env.TEST_PARALLEL, timeout: 60_00
assert.strictEqual(stderr, '');
});

it('should watch when running an non-existing file - when specified under --watch-path', {
skip: !supportsRecursive
}, async () => {
it('should watch when running an non-existing file - when specified under --watch-path', async () => {
const dir = tmpdir.resolve('subdir2');
mkdirSync(dir);
const file = path.join(dir, 'non-existing.js');
Expand All @@ -304,9 +300,7 @@ describe('watch mode', { concurrency: !process.env.TEST_PARALLEL, timeout: 60_00
]);
});

it('should watch when running an non-existing file - when specified under --watch-path with equals', {
skip: !supportsRecursive
}, async () => {
it('should watch when running an non-existing file - when specified under --watch-path with equals', async () => {
const dir = tmpdir.resolve('subdir3');
mkdirSync(dir);
const file = path.join(dir, 'non-existing.js');
Expand Down Expand Up @@ -453,17 +447,12 @@ console.log(values.random);
]);
});

// TODO: Remove skip after https://github.com/nodejs/node/pull/45271 lands
it('should not watch when running an missing file', {
skip: !supportsRecursive
}, async () => {
it('should not watch when running an missing file', async () => {
const nonExistingfile = tmpdir.resolve(`${tmpFiles++}.js`);
await failWriteSucceed({ file: nonExistingfile, watchedFile: nonExistingfile });
});

it('should not watch when running an missing mjs file', {
skip: !supportsRecursive
}, async () => {
it('should not watch when running an missing mjs file', async () => {
const nonExistingfile = tmpdir.resolve(`${tmpFiles++}.mjs`);
await failWriteSucceed({ file: nonExistingfile, watchedFile: nonExistingfile });
});
Expand Down Expand Up @@ -517,9 +506,7 @@ console.log(values.random);
]);
});

it('should run when `--watch-path=./foo --require ./bar.js`', {
skip: !supportsRecursive,
}, async () => {
it('should run when `--watch-path=./foo --require ./bar.js`', async () => {
const projectDir = tmpdir.resolve('project2');
mkdirSync(projectDir);

Expand Down Expand Up @@ -549,9 +536,7 @@ console.log(values.random);
]);
});

it('should run when `--watch-path=./foo --require=./bar.js`', {
skip: !supportsRecursive,
}, async () => {
it('should run when `--watch-path=./foo --require=./bar.js`', async () => {
const projectDir = tmpdir.resolve('project3');
mkdirSync(projectDir);

Expand Down Expand Up @@ -581,9 +566,7 @@ console.log(values.random);
]);
});

it('should run when `--watch-path ./foo --require ./bar.js`', {
skip: !supportsRecursive,
}, async () => {
it('should run when `--watch-path ./foo --require ./bar.js`', async () => {
const projectDir = tmpdir.resolve('project5');
mkdirSync(projectDir);

Expand Down Expand Up @@ -613,9 +596,7 @@ console.log(values.random);
]);
});

it('should run when `--watch-path=./foo --require=./bar.js`', {
skip: !supportsRecursive,
}, async () => {
it('should run when `--watch-path=./foo --require=./bar.js`', async () => {
const projectDir = tmpdir.resolve('project6');
mkdirSync(projectDir);

Expand Down
Loading