diff --git a/packages/istanbul-api/lib/run-cover.js b/packages/istanbul-api/lib/run-cover.js index f61e18e3..5e5f54d3 100644 --- a/packages/istanbul-api/lib/run-cover.js +++ b/packages/istanbul-api/lib/run-cover.js @@ -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'), @@ -33,6 +34,8 @@ function getCoverFunctions(config, includes, callback) { sourceMapStore = libSourceMaps.createSourceMapStore({}), instrumenter, transformer, + runInContextTransformer, + runInThisContextTransformer, fakeRequire, requireTransformer, reportInitFn, @@ -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) { @@ -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) { diff --git a/packages/istanbul-api/package.json b/packages/istanbul-api/package.json index b0956833..fbe4342b 100644 --- a/packages/istanbul-api/package.json +++ b/packages/istanbul-api/package.json @@ -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", diff --git a/packages/istanbul-api/test/run-check-coverage.test.js b/packages/istanbul-api/test/run-check-coverage.test.js index a9aa4130..da818e3f 100644 --- a/packages/istanbul-api/test/run-check-coverage.test.js +++ b/packages/istanbul-api/test/run-check-coverage.test.js @@ -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 diff --git a/packages/istanbul-api/test/sample-code/context.js b/packages/istanbul-api/test/sample-code/context.js index 805c9988..2794bfd1 100644 --- a/packages/istanbul-api/test/sample-code/context.js +++ b/packages/istanbul-api/test/sample-code/context.js @@ -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 +}); diff --git a/packages/istanbul-lib-hook/lib/hook.js b/packages/istanbul-lib-hook/lib/hook.js index df3162fa..cba40fd2 100644 --- a/packages/istanbul-lib-hook/lib/hook.js +++ b/packages/istanbul-lib-hook/lib/hook.js @@ -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); @@ -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); }; } /** diff --git a/packages/istanbul-lib-hook/test/hook.test.js b/packages/istanbul-lib-hook/test/hook.test.js index e8d5e75c..5967df29 100644 --- a/packages/istanbul-lib-hook/test/hook.test.js +++ b/packages/istanbul-lib-hook/test/hook.test.js @@ -144,10 +144,10 @@ 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 () { @@ -155,14 +155,14 @@ describe('hooks', function () { 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 () {