First passing tests for fs.watch(), use EventEmitter2 via bower
This commit is contained in:
parent
799a7ae4b1
commit
a365144e97
|
@ -2,6 +2,9 @@
|
||||||
"name": "filer",
|
"name": "filer",
|
||||||
"version": "0.0.4",
|
"version": "0.0.4",
|
||||||
"main": "dist/filer.js",
|
"main": "dist/filer.js",
|
||||||
|
"dependencies": {
|
||||||
|
"eventemitter2": "~0.4.13"
|
||||||
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"mocha": "1.17.1",
|
"mocha": "1.17.1",
|
||||||
"chai": "1.9.0"
|
"chai": "1.9.0"
|
||||||
|
|
|
@ -45,7 +45,8 @@ module.exports = function(grunt) {
|
||||||
options: {
|
options: {
|
||||||
paths: {
|
paths: {
|
||||||
"src": "../src",
|
"src": "../src",
|
||||||
"build": "../build"
|
"build": "../build",
|
||||||
|
"EventEmitter": "../bower_components/eventemitter2/lib/eventemitter2"
|
||||||
},
|
},
|
||||||
baseUrl: "lib",
|
baseUrl: "lib",
|
||||||
name: "build/almond",
|
name: "build/almond",
|
||||||
|
|
|
@ -1,66 +0,0 @@
|
||||||
define(function(require) {
|
|
||||||
|
|
||||||
// Based on https://github.com/diy/intercom.js/blob/master/lib/events.js
|
|
||||||
// Copyright 2012 DIY Co Apache License, Version 2.0
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
function removeItem(item, array) {
|
|
||||||
for (var i = array.length - 1; i >= 0; i--) {
|
|
||||||
if (array[i] === item) {
|
|
||||||
array.splice(i, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return array;
|
|
||||||
}
|
|
||||||
|
|
||||||
function EventEmitter() {}
|
|
||||||
|
|
||||||
EventEmitter.createInterface = function(space) {
|
|
||||||
var methods = {};
|
|
||||||
|
|
||||||
methods.on = function(name, fn) {
|
|
||||||
if (typeof this[space] === 'undefined') {
|
|
||||||
this[space] = {};
|
|
||||||
}
|
|
||||||
if (!this[space].hasOwnProperty(name)) {
|
|
||||||
this[space][name] = [];
|
|
||||||
}
|
|
||||||
this[space][name].push(fn);
|
|
||||||
};
|
|
||||||
|
|
||||||
methods.off = function(name, fn) {
|
|
||||||
if (typeof this[space] === 'undefined') return;
|
|
||||||
if (this[space].hasOwnProperty(name)) {
|
|
||||||
removeItem(fn, this[space][name]);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
methods.trigger = function(name) {
|
|
||||||
if (typeof this[space] !== 'undefined' && this[space].hasOwnProperty(name)) {
|
|
||||||
var args = Array.prototype.slice.call(arguments, 1);
|
|
||||||
for (var i = 0; i < this[space][name].length; i++) {
|
|
||||||
this[space][name][i].apply(this[space][name][i], args);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return methods;
|
|
||||||
};
|
|
||||||
|
|
||||||
var pvt = EventEmitter.createInterface('_handlers');
|
|
||||||
EventEmitter.prototype._on = pvt.on;
|
|
||||||
EventEmitter.prototype._off = pvt.off;
|
|
||||||
EventEmitter.prototype._trigger = pvt.trigger;
|
|
||||||
|
|
||||||
var pub = EventEmitter.createInterface('handlers');
|
|
||||||
EventEmitter.prototype.on = function() {
|
|
||||||
pub.on.apply(this, arguments);
|
|
||||||
Array.prototype.unshift.call(arguments, 'on');
|
|
||||||
this._trigger.apply(this, arguments);
|
|
||||||
};
|
|
||||||
EventEmitter.prototype.off = pub.off;
|
|
||||||
EventEmitter.prototype.trigger = pub.trigger;
|
|
||||||
|
|
||||||
return EventEmitter;
|
|
||||||
|
|
||||||
});
|
|
|
@ -4,7 +4,7 @@ define(function(require) {
|
||||||
// Copyright 2012 DIY Co Apache License, Version 2.0
|
// Copyright 2012 DIY Co Apache License, Version 2.0
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
var EventEmitter = require('eventemitter');
|
var EventEmitter = require('EventEmitter');
|
||||||
var guid = require('src/shared').guid;
|
var guid = require('src/shared').guid;
|
||||||
|
|
||||||
function throttle(delay, fn) {
|
function throttle(delay, fn) {
|
||||||
|
|
65
src/fs.js
65
src/fs.js
|
@ -59,6 +59,7 @@ define(function(require) {
|
||||||
var adapters = require('src/adapters/adapters');
|
var adapters = require('src/adapters/adapters');
|
||||||
var Shell = require('src/shell');
|
var Shell = require('src/shell');
|
||||||
var Intercom = require('intercom');
|
var Intercom = require('intercom');
|
||||||
|
var EventEmitter = require('EventEmitter');
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* DirectoryEntry
|
* DirectoryEntry
|
||||||
|
@ -1551,6 +1552,45 @@ define(function(require) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* FSWatcher based loosely on node.js' FSWatcher
|
||||||
|
* see https://github.com/joyent/node/blob/master/lib/fs.js
|
||||||
|
*/
|
||||||
|
function FSWatcher() {
|
||||||
|
EventEmitter.call(this);
|
||||||
|
var self = this;
|
||||||
|
var recursive = false;
|
||||||
|
var filename;
|
||||||
|
|
||||||
|
function onchange(path) {
|
||||||
|
// Watch for exact filename, or parent path when recursive is true
|
||||||
|
if(filename === path || (recursive && filename.indexOf(path + '/') === 0)) {
|
||||||
|
self.emit('change', filename);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// We support, but ignore the second arg, which node.js uses.
|
||||||
|
self.start = function(filename_, persistent_, recursive_) {
|
||||||
|
if(isNullPath(filename)) {
|
||||||
|
throw new Error('Path must be a string without null bytes.');
|
||||||
|
}
|
||||||
|
recursive = recursive_ === true;
|
||||||
|
// TODO: get realpath for symlinks on filename...
|
||||||
|
filename = filename_;
|
||||||
|
|
||||||
|
var intercom = Intercom.getInstance();
|
||||||
|
intercom.on('change', onchange);
|
||||||
|
};
|
||||||
|
|
||||||
|
self.close = function() {
|
||||||
|
var intercom = Intercom.getInstance();
|
||||||
|
intercom.off('change', onchange);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
FSWatcher.prototype = new EventEmitter();
|
||||||
|
FSWatcher.prototype.constructor = FSWatcher;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FileSystem
|
* FileSystem
|
||||||
*
|
*
|
||||||
|
@ -1628,12 +1668,31 @@ define(function(require) {
|
||||||
queue = null;
|
queue = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FileSystem watch events are broadcast between windows via intercom
|
||||||
|
var intercom = Intercom.getInstance();
|
||||||
|
|
||||||
|
// We support the optional `options` arg from node, but ignore it
|
||||||
|
this.watch = function(filename, options, listener) {
|
||||||
|
if(isNullPath(filename)) {
|
||||||
|
throw new Error('Path must be a string without null bytes.');
|
||||||
|
}
|
||||||
|
if(typeof options === 'function') {
|
||||||
|
listener = options;
|
||||||
|
options = {};
|
||||||
|
}
|
||||||
|
options = options || {};
|
||||||
|
listener = listener || nop;
|
||||||
|
|
||||||
|
var watcher = new FSWatcher();
|
||||||
|
watcher.start(filename, false, options.recursive);
|
||||||
|
watcher.addListener('change', listener);
|
||||||
|
|
||||||
|
return watcher;
|
||||||
|
};
|
||||||
|
|
||||||
// Open file system storage provider
|
// Open file system storage provider
|
||||||
provider.open(function(err, needsFormatting) {
|
provider.open(function(err, needsFormatting) {
|
||||||
function complete(error) {
|
function complete(error) {
|
||||||
// FileSystem watch events are broadcast between windows via intercom
|
|
||||||
var intercom = Intercom.getInstance();
|
|
||||||
|
|
||||||
// Wrap the provider so we can extend the context with fs flags, intercom.
|
// Wrap the provider so we can extend the context with fs flags, intercom.
|
||||||
// From this point forward we won't call open again, so drop it.
|
// From this point forward we won't call open again, so drop it.
|
||||||
fs.provider = {
|
fs.provider = {
|
||||||
|
|
|
@ -58,7 +58,8 @@ var config = (function() {
|
||||||
"spec": "../tests/spec",
|
"spec": "../tests/spec",
|
||||||
"bugs": "../tests/bugs",
|
"bugs": "../tests/bugs",
|
||||||
"util": "../tests/lib/test-utils",
|
"util": "../tests/lib/test-utils",
|
||||||
"Filer": "../src/index"
|
"Filer": "../src/index",
|
||||||
|
"EventEmitter": "../bower_components/eventemitter2/lib/eventemitter2"
|
||||||
},
|
},
|
||||||
baseUrl: "../lib",
|
baseUrl: "../lib",
|
||||||
optimize: "none",
|
optimize: "none",
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
define(["Filer", "util"], function(Filer, util) {
|
||||||
|
|
||||||
|
describe('fs.watch', function() {
|
||||||
|
beforeEach(util.setup);
|
||||||
|
afterEach(util.cleanup);
|
||||||
|
|
||||||
|
it('should be a function', function() {
|
||||||
|
var fs = util.fs();
|
||||||
|
expect(typeof fs.watch).to.equal('function');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should get a change event when writing a file', function(done) {
|
||||||
|
var fs = util.fs();
|
||||||
|
|
||||||
|
fs.watch('/myfile', function(filename) {
|
||||||
|
expect(filename).to.equal('/myfile');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
|
||||||
|
fs.writeFile('/myfile', 'data', function(error) {
|
||||||
|
if(error) throw error;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should get a change event when writing a file in a dir with recursive=true', function(done) {
|
||||||
|
var fs = util.fs();
|
||||||
|
|
||||||
|
fs.watch('/', { recursive: true }, function(filename) {
|
||||||
|
expect(filename).to.equal('/');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
|
||||||
|
fs.writeFile('/myfile', 'data', function(error) {
|
||||||
|
if(error) throw error;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
|
@ -34,6 +34,7 @@ define([
|
||||||
"spec/path-resolution.spec",
|
"spec/path-resolution.spec",
|
||||||
"spec/times.spec",
|
"spec/times.spec",
|
||||||
"spec/time-flags.spec",
|
"spec/time-flags.spec",
|
||||||
|
"spec/fs.watch.spec",
|
||||||
|
|
||||||
// Filer.FileSystem.providers.*
|
// Filer.FileSystem.providers.*
|
||||||
"spec/providers/providers.spec",
|
"spec/providers/providers.spec",
|
||||||
|
|
Loading…
Reference in New Issue