Skip to content

Commit

Permalink
Allow intercept of transitive require calls files.
Browse files Browse the repository at this point in the history
This paves the way for avajs/ava#156
  • Loading branch information
jamestalmage committed Nov 10, 2015
1 parent 42b400d commit 46dffd5
Show file tree
Hide file tree
Showing 7 changed files with 62 additions and 6 deletions.
5 changes: 5 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ module.exports = function requireFromString(code, filename, opts) {
var paths = Module._nodeModulePaths(path.dirname(filename));

var m = new Module(filename, module.parent);
if (opts.require) {
m.require = function (path) {
return opts.require.call(this, path);
}
}
m.filename = filename;
m.paths = [].concat(opts.prependPaths).concat(paths).concat(opts.appendPaths);
m._compile(code, filename);
Expand Down
2 changes: 2 additions & 0 deletions test/fixture/depth0.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@

module.exports = require('./depth1');
1 change: 1 addition & 0 deletions test/fixture/depth1/depth2/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = 'FOO - depth2';
1 change: 1 addition & 0 deletions test/fixture/depth1/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require('./depth2');
3 changes: 3 additions & 0 deletions test/fixture/greet-james.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = function() {
return 'Hello ' + require('./james');
};
1 change: 1 addition & 0 deletions test/fixture/james.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = 'James';
55 changes: 49 additions & 6 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@ var fs = require('fs');
var path = require('path');
var requireFromString = require('../');

function getFixture(file) {
file = path.join(__dirname, 'fixture', file);
var code = fs.readFileSync(file, 'utf8');

return {file: file, code: code};
}

it('should accept only string as code', function () {
assert.throws(function () {
requireFromString();
Expand All @@ -24,18 +31,16 @@ it('should accept filename', function () {
});

it('should work with relative require in file', function () {
var file = path.join(__dirname, '/fixture/module.js');
var code = fs.readFileSync(file, 'utf8');
var result = requireFromString(code, file);
var fixture = getFixture('module.js');
var result = requireFromString(fixture.code, fixture.file);

assert.ok(result);
assert.ok(module === result.parent.parent);
});

it('should have appended and preppended paths', function () {
var file = path.join(__dirname, '/fixture/submodule.js');
var code = fs.readFileSync(file, 'utf8');
var result = requireFromString(code, file, {
var fixture = getFixture('submodule.js');
var result = requireFromString(fixture.code, fixture.file, {
appendPaths: ['append'],
prependPaths: ['prepend']
});
Expand All @@ -44,3 +49,41 @@ it('should have appended and preppended paths', function () {
assert.equal(result.paths.indexOf('append'), result.paths.length - 1);
assert.equal(result.paths.indexOf('prepend'), 0);
});

it('should allow modification of other required modules via callback', function () {
var fixture = getFixture('greet-james.js');
var Module = module.constructor;

function transform(code) {
return code.replace('James', 'Jim');
}

function requireHook(path) {
var file = Module._resolveFilename(path, this);
var code = fs.readFileSync(file, 'utf8');
return requireFromString(transform(code), file, {require: requireHook});
}

var result = requireFromString(fixture.code, fixture.file, {require: requireHook});

assert.equal(result(), 'Hello Jim');
});

it('transforms should be doable even as relative directory changes', function () {
var fixture = getFixture('depth0.js');
var Module = module.constructor;

function transform(code) {
return code.replace('FOO', 'BAR');
}

function requireHook(path) {
var file = Module._resolveFilename(path, this);
var code = fs.readFileSync(file, 'utf8');
return requireFromString(transform(code), file, {require: requireHook});
}

var result = requireFromString(fixture.code, fixture.file, {require: requireHook});

assert.equal(result, 'BAR - depth2');
});

0 comments on commit 46dffd5

Please sign in to comment.