Skip to content

Commit

Permalink
added mocha to dev dependencies
Browse files Browse the repository at this point in the history
  • Loading branch information
christkv committed Feb 3, 2016
1 parent 420b49f commit c2de8f0
Show file tree
Hide file tree
Showing 4 changed files with 176 additions and 0 deletions.
6 changes: 6 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
language: node_js
node_js:
- "0.10"
- "0.12"
- "4.2.1"
sudo: false
89 changes: 89 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
var path = require('path'),
fs = require('fs'),
f = require('util').format,
semver = require('semver');

var exists = fs.existsSync || path.existsSync;

var find_package_json = function(location) {
var found = false;

while(!found) {
if (exists(location + '/package.json')) {
found = location;
} else if (location !== '/') {

This comment has been minimized.

Copy link
@garry-sk

garry-sk Sep 26, 2017

On the win32 platform, we can get into an infinite loop (for example: path.dirname ("c:\") === "c:\" and will never equal "/").

location = path.dirname(location);
} else {
return false;
}
}

return location;
}

var require_optional = function(name, options) {
options = options || {};
options.strict = typeof options.strict == 'boolean' ? options.strict : true;

// Locate this module's package.json file
var location = find_package_json(__dirname);
if(!location) {
throw new Error('package.json can not be located');
}

// Read the package.json file
var object = JSON.parse(fs.readFileSync(f('%s/package.json', location)));
// Is the name defined by interal file references
var parts = name.split(/\//);

// Optional dependencies exist
if(!object.peerOptionalDependencies) {
throw new Error(f('no optional dependency [%s] defined in peerOptionalDependencies in package.json', parts[0]));
} else if(object.peerOptionalDependencies && !object.peerOptionalDependencies[parts[0]]) {
throw new Error(f('no optional dependency [%s] defined in peerOptionalDependencies in package.json', parts[0]));
}

var expectedVersions = object.peerOptionalDependencies[parts[0]];

try {
// Validate if it's possible to read the module
var moduleEntry = require(name);

// Resolve the location of the module's package.json file
var location = find_package_json(require.resolve(name));
if(!location) {
throw new Error('package.json can not be located');
}

// Read the module file
var dependentOnModule = JSON.parse(fs.readFileSync(f('%s/package.json', location)));
// Get the version
var version = dependentOnModule.version;
// Validate if the found module satisfies the version id
if(semver.satisfies(version, expectedVersions) == false
&& options.strict) {
var error = new Error(f('optional dependency [%s] found but version [%s] did not satisfy constraint [%s]', parts[0], version, expectedVersions));
error.code = 'OPTIONAL_MODULE_NOT_FOUND';
throw error;
}

// Satifies the module requirement
return moduleEntry;
} catch(err) {
if(err.code != 'MODULE_NOT_FOUND') {
throw err;
}
}
}

require_optional.exists = function(name) {
try {
var m = require_optional(name);
if(m === undefined) return false;
return true;
} catch(err) {
return false;
}
}

module.exports = require_optional;
39 changes: 39 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
{
"name": "require_optional",
"version": "1.0.0",
"description": "Allows you declare optionalPeerDependencies that can be satisfied by the top level module but ignored if they are not.",
"main": "index.js",
"scripts": {
"test": "mocha"
},
"repository": {
"type": "git",
"url": "https://github.com/christkv/require_optional.git"
},
"keywords": [
"optional",
"require",
"optionalPeerDependencies"
],
"author": "Christian Kvalheim Amor",
"license": "Apache-2.0",
"bugs": {
"url": "https://github.com/christkv/require_optional/issues"
},
"homepage": "https://github.com/christkv/require_optional",
"dependencies": {
"semver": "^5.1.0"
},
"devDependencies": {
"mocha": "^2.4.5",
"es6-promise": "^3.0.2",
"co": "4.6.0",
"bson": "0.4.21"
},
"peerOptionalDependencies": {
"co": ">=5.6.0",
"es6-promise": "^3.0.2",
"es6-promise2": "^4.0.2",
"bson": "0.4.21"
}
}
42 changes: 42 additions & 0 deletions test/require_optional_tests.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
var assert = require('assert'),
require_optional = require('../');

describe('Require Optional', function() {
describe('top level require', function() {
it('should correctly require co library', function() {
var promise = require_optional('es6-promise');
assert.ok(promise);
});

it('should fail to require es6-promise library', function() {
try {
require_optional('co');
} catch(e) {
assert.equal('OPTIONAL_MODULE_NOT_FOUND', e.code);
return;
}

assert.ok(false);
});

it('should ignore optional library not defined', function() {
assert.equal(undefined, require_optional('es6-promise2'));
});
});

describe('internal module file require', function() {
it('should correctly require co library', function() {
var Long = require_optional('bson/lib/bson/long.js');
assert.ok(Long);
});
});

describe('top level resolve', function() {
it('should correctly use exists method', function() {
assert.equal(false, require_optional.exists('co'));
assert.equal(true, require_optional.exists('es6-promise'));
assert.equal(true, require_optional.exists('bson/lib/bson/long.js'));
assert.equal(false, require_optional.exists('es6-promise2'));
});
});
});

0 comments on commit c2de8f0

Please sign in to comment.