diff --git a/README.md b/README.md index 61e72bc..34b3b6d 100644 --- a/README.md +++ b/README.md @@ -388,6 +388,7 @@ const fs = new Filer.FileSystem(options, callback); * [fs.removexattr(path, name, callback)](#removexattr) * [fs.fremovexattr(fd, name, callback)](#fremovexattr) * [fs.watch(filename, [options], [listener])](#watch) +* [fs.watchFile(filename, [options], [listener])](#watchFile) #### fs.rename(oldPath, newPath, callback) @@ -1323,6 +1324,24 @@ var watcher = fs.watch('/data', { recursive: true }, function(event, filename) { fs.writeFile('/data/subdir/file', 'data'); ``` +### fs.watchFile(filename, [options], [listener]) + +Watch for changes on a file at `filename`. The callback `listener` will be called each time the file is accessed. + +The `options` argument only supports the change in interval between checks measured in milliseconds and does not support perstistence like node. + +The `listener` receives two arguments that are the current stat object and previous stat object that are instances of `fs.Stat`. Reference to `fs.Stat` can be found +here: [`fs.Stat`](https://nodejs.org/api/fs.html#fs_class_fs_stats) + +Example: +```javascript +fs.watchFile('/myfile.txt', (curr, prev) => { + console.log(`the current mtime is: ${curr.mtime}`); + console.log(`the previous mtime was: ${prev.mtime}`); +}); +``` + + ### FileSystemShell Many common file system shell operations are available by using a `FileSystemShell` object. diff --git a/src/filesystem/interface.js b/src/filesystem/interface.js index 1a99963..859e9ad 100644 --- a/src/filesystem/interface.js +++ b/src/filesystem/interface.js @@ -226,15 +226,16 @@ function FileSystem(options, callback) { let intervalValue = statWatchers.get(filename); - // Checks to see if there's a pre-existing watcher on the file - if (intervalValue === undefined) { - // Stores initial prev value to compare + if(intervalValue) { + return; + } + else { fs.stat(filename, function (err, stats) { var value = setInterval(function () { prevStat = currStat; //Conditional check for first run to set initial state for prevStat - if(prevStat === undefined) { + if(!prevStat) { prevStat = stats; } @@ -242,21 +243,21 @@ function FileSystem(options, callback) { if (err) { clearInterval(value); - console.warn('[Filer Error] fs.watchFile encountered an error: ' + err); + console.warn('[Filer Error] fs.watchFile encountered an error' + err.message); } if (JSON.stringify(prevStat) !== JSON.stringify(currStat)) { listener(prevStat, currStat); } // Set a new prevStat based on previous prevStat = currStat; - }, + }, interval ); // Stores interval return values statWatchers.set(filename, value); }); - } + } }; // Deal with various approaches to node ID creation diff --git a/tests/spec/fs.watchFile.spec.js b/tests/spec/fs.watchFile.spec.js index d54c55f..2a59a2c 100644 --- a/tests/spec/fs.watchFile.spec.js +++ b/tests/spec/fs.watchFile.spec.js @@ -19,7 +19,25 @@ describe('fs.watchFile', function() { expect(fn).to.throw(); }); - it('prev and curr should be populated', function() { + it('should throw an error if a file is deleted', function() { + const fs = util.fs(); + + fs.writeFile('/myfile', 'data', function(error) { + if(error) throw error; + }); + + fs.watchFile('/myfile', function(prev, curr) { + expect(prev).to.exist; + expect(curr).to.exist; + }); + + fs.unlink('/myfile'); + + const fn = () => fs.watchFile('/myfile'); + expect(fn).to.throw(); + }); + + it('prev and curr should be equal if nothing has been changed in the file', function() { const fs = util.fs(); fs.writeFile('/myfile', 'data', function(error) { @@ -27,8 +45,25 @@ describe('fs.watchFile', function() { }); fs.watchFile('/myfile', function(prev, curr) { - expect(prev).to.exist; - expect(curr).to.exist; + expect(prev).to.equal(curr); + }); + }); + + it('prev and curr should not be equal if something has been changed in the file', function() { + const fs = util.fs(); + + fs.writeFile('/myfile', 'data', function(error) { + if(error) throw error; + }); + + fs.watchFile('/myfile', function(prev, curr) { + expect(prev).to.equal(curr); + + fs.writeFile('/myfile', 'data2', function(error) { + if(error) throw error; + }); + + expect(prev).to.not.equal(curr); }); }); }); \ No newline at end of file