Skip to content

Commit f0facd2

Browse files
Christopher HillerJoshua Appelman
authored andcommitted
resolves #1223: fix interaction with symbolic links
- symbolic links are followed if they are not broken - move `lookupFiles()` into `utils` module - add some tests for the symbolic link stuff - build
1 parent 340cb56 commit f0facd2

File tree

4 files changed

+125
-37
lines changed

4 files changed

+125
-37
lines changed

bin/_mocha

Lines changed: 1 addition & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -284,8 +284,6 @@ program.compilers.forEach(function(c) {
284284
extensions.push(ext);
285285
});
286286

287-
var re = new RegExp('\\.(' + extensions.join('|') + ')$');
288-
289287
// requires
290288

291289
requires.forEach(function(mod) {
@@ -302,7 +300,7 @@ var files = []
302300
if (!args.length) args.push('test');
303301

304302
args.forEach(function(arg){
305-
files = files.concat(lookupFiles(arg, program.recursive));
303+
files = files.concat(utils.lookupFiles(arg, extensions, program.recursive));
306304
});
307305

308306
// resolve
@@ -439,40 +437,6 @@ function stop() {
439437
clearInterval(play.timer);
440438
}
441439

442-
/**
443-
* Lookup file names at the given `path`.
444-
*/
445-
446-
function lookupFiles(path, recursive) {
447-
var files = [];
448-
449-
if (!exists(path)) {
450-
if (exists(path + '.js')) {
451-
path += '.js'
452-
} else {
453-
files = glob.sync(path);
454-
if (!files.length) throw new Error("cannot resolve path (or pattern) '" + path + "'");
455-
return files;
456-
}
457-
}
458-
459-
var stat = fs.statSync(path);
460-
if (stat.isFile()) return path;
461-
462-
fs.readdirSync(path).forEach(function(file){
463-
file = join(path, file);
464-
var stat = fs.statSync(file);
465-
if (stat.isDirectory()) {
466-
if (recursive) files = files.concat(lookupFiles(file, recursive));
467-
return
468-
}
469-
if (!stat.isFile() || !re.test(file) || basename(file)[0] == '.') return;
470-
files.push(file);
471-
});
472-
473-
return files;
474-
}
475-
476440
/**
477441
* Play the given array of strings.
478442
*/

lib/utils.js

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44

55
var fs = require('fs')
66
, path = require('path')
7+
, basename = path.basename
8+
, exists = fs.existsSync || path.existsSync
9+
, glob = require('glob')
710
, join = path.join
811
, debug = require('debug')('mocha:watch');
912

@@ -348,3 +351,49 @@ exports.canonicalize = function(obj, stack) {
348351

349352
return canonicalizedObj;
350353
}
354+
355+
/**
356+
* Lookup file names at the given `path`.
357+
*/
358+
exports.lookupFiles = function lookupFiles(path, extensions, recursive) {
359+
var files = [];
360+
var re = new RegExp('\\.(' + extensions.join('|') + ')$');
361+
362+
if (!exists(path)) {
363+
if (exists(path + '.js')) {
364+
path += '.js';
365+
} else {
366+
files = glob.sync(path);
367+
if (!files.length) throw new Error("cannot resolve path (or pattern) '" + path + "'");
368+
return files;
369+
}
370+
}
371+
372+
try {
373+
var stat = fs.statSync(path);
374+
if (stat.isFile()) return path;
375+
}
376+
catch (ignored) {
377+
return;
378+
}
379+
380+
fs.readdirSync(path).forEach(function(file){
381+
file = join(path, file);
382+
try {
383+
var stat = fs.statSync(file);
384+
if (stat.isDirectory()) {
385+
if (recursive) {
386+
files = files.concat(lookupFiles(file, recursive));
387+
}
388+
return;
389+
}
390+
}
391+
catch (ignored) {
392+
return;
393+
}
394+
if (!stat.isFile() || !re.test(file) || basename(file)[0] === '.') return;
395+
files.push(file);
396+
});
397+
398+
return files;
399+
}

mocha.js

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5498,6 +5498,9 @@ require.register("utils.js", function(module, exports, require){
54985498

54995499
var fs = require('browser/fs')
55005500
, path = require('browser/path')
5501+
, basename = path.basename
5502+
, exists = fs.existsSync || path.existsSync
5503+
, glob = require('glob')
55015504
, join = path.join
55025505
, debug = require('browser/debug')('mocha:watch');
55035506

@@ -5843,6 +5846,52 @@ exports.canonicalize = function(obj, stack) {
58435846
return canonicalizedObj;
58445847
}
58455848

5849+
/**
5850+
* Lookup file names at the given `path`.
5851+
*/
5852+
exports.lookupFiles = function lookupFiles(path, extensions, recursive) {
5853+
var files = [];
5854+
var re = new RegExp('\\.(' + extensions.join('|') + ')$');
5855+
5856+
if (!exists(path)) {
5857+
if (exists(path + '.js')) {
5858+
path += '.js';
5859+
} else {
5860+
files = glob.sync(path);
5861+
if (!files.length) throw new Error("cannot resolve path (or pattern) '" + path + "'");
5862+
return files;
5863+
}
5864+
}
5865+
5866+
try {
5867+
var stat = fs.statSync(path);
5868+
if (stat.isFile()) return path;
5869+
}
5870+
catch (ignored) {
5871+
return;
5872+
}
5873+
5874+
fs.readdirSync(path).forEach(function(file){
5875+
file = join(path, file);
5876+
try {
5877+
var stat = fs.statSync(file);
5878+
if (stat.isDirectory()) {
5879+
if (recursive) {
5880+
files = files.concat(lookupFiles(file, recursive));
5881+
}
5882+
return;
5883+
}
5884+
}
5885+
catch (ignored) {
5886+
return;
5887+
}
5888+
if (!stat.isFile() || !re.test(file) || basename(file)[0] === '.') return;
5889+
files.push(file);
5890+
});
5891+
5892+
return files;
5893+
}
5894+
58465895
}); // module: utils.js
58475896
// The global object is "self" in Web Workers.
58485897
var global = (function() { return this; })();

test/acceptance/utils.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,4 +86,30 @@ describe('lib/utils', function () {
8686
utils.stringify(travis).should.equal('{\n "name": "travis"\n "whoami": "[Circular]"\n}');
8787
});
8888
});
89+
90+
describe('lookupFiles', function () {
91+
var fs = require('fs');
92+
93+
beforeEach(function () {
94+
fs.writeFileSync('/tmp/mocha-utils.js', 'yippy skippy ying yang yow');
95+
fs.symlinkSync('/tmp/mocha-utils.js', '/tmp/mocha-utils-link.js');
96+
});
97+
98+
it('should not choke on symlinks', function () {
99+
utils.lookupFiles('/tmp', ['js'], false).should.eql(['/tmp/mocha-utils-link.js', '/tmp/mocha-utils.js']);
100+
fs.existsSync('/tmp/mocha-utils-link.js').should.be.true;
101+
fs.rename('/tmp/mocha-utils.js', '/tmp/bob');
102+
fs.existsSync('/tmp/mocha-utils-link.js').should.be.true;
103+
utils.lookupFiles('/tmp', ['js'], false).should.eql([]);
104+
});
105+
106+
afterEach(function () {
107+
['/tmp/mocha-utils.js', '/tmp/mocha-utils-link.js', '/tmp/bob'].forEach(function (path) {
108+
try {
109+
fs.unlinkSync(path);
110+
}
111+
catch (ignored) {}
112+
});
113+
})
114+
});
89115
});

0 commit comments

Comments
 (0)