Skip to content

Commit

Permalink
Merge pull request #19 from nodules/issue-18
Browse files Browse the repository at this point in the history
Support Node.js 0.10 and 0.12
  • Loading branch information
qfox committed Oct 20, 2016
2 parents 2d36b41 + 710a6ac commit c3b99d9
Show file tree
Hide file tree
Showing 5 changed files with 107 additions and 45 deletions.
14 changes: 14 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
root = true

[*]
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
indent_style = space
indent_size = 4

[*.{json,*rc,yml}]
indent_size = 2

[*.md]
trim_trailing_whitespace = false
2 changes: 2 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ language: node_js

matrix:
include:
- node_js: "0.10"
- node_js: "0.12"
- node_js: 4
- node_js: 6
env: COVERALLS=1
Expand Down
10 changes: 6 additions & 4 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ var vm = require('vm');
var path = require('path');
var Module = require('module');

var isAbsolutePath = require('path-is-absolute');

/**
* Eval expressions, JSON files or require commonJS modules
*
Expand All @@ -22,7 +24,7 @@ module.exports = function(content, filename, context) {
});
}

if(filename && !path.isAbsolute(filename)) {
if(filename && !isAbsolutePath(filename)) {
filename = path.resolve(path.dirname(_getCalleeFilename()), filename);
}

Expand Down Expand Up @@ -54,15 +56,15 @@ function _commonjsEval(content, filename, context) {
sandbox.module.filename = filename;
sandbox.module.paths = Module._nodeModulePaths(dirname);
// See: https://github.com/nodejs/node/blob/master/lib/internal/module.js#L13-L40
sandbox.require = id => sandbox.module.require(id);
sandbox.require.resolve = req => Module._resolveFilename(req, sandbox.module);
sandbox.require = function(id) { return sandbox.module.require(id); };
sandbox.require.resolve = function(req) { return Module._resolveFilename(req, sandbox.module); };
} else {
filename = '<anonymous>';
sandbox.require = filenameRequired;
}

var args = [sandbox.module.exports, sandbox.require, sandbox.module, filename, dirname];
context && (contextKeys = Object.keys(context).map(key => {
context && (contextKeys = Object.keys(context).map(function(key) {
args.push(context[key]);
return key;
}));
Expand Down
6 changes: 6 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,18 @@
"url": "https://github.com/nodules/node-eval"
},
"main": "index.js",
"engines": {
"node": ">= 0.10"
},
"scripts": {
"pretest": "npm run lint",
"test": "npm run specs",
"specs": "nyc mocha",
"lint": "jshint . && jscs ."
},
"dependencies": {
"path-is-absolute": "1.0.1"
},
"devDependencies": {
"chai": "^3.5.0",
"jscs": "^2.11.0",
Expand Down
120 changes: 79 additions & 41 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,53 +7,85 @@ function coco(content, context) {
return expect(nodeEval(content, '/file.js', context)).to;
}

describe('expression', () => {
it('should eval simple expression', () => coco('42 / 42').eql(1));
describe('expression', function() {
it('should eval simple expression', function() {
return coco('42 / 42').eql(1);
});

it('should eval expression', () => coco('({42:42})').eql({42: 42}));
it('should eval expression', function() {
return coco('({42:42})').eql({42: 42});
});

it('should eval arrayExpression', () => coco('[{42:42}]').eql([{42: 42}]));
it('should eval arrayExpression', function() {
return coco('[{42:42}]').eql([{42: 42}]);
});

it('should not eval simple object', () => coco('{}').to.undefined);
it('should not eval simple object', function() {
return coco('{}').to.undefined;
});

it('should eval expression with \'exports\' key', () => coco('[{exports:42}]').eql([{exports: 42}]));
it('should eval expression with \'exports\' key', function() {
return coco('[{exports:42}]').eql([{exports: 42}]);
});

it('should eval expression with \'module\' key', () => coco('[{module:42}]').eql([{module: 42}]));
it('should eval expression with \'module\' key', function() {
return coco('[{module:42}]').eql([{module: 42}]);
});
});

describe('commonJS modules', () => {
it('should eval exports', () => coco('exports.block = 42; ({1:1, 2:2});').eql({block: 42}));
describe('commonJS modules', function() {
it('should eval exports', function() {
return coco('exports.block = 42; ({1:1, 2:2});').eql({block: 42});
});

it('should eval module.exports', () => coco('module.exports = {42:42}; ({1:1, 2:2});').eql({42: 42}));
it('should eval module.exports', function() {
return coco('module.exports = {42:42}; ({1:1, 2:2});').eql({42: 42});
});

it('should eval module.exports number', () => coco('module.exports = 42; ({1:1, 2:2});').eql(42));
it('should eval module.exports number', function() {
return coco('module.exports = 42; ({1:1, 2:2});').eql(42);
});

it('should eval module.exports bool', () => coco('module.exports = true; ({1:1, 2:2});').eql(true));
it('should eval module.exports bool', function() {
return coco('module.exports = true; ({1:1, 2:2});').eql(true);
});

it('should eval module.exports bool', () => coco('module.exports = false; ({1:1, 2:2});').eql(false));
it('should eval module.exports bool', function() {
return coco('module.exports = false; ({1:1, 2:2});').eql(false);
});

it('should eval module.exports string', () => coco('module.exports = \'42\'; ({1:1, 2:2});').eql('42'));
it('should eval module.exports string', function() {
return coco('module.exports = \'42\'; ({1:1, 2:2});').eql('42');
});

it('should eval module.exports undefined', () => coco('module.exports = undefined; ({1:1, 2:2});').eql(undefined));
it('should eval module.exports undefined', function() {
return coco('module.exports = undefined; ({1:1, 2:2});').eql(undefined);
});

it('should eval module.exports replace', () => coco('module.exports = {42:42, 24:24, 1:1}; ({1:1, 2:2});').eql({42: 42, 24: 24, 1: 1}));
it('should eval module.exports replace', function() {
return coco('module.exports = {42:42, 24:24, 1:1}; ({1:1, 2:2});').eql({42: 42, 24: 24, 1: 1});
});

it('should eval module.exports {}', () => coco('module.exports = {}; ({1:1, 2:2});').eql({}));
it('should eval module.exports {}', function() {
return coco('module.exports = {}; ({1:1, 2:2});').eql({});
});

it('should eval exports = module.exports', () => coco('exports = module.exports = {42:42}; ({1:1, 2:2});').eql({42: 42}));
it('should eval exports = module.exports', function() {
return coco('exports = module.exports = {42:42}; ({1:1, 2:2});').eql({42: 42});
});

it('should return empty object if you touch `module` object but didn\'t export anything', () => {
it('should return empty object if you touch `module` object but didn\'t export anything', function() {
expect(nodeEval('module.zxqfox = {42:42}; ({1:1, 2:2});')).to.eql({});
});

it('should eval module with require', () => {
var requireContent =
`
var p = require('../package.json');
module.exports = {
block: p.name,
};
`;
it('should eval module with require', function() {
var requireContent = [
'var p = require("../package.json")',
'module.exports = {',
'block: p.name,',
'};'
].join('\n');

expect(nodeEval(requireContent, 'file.js')).to.eql({block: 'node-eval'});
});

Expand All @@ -72,32 +104,38 @@ describe('commonJS modules', () => {
});
});

describe('JSON', () => {
it('should eval json', () => {
describe('JSON', function() {
it('should eval json', function() {
var path = 'file.json',
content = '{"42":42}';

expect(nodeEval(content, path)).to.eql({42: 42});
});

it('should throw on bad json', () => {
it('should throw on bad json', function() {
var path = 'file.json',
content = '{"block":"page",}';

expect(() => nodeEval(content, path)).to.throw(/Unexpected token }/);
expect(function() { nodeEval(content, path); }).to.throw(/Unexpected token }/);
});
});

describe('context', () => {
describe('context', function() {
var answer = 42;

it('should provide context objects', () => coco('answer + answer', {answer}).to.eql(84));
it('should provide context objects', function() {
return coco('answer + answer', {answer: answer}).to.eql(84);
});

it('should provide context objects to module syntax', () => coco('module.exports = typeof it + typeof chai', {it, chai}).to.eql('functionobject'));
it('should provide context objects to module syntax', function() {
return coco('module.exports = typeof it + typeof chai', {it: it, chai: chai}).to.eql('functionobject');
});
});

describe('common', () => {
it('should work without filename argument', () => expect(nodeEval('42')).to.eql(42));
describe('common', function() {
it('should work without filename argument', function() {
return expect(nodeEval('42')).to.eql(42);
});

it('should not polute global.module obj', function() {
global.module = {42: 42};
Expand All @@ -106,28 +144,28 @@ describe('common', () => {
});
});

describe('errors', () => {
describe('errors', function() {
it('should throw on throwing bad js', function() {
var path = 'file.js',
content = 'throw new Error("Hello")';

expect(() => nodeEval(content, path)).to.throw('Hello');
expect(function() { nodeEval(content, path); }).to.throw('Hello');
});

it('should throw on syntactically bad js', function() {
var path = 'file.js',
content = 'yoba ! rot';

expect(() => nodeEval(content, path)).to.throw(/Unexpected token !/);
expect(function() { nodeEval(content, path); }).to.throw(/Unexpected token !/);
});

it('should throw error on require call without filename', function() {
expect(() => nodeEval('exports.path = require("path");'))
expect(function() { nodeEval('exports.path = require("path");'); })
.to.throw(/pass in filename/);
});

it('should throw error on require call without filename', function() {
expect(() => nodeEval('exports.path = require.resolve("path");'))
expect(function() { nodeEval('exports.path = require.resolve("path");'); })
.to.throw(/pass in filename/);
});
});

0 comments on commit c3b99d9

Please sign in to comment.