diff --git a/src/__tests__/volume.test.ts b/src/__tests__/volume.test.ts index 9aea5c26c..31a905f45 100644 --- a/src/__tests__/volume.test.ts +++ b/src/__tests__/volume.test.ts @@ -1090,6 +1090,42 @@ describe('volume', () => { }); }); describe('.watch(path[, options], listener)', () => { + it('should handle watching a file correctly', () => { + const vol = Volume.fromJSON({ '/tmp/foo.js': 'hello test' }); + vol.writeFileSync('/tmp/foo.js', 'hello test'); + + const mockCallback = jest.fn(); + const writtenContent = 'hello world'; + const watcher = vol.watch('/tmp/foo.js', mockCallback as any); + + try { + vol.writeFileSync('/tmp/foo.js', writtenContent); + + expect(mockCallback).toBeCalledTimes(2); + expect(mockCallback).toBeCalledWith('change', 'foo.js'); + } finally { + watcher.close(); + } + }); + + it('should handle watching a directory correctly', () => { + const vol = Volume.fromJSON({ '/tmp/foo.js': 'hello test' }); + vol.mkdirSync('/tmp/foo-dir'); + + const mockCallback = jest.fn(); + const writtenContent = 'hello world'; + const watcher = vol.watch('/tmp/foo-dir', mockCallback as any); + + try { + vol.writeFileSync('/tmp/foo-dir/foo.js', writtenContent); + + expect(mockCallback).toBeCalledTimes(1); + expect(mockCallback).toBeCalledWith('rename', 'foo.js'); + } finally { + watcher.close(); + } + }); + it('Calls listener on .watch when renaming with recursive=true', done => { const vol = new Volume(); vol.mkdirSync('/test'); diff --git a/src/volume.ts b/src/volume.ts index 9282003a1..78d7726af 100644 --- a/src/volume.ts +++ b/src/volume.ts @@ -2759,7 +2759,15 @@ export class FSWatcher extends EventEmitter { const watchLinkNodeChanged = (link: Link) => { const filepath = link.getPath(); const node = link.getNode(); - const onNodeChange = () => this.emit('change', 'change', relative(this._filename, filepath)); + const onNodeChange = () => { + let filename = relative(this._filename, filepath); + + if (!filename) { + filename = this._getName(); + } + + return this.emit('change', 'change', filename); + }; node.on('change', onNodeChange); const removers = this._listenerRemovers.get(node.ino) ?? [];