diff --git a/spec/pathwatcher-spec.js b/spec/pathwatcher-spec.js index bd62589..05f45b0 100644 --- a/spec/pathwatcher-spec.js +++ b/spec/pathwatcher-spec.js @@ -19,6 +19,29 @@ describe('PathWatcher', () => { await wait(100); }); + describe('when a watched file is replaced via atomic save', () => { + it('fires the callback with a change event', async () => { + let eventType; + let eventPath; + + PathWatcher.watch(tempFile, (type, path) => { + eventType = type; + eventPath = path; + }); + + await wait(20); + + let tempFileCopy = path.join(tempDir, 'file-copy'); + fs.writeFileSync(tempFileCopy, 'atomic save content'); + fs.renameSync(tempFileCopy, tempFile); + + await condition(() => !!eventType); + + expect(eventType).toBe('change'); + expect(eventPath).toBe(''); + }); + }); + describe('getWatchedPaths', () => { it('returns an array of all watched paths', () => { let realTempFilePath = fs.realpathSync(tempFile); diff --git a/src/main.js b/src/main.js index 9e77527..feac44c 100644 --- a/src/main.js +++ b/src/main.js @@ -520,7 +520,12 @@ class PathWatcher { let isSameDirectory = !this.isWatchingParent && path.dirname(event.path) == path.dirname(event.oldPath); - if ((oldWatched && newWatched) || isSameDirectory) { + if (eventPathIsEqual && !eventOldPathIsEqual) { + // Atomic save: some other file was renamed into our watched path. + // The new path _is_ the watched file, but the old path was not. + newEvent.action = 'change'; + newEvent.path = ''; + } else if ((oldWatched && newWatched) || isSameDirectory) { // We can keep tabs on both file paths from here, so this will // be treated as a rename. newEvent.action = 'rename';