diff --git a/lib/DirectoryWatcher.js b/lib/DirectoryWatcher.js index abbb142..1030fd2 100644 --- a/lib/DirectoryWatcher.js +++ b/lib/DirectoryWatcher.js @@ -738,7 +738,27 @@ class DirectoryWatcher extends EventEmitter { for (const watcher of watchers) { const path = watcher.path; if (!fileTimestamps.has(path)) { - fileTimestamps.set(path, null); + // If the file does not exist, we'll mark it as null, + // but beforehand we check if the same file with different + // casing exists in the map. + + // This can happen because the `this.files` map is case-sensitive. + let lowercase = withoutCase(path); + if (this.filesWithoutCase.has(lowercase)) { + const keys = fileTimestamps.keys(); + let nextKey = null; + while (!(nextKey = keys.next()).done) { + if (nextKey.value.toLowerCase() === lowercase) { + fileTimestamps.set(path, fileTimestamps.get(nextKey.value)); + break; + } + } + } + + // If no file with different casing was found, we'll mark it as null + if (!fileTimestamps.has(path)) { + fileTimestamps.set(path, null); + } } } } diff --git a/test/DirectoryWatcher.js b/test/DirectoryWatcher.js index 8b8072d..b6b60cc 100644 --- a/test/DirectoryWatcher.js +++ b/test/DirectoryWatcher.js @@ -12,6 +12,15 @@ var testHelper = new TestHelper(fixtures); var openWatchers = []; +var fsIsCaseInsensitive; +try { + fsIsCaseInsensitive = require("fs").existsSync( + path.join(__dirname, "..", "PACKAGE.JSON") + ); +} catch (e) { + fsIsCaseInsensitive = false; +} + var DirectoryWatcher = function(p, options) { var d = new OrgDirectoryWatcher(getWatcherManager(options), p, options); openWatchers.push(d); @@ -169,6 +178,34 @@ describe("DirectoryWatcher", function() { }); }); + if (fsIsCaseInsensitive) { + it("should collectTimeInfoEntries for uppercase and lowercase filename", function(done) { + testHelper.file("A"); + var d = new DirectoryWatcher(fixtures, {}); + var a = d.watch(path.join(fixtures, "a")); + + let filenameTimestamps = new Map(); + let directoryTimestamps = new Map(); + testHelper.tick(function() { + d.collectTimeInfoEntries(filenameTimestamps, directoryTimestamps); + let lowercase = filenameTimestamps.get( + path.join(testHelper.testdir, "a") + ); + let uppercase = filenameTimestamps.get( + path.join(testHelper.testdir, "A") + ); + if (!lowercase) { + throw new Error("should have timeInfoEntries for lowercase"); + } + if (!uppercase) { + throw new Error("should have timeInfoEntries for uppercase"); + } + a.close(); + done(); + }); + }); + } + if (!+process.env.WATCHPACK_POLLING) { it("should log errors emitted from watcher to stderr", function(done) { var error_logged = false;