433 lines
13 KiB
JavaScript
433 lines
13 KiB
JavaScript
// jshint maxstatements: false
|
|
// jscs:disable disallowMultipleVarDecl, maximumLineLength
|
|
'use strict';
|
|
|
|
var assert = require('proclaim');
|
|
var mockery = require('mockery');
|
|
var sinon = require('sinon');
|
|
var path = require('path');
|
|
|
|
describe('lib/hasbin', function () {
|
|
var fs, hasbin;
|
|
|
|
beforeEach(function () {
|
|
|
|
process.env.PATH = ['/bin', '/usr/bin', '/usr/local/bin'].join(path.delimiter);
|
|
|
|
fs = require('../mock/fs');
|
|
mockery.registerMock('fs', fs);
|
|
|
|
fs.stat.withArgs('/usr/bin/foo').yieldsAsync(null, fs.mockStatIsFile);
|
|
fs.stat.withArgs('/usr/bin/baz').yieldsAsync(null, fs.mockStatIsFile);
|
|
fs.stat.withArgs('/usr/bin/error').yieldsAsync(new Error());
|
|
fs.statSync.withArgs('/usr/bin/foo').returns(fs.mockStatIsFile);
|
|
fs.statSync.withArgs('/usr/bin/baz').returns(fs.mockStatIsFile);
|
|
fs.statSync.withArgs('/usr/bin/error').throws(new Error());
|
|
|
|
hasbin = require('../../../lib/hasbin');
|
|
|
|
});
|
|
|
|
it('should be a function', function () {
|
|
assert.isFunction(hasbin);
|
|
});
|
|
|
|
it('should have an `async` method which aliases `hasbin`', function () {
|
|
assert.strictEqual(hasbin.async, hasbin);
|
|
});
|
|
|
|
describe('hasbin()', function () {
|
|
var passingResult, failingResult, errorResult;
|
|
|
|
beforeEach(function (done) {
|
|
hasbin('foo', function (result) {
|
|
passingResult = result;
|
|
hasbin('bar', function (result) {
|
|
failingResult = result;
|
|
hasbin('error', function (result) {
|
|
errorResult = result;
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
it('should call `fs.stat()` and `stat.isFile()` for the binary on each path in `process.env.PATH`', function () {
|
|
assert.callCount(fs.stat, 9);
|
|
assert.calledWith(fs.stat, '/bin/foo');
|
|
assert.calledWith(fs.stat, '/usr/bin/foo');
|
|
assert.calledWith(fs.stat, '/usr/local/bin/foo');
|
|
assert.calledWith(fs.stat, '/bin/bar');
|
|
assert.calledWith(fs.stat, '/usr/bin/bar');
|
|
assert.calledWith(fs.stat, '/usr/local/bin/bar');
|
|
assert.calledWith(fs.stat, '/bin/error');
|
|
assert.calledWith(fs.stat, '/usr/bin/error');
|
|
assert.calledWith(fs.stat, '/usr/local/bin/error');
|
|
});
|
|
|
|
it('should callback with `true` if a matching binary is found', function () {
|
|
assert.isTrue(passingResult);
|
|
});
|
|
|
|
it('should callback with `false` if a matching binary is not found', function () {
|
|
assert.isFalse(failingResult);
|
|
});
|
|
|
|
it('should callback with `false` if an error occurs', function () {
|
|
assert.isFalse(errorResult);
|
|
});
|
|
|
|
});
|
|
|
|
describe('hasbin() without PATH', function () {
|
|
var oldPath;
|
|
|
|
beforeEach(function (done) {
|
|
oldPath = process.env.PATH;
|
|
delete process.env.PATH;
|
|
hasbin('foo', function () {
|
|
done();
|
|
});
|
|
});
|
|
|
|
afterEach(function () {
|
|
process.env.PATH = oldPath;
|
|
});
|
|
|
|
it('should call `fs.stat()` for the binary alone', function () {
|
|
assert.callCount(fs.stat, 1);
|
|
assert.calledWith(fs.stat, 'foo');
|
|
});
|
|
});
|
|
|
|
describe('hasbin() with PATHEXT', function () {
|
|
beforeEach(function (done) {
|
|
process.env.PATHEXT = ['.COM', '.EXE'].join(path.delimiter);
|
|
hasbin('foo', function () {
|
|
done();
|
|
});
|
|
});
|
|
|
|
afterEach(function () {
|
|
process.env.PATHEXT = '';
|
|
});
|
|
|
|
it('should call `fs.stat()` for the binary on each path in `process.env.PATH` with each extension in `process.env.PATHEXT`', function () {
|
|
assert.callCount(fs.stat, 6);
|
|
assert.calledWith(fs.stat, '/bin/foo.COM');
|
|
assert.calledWith(fs.stat, '/bin/foo.EXE');
|
|
assert.calledWith(fs.stat, '/usr/bin/foo.COM');
|
|
assert.calledWith(fs.stat, '/usr/bin/foo.EXE');
|
|
assert.calledWith(fs.stat, '/usr/local/bin/foo.COM');
|
|
assert.calledWith(fs.stat, '/usr/local/bin/foo.EXE');
|
|
});
|
|
});
|
|
|
|
it('should have a `sync` method', function () {
|
|
assert.isFunction(hasbin.sync);
|
|
});
|
|
|
|
describe('hasbin.sync()', function () {
|
|
var passingResult, failingResult, errorResult;
|
|
|
|
beforeEach(function () {
|
|
passingResult = hasbin.sync('foo');
|
|
failingResult = hasbin.sync('bar');
|
|
errorResult = hasbin.sync('error');
|
|
});
|
|
|
|
it('should call `fs.statSync()` and `stat.isFile()` for the binary on each path in `process.env.PATH`', function () {
|
|
assert.callCount(fs.statSync, 8);
|
|
assert.calledWith(fs.statSync, '/bin/foo');
|
|
assert.calledWith(fs.statSync, '/usr/bin/foo');
|
|
assert.neverCalledWith(fs.statSync, '/usr/local/bin/foo');
|
|
assert.calledWith(fs.statSync, '/bin/bar');
|
|
assert.calledWith(fs.statSync, '/usr/bin/bar');
|
|
assert.calledWith(fs.statSync, '/usr/local/bin/bar');
|
|
assert.calledWith(fs.statSync, '/bin/error');
|
|
assert.calledWith(fs.statSync, '/usr/bin/error');
|
|
assert.calledWith(fs.statSync, '/usr/local/bin/error');
|
|
});
|
|
|
|
it('should return `true` if a matching binary is found', function () {
|
|
assert.isTrue(passingResult);
|
|
});
|
|
|
|
it('should return `false` if a matching binary is not found', function () {
|
|
assert.isFalse(failingResult);
|
|
});
|
|
|
|
it('should return `false` if an error occurs', function () {
|
|
assert.isFalse(errorResult);
|
|
});
|
|
|
|
});
|
|
|
|
it('should have an `all` method', function () {
|
|
assert.isFunction(hasbin.all);
|
|
});
|
|
|
|
it('should have an `every` method which aliases `all`', function () {
|
|
assert.strictEqual(hasbin.every, hasbin.all);
|
|
});
|
|
|
|
describe('hasbin.all()', function () {
|
|
var passingResult, failingResult;
|
|
|
|
beforeEach(function (done) {
|
|
hasbin.async = sinon.stub();
|
|
hasbin.async.withArgs('foo').yieldsAsync(true);
|
|
hasbin.async.withArgs('bar').yieldsAsync(true);
|
|
hasbin.async.withArgs('baz').yieldsAsync(true);
|
|
hasbin.async.withArgs('qux').yieldsAsync(false);
|
|
hasbin.all(['foo', 'bar'], function (result) {
|
|
passingResult = result;
|
|
hasbin.all(['baz', 'qux'], function (result) {
|
|
failingResult = result;
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
|
|
it('should call `hasbin.async()` for each binary', function () {
|
|
assert.callCount(hasbin.async, 4);
|
|
assert.calledWith(hasbin.async, 'foo');
|
|
assert.calledWith(hasbin.async, 'bar');
|
|
assert.calledWith(hasbin.async, 'baz');
|
|
assert.calledWith(hasbin.async, 'qux');
|
|
});
|
|
|
|
it('should callback with `true` if matching binaries are all found', function () {
|
|
assert.isTrue(passingResult);
|
|
});
|
|
|
|
it('should callback with `false` if a matching binary is not found', function () {
|
|
assert.isFalse(failingResult);
|
|
});
|
|
|
|
});
|
|
|
|
it('should have an `all.sync` method', function () {
|
|
assert.isFunction(hasbin.all.sync);
|
|
});
|
|
|
|
it('should have an `every.sync` method which aliases `all.sync`', function () {
|
|
assert.strictEqual(hasbin.every.sync, hasbin.all.sync);
|
|
});
|
|
|
|
describe('hasbin.all.sync()', function () {
|
|
var passingResult, failingResult;
|
|
|
|
beforeEach(function () {
|
|
hasbin.sync = sinon.stub();
|
|
hasbin.sync.withArgs('foo').returns(true);
|
|
hasbin.sync.withArgs('bar').returns(true);
|
|
hasbin.sync.withArgs('baz').returns(true);
|
|
hasbin.sync.withArgs('qux').returns(false);
|
|
passingResult = hasbin.all.sync(['foo', 'bar']);
|
|
failingResult = hasbin.all.sync(['baz', 'qux']);
|
|
});
|
|
|
|
it('should call `hasbin.sync()` for each binary', function () {
|
|
assert.callCount(hasbin.sync, 4);
|
|
assert.calledWith(hasbin.sync, 'foo');
|
|
assert.calledWith(hasbin.sync, 'bar');
|
|
assert.calledWith(hasbin.sync, 'baz');
|
|
assert.calledWith(hasbin.sync, 'qux');
|
|
});
|
|
|
|
it('should return `true` if matching binaries are all found', function () {
|
|
assert.isTrue(passingResult);
|
|
});
|
|
|
|
it('should return `false` if a matching binary is not found', function () {
|
|
assert.isFalse(failingResult);
|
|
});
|
|
|
|
});
|
|
|
|
it('should have a `some` method', function () {
|
|
assert.isFunction(hasbin.some);
|
|
});
|
|
|
|
it('should have an `any` method which aliases `some`', function () {
|
|
assert.strictEqual(hasbin.any, hasbin.some);
|
|
});
|
|
|
|
describe('hasbin.some()', function () {
|
|
var passingResult, failingResult;
|
|
|
|
beforeEach(function (done) {
|
|
hasbin.async = sinon.stub();
|
|
hasbin.async.withArgs('foo').yieldsAsync(true);
|
|
hasbin.async.withArgs('bar').yieldsAsync(false);
|
|
hasbin.async.withArgs('baz').yieldsAsync(false);
|
|
hasbin.async.withArgs('qux').yieldsAsync(false);
|
|
hasbin.some(['foo', 'bar'], function (result) {
|
|
passingResult = result;
|
|
hasbin.some(['baz', 'qux'], function (result) {
|
|
failingResult = result;
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
|
|
it('should call `hasbin.async()` for each binary', function () {
|
|
assert.callCount(hasbin.async, 4);
|
|
assert.calledWith(hasbin.async, 'foo');
|
|
assert.calledWith(hasbin.async, 'bar');
|
|
assert.calledWith(hasbin.async, 'baz');
|
|
assert.calledWith(hasbin.async, 'qux');
|
|
});
|
|
|
|
it('should return `true` if some matching binaries are found', function () {
|
|
assert.isTrue(passingResult);
|
|
});
|
|
|
|
it('should return `false` if no matching binaries are found', function () {
|
|
assert.isFalse(failingResult);
|
|
});
|
|
|
|
});
|
|
|
|
it('should have a `some.sync` method', function () {
|
|
assert.isFunction(hasbin.some.sync);
|
|
});
|
|
|
|
it('should have an `any.sync` method which aliases `some.sync`', function () {
|
|
assert.strictEqual(hasbin.any.sync, hasbin.some.sync);
|
|
});
|
|
|
|
describe('hasbin.some.sync()', function () {
|
|
var passingResult, failingResult;
|
|
|
|
beforeEach(function () {
|
|
hasbin.sync = sinon.stub();
|
|
hasbin.sync.withArgs('foo').returns(true);
|
|
hasbin.sync.withArgs('bar').returns(false);
|
|
hasbin.sync.withArgs('baz').returns(false);
|
|
hasbin.sync.withArgs('qux').returns(false);
|
|
passingResult = hasbin.some.sync(['foo', 'bar']);
|
|
failingResult = hasbin.some.sync(['baz', 'qux']);
|
|
});
|
|
|
|
it('should call `hasbin.sync()` for each binary', function () {
|
|
assert.callCount(hasbin.sync, 3);
|
|
assert.calledWith(hasbin.sync, 'foo');
|
|
assert.calledWith(hasbin.sync, 'baz');
|
|
assert.calledWith(hasbin.sync, 'qux');
|
|
});
|
|
|
|
it('should return `true` if some matching binaries are found', function () {
|
|
assert.isTrue(passingResult);
|
|
});
|
|
|
|
it('should return `false` if no matching binaries are found', function () {
|
|
assert.isFalse(failingResult);
|
|
});
|
|
|
|
});
|
|
|
|
it('should have a `first` method', function () {
|
|
assert.isFunction(hasbin.first);
|
|
});
|
|
|
|
describe('hasbin.first()', function () {
|
|
var passingResult, failingResult;
|
|
|
|
beforeEach(function (done) {
|
|
hasbin.async = sinon.stub();
|
|
hasbin.async.withArgs('foo').yieldsAsync(true);
|
|
hasbin.async.withArgs('bar').yieldsAsync(false);
|
|
hasbin.async.withArgs('baz').yieldsAsync(false);
|
|
hasbin.async.withArgs('qux').yieldsAsync(false);
|
|
hasbin.first(['foo', 'bar'], function (result) {
|
|
passingResult = result;
|
|
hasbin.first(['baz', 'qux'], function (result) {
|
|
failingResult = result;
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
|
|
it('should call `hasbin.async()` for each binary', function () {
|
|
assert.callCount(hasbin.async, 4);
|
|
assert.calledWith(hasbin.async, 'foo');
|
|
assert.calledWith(hasbin.async, 'bar');
|
|
assert.calledWith(hasbin.async, 'baz');
|
|
assert.calledWith(hasbin.async, 'qux');
|
|
});
|
|
|
|
it('should return the name of the first binary if some matching binaries are found', function () {
|
|
assert.strictEqual('foo', passingResult);
|
|
});
|
|
|
|
it('should return `false` if no matching binaries are found', function () {
|
|
assert.isFalse(failingResult);
|
|
});
|
|
});
|
|
|
|
it('should have a `first.sync` method', function () {
|
|
assert.isFunction(hasbin.first.sync);
|
|
});
|
|
|
|
describe('hasbin.first.sync()', function () {
|
|
var passingResult, failingResult;
|
|
|
|
beforeEach(function () {
|
|
hasbin.sync = sinon.stub();
|
|
hasbin.sync.withArgs('foo').returns(true);
|
|
hasbin.sync.withArgs('bar').returns(false);
|
|
hasbin.sync.withArgs('baz').returns(false);
|
|
hasbin.sync.withArgs('qux').returns(false);
|
|
passingResult = hasbin.first.sync(['foo', 'bar']);
|
|
failingResult = hasbin.first.sync(['baz', 'qux']);
|
|
});
|
|
|
|
it('should call `hasbin.sync()` for each binary', function () {
|
|
assert.callCount(hasbin.sync, 4);
|
|
assert.calledWith(hasbin.sync, 'foo');
|
|
assert.calledWith(hasbin.sync, 'bar');
|
|
assert.calledWith(hasbin.sync, 'baz');
|
|
assert.calledWith(hasbin.sync, 'qux');
|
|
});
|
|
|
|
it('should return the name of the first binary if some matching binaries are found', function () {
|
|
assert.strictEqual('foo', passingResult);
|
|
});
|
|
|
|
it('should return `false` if no matching binaries are found', function () {
|
|
assert.isFalse(failingResult);
|
|
});
|
|
|
|
});
|
|
|
|
describe('hasbin() with quotes in PATH', function () {
|
|
var passingResult, oldPath, pathArr;
|
|
|
|
beforeEach(function (done) {
|
|
oldPath = process.env.PATH;
|
|
pathArr = process.env.PATH.split(path.delimiter);
|
|
pathArr.push('"/win"');
|
|
process.env.PATH = pathArr.join(path.delimiter);
|
|
|
|
fs.stat.withArgs('/win/norf').yieldsAsync(null, fs.mockStatIsFile);
|
|
fs.statSync.withArgs('/win/norf').returns(fs.mockStatIsFile);
|
|
|
|
hasbin('norf', function (result) {
|
|
passingResult = result;
|
|
done();
|
|
});
|
|
});
|
|
|
|
afterEach(function () {
|
|
process.env.PATH = oldPath;
|
|
});
|
|
|
|
it('should return `true` if PATH entries are wrapped in quotes and binaries are found', function () {
|
|
assert.isTrue(passingResult);
|
|
});
|
|
|
|
});
|
|
});
|