diff --git a/src/providers/memory.js b/src/providers/memory.js index 171da97..32a229d 100644 --- a/src/providers/memory.js +++ b/src/providers/memory.js @@ -1,5 +1,7 @@ var FILE_SYSTEM_NAME = require('../constants.js').FILE_SYSTEM_NAME; -var asyncCallback = require('../../lib/async.js').nextTick; +// NOTE: prefer setImmediate to nextTick for proper recursion yielding. +// see https://github.com/js-platform/filer/pull/24 +var asyncCallback = require('../../lib/async.js').setImmediate; /** * Make shared in-memory DBs possible when using the same name. diff --git a/src/shell/shell.js b/src/shell/shell.js index 648b2fa..987d6c9 100644 --- a/src/shell/shell.js +++ b/src/shell/shell.js @@ -255,7 +255,7 @@ Shell.prototype.ls = function(dir, options, callback) { }); } - async.each(entries, getDirEntry, function(error) { + async.eachSeries(entries, getDirEntry, function(error) { callback(error, result); }); }); @@ -323,7 +323,7 @@ Shell.prototype.rm = function(path, options, callback) { // Root dir entries absolutely return Path.join(pathname, filename); }); - async.each(entries, remove, function(error) { + async.eachSeries(entries, remove, function(error) { if(error) { callback(error); return; diff --git a/tests/bugs/ls-depth-bug.js b/tests/bugs/ls-depth-bug.js index a5a5f5c..3fa834b 100644 --- a/tests/bugs/ls-depth-bug.js +++ b/tests/bugs/ls-depth-bug.js @@ -1,6 +1,7 @@ var Filer = require('../..'); var util = require('../lib/test-utils.js'); var expect = require('chai').expect; +var async = require('../../lib/async.js'); describe('sh.ls and deep directory trees', function() { beforeEach(util.setup); @@ -10,10 +11,10 @@ describe('sh.ls and deep directory trees', function() { var fs = util.fs(); var sh = fs.Shell(); - // The specific depth at which this will fail is based on the depth - // of the call stack, since sh.ls() is recursive, so it can be less - // than this in some cases, but this should trigger it in *this* case. - var path = '/1/2/3/4/5/6/7/8/9/10/11/12/13/14/15/16/17/18/19/20'; + var path = ''; + for(var i=0; i<50; i++) { + path += '/' + i; + } sh.mkdirp(path, function(err) { if(err) throw err; @@ -25,4 +26,34 @@ describe('sh.ls and deep directory trees', function() { }); }); }); + + it('should not crash when calling sh.ls() on wide directory layouts', function(done) { + var fs = util.fs(); + var sh = fs.Shell(); + + var dirName = '/dir'; + + fs.mkdir(dirName, function(err) { + if(err) throw err; + + var paths = []; + for(var i=0; i<100; i++) { + paths.push(Filer.Path.join(dirName, ''+i)); + } + + function writeFile(path, callback) { + fs.writeFile(path, 'data', callback); + } + + async.eachSeries(paths, writeFile, function(err) { + if(err) { console.log('error', err); throw err; } + + sh.ls('/', {recursive: true}, function(err, listing) { + expect(err).not.to.exist; + expect(listing).to.exist; + done(); + }); + }); + }); + }); });