Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
module.exports = {
"env": {
"es6": true,
"node": true
},
"extends": "eslint:recommended",
"globals": {
"Atomics": "readonly",
"SharedArrayBuffer": "readonly"
},
"parserOptions": {
"ecmaVersion": 2018,
"sourceType": "module"
},
"rules": {
}
};
6 changes: 6 additions & 0 deletions .prettierrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"arrowParens": "always",
"trailingComma": "all",
"singleQuote": true,
"htmlWhitespaceSensitivity": "ignore"
}
46 changes: 25 additions & 21 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,27 +12,31 @@ function resolvePkg(name, basedir) {

var filename = path.resolve(basedir, 'node_modules', name, 'package.json');
debug('%s: %s', name, filename);
return fs.stat(filename).then(function (stat) {
if (stat.isFile()) {
return path.dirname(filename);
}
}).catch(function (error) {
debug('%s: not found on %s (root? %s)', name, basedir, isRoot(basedir));
if (isRoot(basedir)) {
debug('at root');
error = new Error('package not found ' + name);
error.code = 'NO_PACKAGE_FOUND';
throw error;
}
}).then(function (dir) {
if (dir) {
debug('%s: FOUND AT %s', name, dir);
return dir;
}
return fs
.stat(filename)
.then(function(stat) {
if (stat.isFile()) {
return path.dirname(filename);
}
})
.catch(function(error) {
debug('%s: not found on %s (root? %s)', name, basedir, isRoot(basedir));
if (isRoot(basedir)) {
debug('at root');
error = new Error('package not found ' + name);
error.code = 'NO_PACKAGE_FOUND';
throw error;
}
})
.then(function(dir) {
if (dir) {
debug('%s: FOUND AT %s', name, dir);
return dir;
}

debug('%s: cycling down', name);
return resolvePkg(name, path.resolve(basedir, '..'));
});
debug('%s: cycling down', name);
return resolvePkg(name, path.resolve(basedir, '..'));
});
}

function sync(name, basedir) {
Expand All @@ -43,7 +47,7 @@ function sync(name, basedir) {
var filename = path.resolve(basedir, 'node_modules', name, 'package.json');
debug('%s: %s', name, filename);

var isFile = function (file) {
var isFile = function(file) {
var stat;
try {
stat = fs.statSync(file);
Expand Down
12 changes: 7 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
"test": "test"
},
"scripts": {
"lint": "jscs lib/*.js -v",
"format": "prettier --write lib/*.?s test/*.?s",
"lint": "eslint lib/*.js test/*.?s",
"test": "npm run lint && tap test/*.test.js --cov --timeout=60"
},
"keywords": [
Expand All @@ -19,11 +20,12 @@
"then-fs": "^2.0.0"
},
"devDependencies": {
"es6-promise": "^4.2.8",
"jscs": "^3.0.7",
"eslint": "^6.5.1",
"eslint-config-prettier": "^6.4.0",
"prettier": "^1.18.2",
"proxyquire": "^2.1.3",
"tap": "^12.7.0",
"tape": "^4.11.0"
"semantic-release": "^15.13.24",
"tap": "^12.7.0"
},
"repository": {
"type": "git",
Expand Down
153 changes: 88 additions & 65 deletions test/index.test.js
Original file line number Diff line number Diff line change
@@ -1,77 +1,88 @@
var test = require('tap').test;
var proxyquire = require('proxyquire');
var Promise = require('es6-promise').Promise; // jshint ignore:line
var path = require('path');

var False = function () { return false; };
var True = function () { return true; };
var False = function() {
return false;
};
var True = function() {
return true;
};
var suceed = False;

var fs = {
statSync: function (filename) {
statSync: function(filename) {
return {
isFile: function () {
isFile: function() {
return suceed(filename);
},
isFIFO: function () {
isFIFO: function() {
return suceed(filename);
},
};
},
stat: function (filename) {
stat: function(filename) {
if (!suceed(filename)) {
return Promise.reject(new Error('not a file'));
}
return Promise.resolve({
isFile: function () {
isFile: function() {
return true;
}
},
});
}
},
};

var resolve = proxyquire('../lib/index', {
'then-fs': fs,
});

test('resolve immediately', function (t) {
test('resolve immediately', function(t) {
t.plan(2);

suceed = True;

resolve('foo').then(function () {
t.pass('foo found');
}).catch(function (e) {
t.fail(e.stack);
});
resolve('foo')
.then(function() {
t.pass('foo found');
})
.catch(function(e) {
t.fail(e.stack);
});

t.ok(resolve.sync('foo'), 'sync should find immediately');
});

test('resolve never', function (t) {
test('resolve never', function(t) {
t.plan(2);
suceed = False;

resolve('foo').then(function () {
t.fail('should result in NO_PACKAGE_FOUND');
}).catch(function (e) {
if (e.code === 'NO_PACKAGE_FOUND') {
t.pass('not found');
} else {
t.fail(e.stack);
}
});
resolve('foo')
.then(function() {
t.fail('should result in NO_PACKAGE_FOUND');
})
.catch(function(e) {
if (e.code === 'NO_PACKAGE_FOUND') {
t.pass('not found');
} else {
t.fail(e.stack);
}
});

t.throws(function () {
resolve.sync('foo');
}, /package not found foo/, 'sync should throw saying not found');
t.throws(
function() {
resolve.sync('foo');
},
/package not found foo/,
'sync should throw saying not found',
);
});

test('resolve if not found', function (t) {
test('resolve if not found', function(t) {
var statSync = fs.statSync;
t.plan(3);
t.test('setup', function (t) {
fs.statSync = function () {
t.test('setup', function(t) {
fs.statSync = function() {
var e = new Error('not found');
e.code = 'ENOENT';
throw e;
Expand All @@ -80,64 +91,76 @@ test('resolve if not found', function (t) {
t.end();
});

t.test('resolve if not found (test)', function (t) {
t.test('resolve if not found (test)', function(t) {
t.plan(1);
t.throws(function () {
resolve.sync('foo');
}, /package not found foo/, 'sync should throw saying not found');
t.throws(
function() {
resolve.sync('foo');
},
/package not found foo/,
'sync should throw saying not found',
);
});

t.test('teardown', function (t) {
t.test('teardown', function(t) {
fs.statSync = statSync;
t.pass('teardown complete');
t.end();
});
});


test('resolve at root', function (t) {
test('resolve at root', function(t) {
t.plan(2);

var target = '/node_modules/foo';
var base = __dirname + '/fixtures/bar';
suceed = function (filename) {
suceed = function(filename) {
// console.log('%s ===? %s', filename, filename === target + '/package.json');
return filename === target + '/package.json';
};

resolve('foo', base).then(function (dir) {
t.equal(dir, target);
}).catch(function (e) {
if (e.code === 'NO_PACKAGE_FOUND') {
t.fail('not found at root');
} else {
t.fail(e.stack, 'unknown error on search at root');
}
});
resolve('foo', base)
.then(function(dir) {
t.equal(dir, target);
})
.catch(function(e) {
if (e.code === 'NO_PACKAGE_FOUND') {
t.fail('not found at root');
} else {
t.fail(e.stack, 'unknown error on search at root');
}
});

t.equal(resolve.sync('foo', base), target, 'found module at root');
});

test('resolve works with scoped packages', function (t) {
test('resolve works with scoped packages', function(t) {
t.plan(2);

var target = __dirname + '/node_modules/@remy/foo/package.json';
suceed = function (filename) {
suceed = function(filename) {
return filename === target;
};

var base = __dirname + '/node_modules/@remy/foo/node_modules/semver/node_modules/bar';

resolve('@remy/foo', base).then(function (dir) {
t.equal(dir, path.dirname(target));
}).catch(function (e) {
console.log(e.stack);
if (e.code === 'NO_PACKAGE_FOUND') {
t.fail('not found');
} else {
t.fail(e.stack);
}
});
var base =
__dirname + '/node_modules/@remy/foo/node_modules/semver/node_modules/bar';

resolve('@remy/foo', base)
.then(function(dir) {
t.equal(dir, path.dirname(target));
})
.catch(function(e) {
console.log(e.stack);
if (e.code === 'NO_PACKAGE_FOUND') {
t.fail('not found');
} else {
t.fail(e.stack);
}
});

t.equal(resolve.sync('@remy/foo', base), path.dirname(target), 'sync scoped matches');
});
t.equal(
resolve.sync('@remy/foo', base),
path.dirname(target),
'sync scoped matches',
);
});