From 1f1042798589594cd973bd22b92da345f409637e Mon Sep 17 00:00:00 2001 From: Peter Flynn Date: Wed, 22 Jan 2014 18:01:28 -0800 Subject: [PATCH] Unit test for bug #6609 (Fast file replacement operations can be missed) Enhance MockFileSystemImpl to allow artificially delaying watcher notifications in addition to delaying normal callbacks. --- test/spec/FileSystem-test.js | 40 +++++++++++++++++++++++++++++++++ test/spec/MockFileSystemImpl.js | 6 +++-- 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/test/spec/FileSystem-test.js b/test/spec/FileSystem-test.js index 7c045c4454b..99b05a2fefe 100644 --- a/test/spec/FileSystem-test.js +++ b/test/spec/FileSystem-test.js @@ -1311,6 +1311,8 @@ define(function (require, exports, module) { }); }); }); + + describe("External change events", function () { var _model, changedEntry, @@ -1454,6 +1456,44 @@ define(function (require, exports, module) { expect(removedEntries[0]).toBe(oldfile); }); }); + + it("should fire change event after rapid delete-add pair", function () { + var dirname = "/subdir/", + filename = "/subdir/file3.txt", + dir, + newfile; + + runs(function () { + // Delay watcher change notifications so that the FS doesn't get a chance to + // read the directory contents in between the deletion and the re-creation + MockFileSystemImpl.when("change", "/subdir/", delay(100)); + + dir = fileSystem.getDirectoryForPath(dirname); + + dir.getContents(function () { + _model.unlink(filename); + }); + + // Normally we'd get a change event here, but due to our delay the FS doesn't + // know of the change yet and thus has no reason to trigger an event + expect(changeDone).toBe(false); + + dir.getContents(function () { + _model.writeFile(filename, "new file content"); + }); + }); + + waitsFor(function () { return changeDone; }, "external change event"); + + runs(function () { + // We should still receive a change event, but the dir-contents diff shows no changes + // since it didn't happen in between the delete and the create - so we expect the added + // & removed lists to both be empty. + expect(changedEntry).toBe(dir); + expect(addedEntries.length).toBe(0); + expect(removedEntries.length).toBe(0); + }); + }); }); }); }); diff --git a/test/spec/MockFileSystemImpl.js b/test/spec/MockFileSystemImpl.js index 55b7e8f37d8..5cfae685643 100644 --- a/test/spec/MockFileSystemImpl.js +++ b/test/spec/MockFileSystemImpl.js @@ -229,7 +229,8 @@ define(function (require, exports, module) { $(_model).on("change", function (event, path) { if (_changeCallback) { - _changeCallback(path, _model.stat(path)); + var cb = _getCallback("change", path, _changeCallback); + cb(path, _model.stat(path)); } }); @@ -252,7 +253,8 @@ define(function (require, exports, module) { * Add callback hooks to be used when specific methods are called with a * specific path. * - * @param {string} method The name of the method + * @param {string} method The name of the method. The special name "change" + * may be used to hook the "change" event handler as well. * @param {string} path The path that must be matched * @param {function} getCallback A function that has one parameter and * must return a callback function.