diff --git a/lib/file-list.js b/lib/file-list.js index 1d999459d..954b5c52c 100644 --- a/lib/file-list.js +++ b/lib/file-list.js @@ -271,14 +271,16 @@ var List = function(patterns, excludes, emitter, preprocess, batchInterval) { return done(); } + var addedFile = new File(path); + buckets[i].push(addedFile); + return fs.stat(path, function(err, stat) { // in the case someone refresh() the list before stat callback if (self.buckets === buckets) { + addedFile.mtime = stat.mtime; - var file = new File(path, stat.mtime); - return preprocess(file, function() { + return preprocess(addedFile, function() { // TODO(vojta): ignore if refresh/reload happens - buckets[i].push(file); log.info('Added file "%s".', path); fireEventAndDefer(); done(); diff --git a/test/unit/file-list.spec.coffee b/test/unit/file-list.spec.coffee index 37f382518..e51cffe49 100644 --- a/test/unit/file-list.spec.coffee +++ b/test/unit/file-list.spec.coffee @@ -296,6 +296,30 @@ describe 'file-list', -> done() + it 'should ignore very quick double "add"', (done) -> + # On linux fs.watch (chokidar with usePolling: false) fires "add" event twice. + # This checks that we only stat and preprocess the file once. + + sinon.spy mockFs, 'stat' + list = new m.List patterns('/a.*'), [], emitter, preprocessMock + + pending = 2 + finish = -> + pending-- + if pending is 0 + expect(preprocessMock).to.have.been.calledOnce + expect(mockFs.stat).to.have.been.calledOnce + done() + + refreshListAndThen (files) -> + preprocessMock.reset() + mockFs.stat.reset() + + list.addFile '/a.js', finish + # fire again, before the stat gets back + list.addFile '/a.js', finish + + it 'should set proper mtime of new file', (done) -> list = new m.List patterns('/a.*'), [], emitter, preprocessMock