diff --git a/lib/babel.js b/lib/babel.js index 24efb4df0..7828c7596 100644 --- a/lib/babel.js +++ b/lib/babel.js @@ -25,7 +25,8 @@ sourceMapSupport.install({ }); var createEspowerPlugin = require('babel-plugin-espower/create'); -var requireFromString = require('require-from-string'); +var libHook = require('istanbul-lib-hook'); +var path = require('path'); var loudRejection = require('loud-rejection/api')(process); var resolveFrom = require('resolve-from'); var hasGenerator = require('has-generator'); @@ -49,15 +50,6 @@ var powerAssert = createEspowerPlugin(babel, { patterns: require('./enhance-assert').PATTERNS }); -// if generators are not supported, use regenerator -var options = { - blacklist: hasGenerator ? ['regenerator'] : [], - optional: hasGenerator ? ['asyncToGenerator', 'runtime'] : ['runtime'], - plugins: [powerAssert], - sourceMaps: true, - inputSourceMap: null -}; - // check if test files required ava and show error, when they didn't exports.avaRequired = false; @@ -65,21 +57,49 @@ process.on('uncaughtException', function (exception) { send('uncaughtException', {exception: serializeError(exception)}); }); -// try to load an input source map for the test file, in case the file was -// already compiled once by the user -var inputSourceMap = sourceMapSupport.retrieveSourceMap(testPath); -if (inputSourceMap) { - // source-map-support returns the source map as a json-encoded string, but - // babel requires an actual object - options.inputSourceMap = JSON.parse(inputSourceMap.map); +// Append AVA's node_modules paths, this is so users don't need to install Babel as a dependency. +var Module = module.constructor; +var originalNodeModulePaths = Module._nodeModulePaths; +var pathToAppend = path.join(__dirname, '../node_modules'); +Module._nodeModulePaths = function () { + var paths = originalNodeModulePaths.apply(this, arguments); + return paths.concat([pathToAppend]); +}; + +// Install a require hook. + +// Currently only matches the test file. Easy to extend. +function matcher(file) { + return file === testPath; } -// include test file -var transpiled = babel.transformFileSync(testPath, options); -sourceMapCache[testPath] = transpiled.map; -requireFromString(transpiled.code, testPath, { - appendPaths: module.paths -}); +function transform(code, file) { + // if generators are not supported, use regenerator + var options = { + blacklist: hasGenerator ? ['regenerator'] : [], + optional: hasGenerator ? ['asyncToGenerator', 'runtime'] : ['runtime'], + plugins: [powerAssert], + sourceMaps: true, + filename: file + }; + + // try to load an input source map for the test file, in case the file was + // already compiled once by the user + var inputSourceMap = sourceMapSupport.retrieveSourceMap(file); + if (inputSourceMap) { + // source-map-support returns the source map as a json-encoded string, but + // babel requires an actual object + options.inputSourceMap = JSON.parse(inputSourceMap.map); + } + + var transpiled = babel.transform(code, options); + sourceMapCache[testPath] = transpiled.map; + return transpiled.code; +} + +libHook.hookRequire(matcher, transform); + +require(testPath); // if ava was not required, show an error if (!exports.avaRequired) { diff --git a/package.json b/package.json index d7171dce8..2d7f778db 100644 --- a/package.json +++ b/package.json @@ -96,6 +96,7 @@ "is-generator-fn": "^1.0.0", "is-observable": "^0.1.0", "is-promise": "^2.1.0", + "istanbul-lib-hook": "^1.0.0-alpha.3", "loud-rejection": "^1.2.0", "max-timeout": "^1.0.0", "meow": "^3.6.0", diff --git a/test/fork.js b/test/fork.js index 3cca1df6c..b3fdad8ba 100644 --- a/test/fork.js +++ b/test/fork.js @@ -39,7 +39,7 @@ test('rejects on error and streams output', function (t) { fork(fixture('broken.js')) .run() .on('uncaughtException', function (data) { - t.true(/no such file or directory/.test(data.exception.message)); + t.match(data.exception.message, /Cannot find module /); }) .catch(function () { t.pass();