Skip to content

Commit

Permalink
Merge pull request #1 from jrsacks/master
Browse files Browse the repository at this point in the history
Picking up new files
  • Loading branch information
benrady committed May 18, 2011
2 parents 1506de7 + c5fb9d2 commit 4f95c90
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 24 deletions.
54 changes: 30 additions & 24 deletions lib/jezebel/watcher.js
@@ -1,41 +1,47 @@
// Basically stolen from supervisor.js, so there are no tests
// Initially stolen from supervisor.js
// https://github.com/isaacs/node-supervisor

var fs = require('fs');
var utils = require('jezebel/utils');

function watchGivenFile (watch, callback) {
fs.watchFile(watch, {persistent: true, interval: 500}, callback);
function watchDirectory(path, callback, watched) {
fs.readdir(path, function(err, fileNames) {
if(err) {
sys.puts('Error reading path: ' + path);
}
else {
fileNames.forEach(function (fileName) {
if (utils.isInProject(fileName)) {
watchFiles(path + '/' + fileName, callback, watched);
}
});
}
});
}

function watchFiles(path, callback) {
projectFiles = [];
function watchFileOnce(watched, path, callback) {
if(watched.indexOf(path) == -1){
watched.push(path)
fs.watchFile(path, {persistent: true, interval: 500}, callback);
}
}

function watchFiles(path, callback, watched) {
watched = watched || [];
fs.stat(path, function(err, stats){
if (err) {
sys.error('Error retrieving stats for file: ' + path);
} else {
}
else {
if (stats.isDirectory()) {
fs.readdir(path, function(err, fileNames) {
if(err) {
sys.puts('Error reading path: ' + path);
}
else {
fileNames.forEach(function (fileName) {
if (utils.isInProject(fileName)) {
watchFiles(path + '/' + fileName, callback);
}
});
}
});
} else {
watchGivenFile(path, function (curr, prev) {
projectFiles.push(path);
callback(path, curr, prev);
});
watchDirectory(path, callback, watched);
watchFileOnce(watched, path, function() { watchDirectory(path, callback, watched); });
}
else {
watchFileOnce(watched, path, function(curr, prev) { callback(path, curr, prev); });
}
}
});
return projectFiles;
}

exports.watchFiles = watchFiles;
Expand Down
8 changes: 8 additions & 0 deletions spec/spec_helper.js
Expand Up @@ -3,3 +3,11 @@ var path = require('path');
var binDir = path.dirname(fs.realpathSync(__filename));
var lib = path.join(binDir, '../lib');
require.paths.push(lib);

jasmine.Spy.prototype.invokeCallback = function(){
var argsToInvokeWith = arguments;
this.argsForCall.forEach(function(args){
args[args.length -1].apply(this, argsToInvokeWith);
});
this.reset();
};
74 changes: 74 additions & 0 deletions spec/watcher_spec.js
@@ -0,0 +1,74 @@
describe('watcher', function() {
var watcher, fs;

beforeEach(function() {
watcher = require('jezebel/watcher');
fs = require('fs');
spyOn(fs, 'watchFile');
spyOn(fs, 'unwatchFile');
spyOn(fs, 'stat');
spyOn(fs, 'readdir');
});

describe('watching a single file', function() {
var callback;
beforeEach(function() {
callback = jasmine.createSpy('callback');
watcher.watchFiles('filename', callback);
fs.stat.invokeCallback('', {isDirectory : function(){return false;}});
});

it('provides the correct filename and options to watchFile', function() {
expect(fs.watchFile.argsForCall[0][0]).toEqual('filename');
expect(fs.watchFile.argsForCall[0][1]).toEqual({persistent : true, interval : 500});
});

it('curries filename to the callback of watchFile', function() {
fs.watchFile.invokeCallback('curr', 'prev');
expect(callback).toHaveBeenCalledWith('filename', 'curr' , 'prev');
});
});

describe('watching a directory', function() {
beforeEach(function() {
watcher.watchFiles('dirName', function() {});
fs.stat.invokeCallback('', {isDirectory : function(){return true;}});
});

it('calls watchFile on dir and all files in the dir', function() {
fs.readdir.invokeCallback('', ['file0', 'file1']);
fs.stat.invokeCallback('', {isDirectory : function(){return false;}});

expect(fs.watchFile.callCount).toEqual(3);
expect(fs.watchFile.argsForCall[0][0]).toEqual('dirName');
expect(fs.watchFile.argsForCall[1][0]).toEqual('dirName/file0');
expect(fs.watchFile.argsForCall[2][0]).toEqual('dirName/file1');
});

it('detects new files and watches those', function() {
fs.readdir.reset();
fs.watchFile.invokeCallback('');

fs.readdir.invokeCallback('', ['file0']);
fs.stat.invokeCallback('', {isDirectory : function(){return false;}});

expect(fs.watchFile.callCount).toEqual(1);
expect(fs.watchFile.argsForCall[0][0]).toEqual('dirName/file0');
});
});

it('only watches a file once', function() {
watcher.watchFiles('dirName', function() {});
fs.stat.invokeCallback('', {isDirectory : function(){return true;}});
var dirChanged = fs.watchFile.argsForCall[0][2];
fs.readdir.invokeCallback('', ['file0']);

dirChanged();
fs.readdir.invokeCallback('', ['file0']);
fs.stat.invokeCallback('', {isDirectory : function(){return false;}});

expect(fs.watchFile.callCount).toEqual(2);
expect(fs.watchFile.argsForCall[0][0]).toEqual('dirName');
expect(fs.watchFile.argsForCall[1][0]).toEqual('dirName/file0');
});
});

0 comments on commit 4f95c90

Please sign in to comment.