Skip to content

Commit

Permalink
feat: hookRunInThisContext now takes options object rather than filen…
Browse files Browse the repository at this point in the history
…ame (#99)
  • Loading branch information
CodeTroopers authored and bcoe committed Mar 1, 2018
1 parent d2a4262 commit 1504374
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 33 deletions.
43 changes: 29 additions & 14 deletions packages/istanbul-api/lib/run-cover.js
Expand Up @@ -5,6 +5,7 @@
var path = require('path'),
fs = require('fs'),
mkdirp = require('mkdirp'),
compareVersions = require('compare-versions'),
matcherFor = require('./file-matcher').matcherFor,
libInstrument = require('istanbul-lib-instrument'),
libCoverage = require('istanbul-lib-coverage'),
Expand Down Expand Up @@ -33,6 +34,8 @@ function getCoverFunctions(config, includes, callback) {
sourceMapStore = libSourceMaps.createSourceMapStore({}),
instrumenter,
transformer,
runInContextTransformer,
runInThisContextTransformer,
fakeRequire,
requireTransformer,
reportInitFn,
Expand All @@ -51,18 +54,26 @@ function getCoverFunctions(config, includes, callback) {
return global[coverageVar];
};
instrumenter = libInstrument.createInstrumenter(instOpts);
transformer = function (code, file) {
return instrumenter.instrumentSync(code, file);
transformer = function (code, options) {
var filename = typeof options === 'string' ? options : options.filename;
return instrumenter.instrumentSync(code, filename);
};
requireTransformer = function (code, file) {
var cov,
ret = transformer(code, file);
if (fakeRequire) {
cov = coverageFinderFn();
cov[file] = instrumenter.lastFileCoverage();
return 'function x() {}';
}
return ret;
runInContextTransformer = function (code, options) {
return transformer(code, options);
};
runInThisContextTransformer = function (code, options) {
return transformer(code, options);
};
requireTransformer = function (code, options) {
var cov,
ret = transformer(code, options),
filename = typeof options === 'string' ? options : options.filename;
if (fakeRequire) {
cov = coverageFinderFn();
cov[filename] = instrumenter.lastFileCoverage();
return 'function x() {}';
}
return ret;
};

coverageSetterFn = function (cov) {
Expand Down Expand Up @@ -102,12 +113,16 @@ function getCoverFunctions(config, includes, callback) {
reportInitFn();

if (config.hooks.hookRunInContext()) {
hook.hookRunInContext(matchFn, transformer, hookOpts);
hook.hookRunInContext(matchFn, runInContextTransformer, hookOpts);
}
if (config.hooks.hookRunInThisContext()) {
hook.hookRunInThisContext(matchFn, transformer, hookOpts);
hook.hookRunInThisContext(matchFn, runInThisContextTransformer, hookOpts);
if(compareVersions(process.versions.node, "6.0.0") === -1) {
disabler = hook.hookRequire(matchFn, requireTransformer, hookOpts);
}
} else {
disabler = hook.hookRequire(matchFn, requireTransformer, hookOpts);
}
disabler = hook.hookRequire(matchFn, requireTransformer, hookOpts);
};

unhookFn = function (matchFn) {
Expand Down
1 change: 1 addition & 0 deletions packages/istanbul-api/package.json
Expand Up @@ -36,6 +36,7 @@
},
"dependencies": {
"async": "^2.1.4",
"compare-versions": "^3.1.0",
"fileset": "^2.0.2",
"istanbul-lib-coverage": "^1.1.2",
"istanbul-lib-hook": "^1.1.0",
Expand Down
3 changes: 0 additions & 3 deletions packages/istanbul-api/test/run-check-coverage.test.js
Expand Up @@ -16,9 +16,6 @@ describe('run check-coverage', function () {
function getConfig(overrides) {
var cfg = configuration.loadObject({
verbose: false,
hooks: {
'hook-run-in-this-context': true
},
instrumentation: {
root: codeRoot,
'include-all-sources': true
Expand Down
4 changes: 3 additions & 1 deletion packages/istanbul-api/test/sample-code/context.js
Expand Up @@ -4,4 +4,6 @@ var vm = require('vm'),
file = path.resolve(__dirname, 'foo.js'),
code = fs.readFileSync(file, 'utf8');

vm.runInThisContext(code, file);
vm.runInThisContext(code, {
filename: file
});
27 changes: 16 additions & 11 deletions packages/istanbul-lib-hook/lib/hook.js
Expand Up @@ -11,20 +11,25 @@ var path = require('path'),

function transformFn(matcher, transformer, verbose) {

return function (code, filename) {
var shouldHook = typeof filename === 'string' && matcher(path.resolve(filename)),
return function (code, options) {
options = options || {};
if (typeof options === 'string') {
options = { filename: options };
}

var shouldHook = typeof options.filename === 'string' && matcher(path.resolve(options.filename)),
transformed,
changed = false;

if (shouldHook) {
if (verbose) {
console.error('Module load hook: transform [' + filename + ']');
console.error('Module load hook: transform [' + options.filename + ']');
}
try {
transformed = transformer(code, filename);
transformed = transformer(code, options);
changed = true;
} catch (ex) {
console.error('Transformation error for', filename, '; return original code');
console.error('Transformation error for', options.filename, '; return original code');
console.error(ex.message || String(ex));
if (verbose) {
console.error(ex.stack);
Expand Down Expand Up @@ -127,19 +132,19 @@ function unhookCreateScript() {
* hooks `vm.runInThisContext` to return transformed code.
* @method hookRunInThisContext
* @static
* @param matcher {Function(filePath)} a function that is called with the filename passed to `vm.createScript`
* @param matcher {Function(filePath)} a function that is called with the filename passed to `vm.runInThisContext`
* Should return a truthy value when transformations need to be applied to the code, a falsy value otherwise
* @param transformer {Function(code, filePath)} a function called with the original code and the filename passed to
* `vm.createScript`. Should return the transformed code.
* @param transformer {Function(code, options)} a function called with the original code and the filename passed to
* `vm.runInThisContext`. Should return the transformed code.
* @param opts {Object} [opts={}] options
* @param {Boolean} [opts.verbose] write a line to standard error every time the transformer is called
*/
function hookRunInThisContext(matcher, transformer, opts) {
opts = opts || {};
var fn = transformFn(matcher, transformer, opts.verbose);
vm.runInThisContext = function (code, file) {
var ret = fn(code, file);
return originalRunInThisContext(ret.code, file);
vm.runInThisContext = function (code, options) {
var ret = fn(code, options);
return originalRunInThisContext(ret.code, options);
};
}
/**
Expand Down
8 changes: 4 additions & 4 deletions packages/istanbul-lib-hook/test/hook.test.js
Expand Up @@ -144,25 +144,25 @@ describe('hooks', function () {
it('transforms foo', function () {
var s;
hook.hookRunInThisContext(matcher, scriptTransformer);
s = require('vm').runInThisContext('(function () { return 10; }());', '/bar/foo.js');
s = require('vm').runInThisContext('(function () { return 10; }());', { filename: '/bar/foo.js' });
assert.equal(s, 42);
hook.unhookRunInThisContext();
s = require('vm').runInThisContext('(function () { return 10; }());', '/bar/foo.js');
s = require('vm').runInThisContext('(function () { return 10; }());', { filename: '/bar/foo.js' });
assert.equal(s, 10);
});
it('does not transform code with no filename', function () {
var s;
hook.hookRunInThisContext(matcher, scriptTransformer);
s = require('vm').runInThisContext('(function () { return 10; }());');
assert.equal(s, 10);
hook.unhookCreateScript();
hook.unhookRunInThisContext();
});
it('does not transform code with non-string filename', function () {
var s;
hook.hookRunInThisContext(matcher, scriptTransformer);
s = require('vm').runInThisContext('(function () { return 10; }());', {});
assert.equal(s, 10);
hook.unhookCreateScript();
hook.unhookRunInThisContext();
});
});
describe('runInContext', function () {
Expand Down

0 comments on commit 1504374

Please sign in to comment.