Skip to content

Commit

Permalink
wip - support compilation of "helper" modules
Browse files Browse the repository at this point in the history
  • Loading branch information
jamestalmage committed Nov 10, 2015
1 parent 4399e7b commit f1973b9
Show file tree
Hide file tree
Showing 8 changed files with 96 additions and 20 deletions.
73 changes: 59 additions & 14 deletions lib/babel.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
'use strict';
var path = require('path');
var resolveFrom = require('resolve-from');
var createEspowerPlugin = require('babel-plugin-espower/create');
var requireFromString = require('require-from-string');

var hasGenerators = parseInt(process.version.slice(1), 10) > 0;
var testPath = process.argv[2];
var testDir = path.dirname(testPath);
var Module = module.constructor;
var babel;

try {
Expand All @@ -14,17 +17,59 @@ try {
babel = require('babel-core');
}

var options = {
blacklist: hasGenerators ? ['regenerator'] : [],
optional: hasGenerators ? ['asyncToGenerator', 'runtime'] : ['runtime'],
plugins: [
createEspowerPlugin(babel, {
patterns: require('./enhance-assert').PATTERNS
})
]
};

var transpiled = babel.transformFileSync(testPath, options);
requireFromString(transpiled.code, testPath, {
appendPaths: module.paths
});
function options() {
return {
blacklist: hasGenerators ? ['regenerator'] : [],
optional: hasGenerators ? ['asyncToGenerator', 'runtime'] : ['runtime'],
plugins: [
createEspowerPlugin(babel, {
patterns: require('./enhance-assert').PATTERNS
})
]
};
}

// TODO: This needs to be smarter.
function shouldTranspile(filePath) {
var fileName = path.basename(filePath);
return testDir === path.dirname(filePath) && fileName[0] === '_' || filePath === testPath;
}

function requireHook(file) {
// Most of this is Module._load with a few modifications.

file = Module._resolveFilename(file, this);

var cachedModule = Module._cache[file];
if (cachedModule) {
return cachedModule.exports;
}

if (shouldTranspile(file)) {
var code = babel.transformFileSync(file, options()).code;

var hadException = true;

var m = requireFromString.load(file, {
appendPaths: module.paths,
require: requireHook
});

try {
Module._cache[file] = m;

m._compile(code, file);

hadException = false;
} finally {
if (hadException) {
delete Module._cache[file];
}
}

return m.exports;
}
return Module._load(file, this);
}

requireHook.call(module, testPath);
2 changes: 1 addition & 1 deletion lib/fork.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ module.exports = function (args) {

ps.on('exit', function (code) {
if (code > 0 && code !== 143) {
reject();
reject(new Error(file + ' exited with error code ' + code));
} else {
resolve(testResults);
}
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@
"power-assert-formatter": "^1.3.0",
"power-assert-renderers": "^0.1.0",
"pretty-ms": "^2.0.0",
"require-from-string": "^1.1.0",
"require-from-string": "jamestalmage/require-from-string#allow-transforms",
"resolve-from": "^1.0.0",
"serialize-error": "^1.0.0",
"set-immediate-shim": "^1.0.1",
Expand Down
5 changes: 5 additions & 0 deletions test/fixture/_es6-helper.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
'use strict';

export default function () {
return Promise.resolve('es6').then(prefix => prefix + ' helper');
}
2 changes: 1 addition & 1 deletion test/fixture/babel-hook-imported.js
Original file line number Diff line number Diff line change
@@ -1 +1 @@
module.export = async () => {};
module.exports = async () => {};
9 changes: 9 additions & 0 deletions test/fixture/uses-es6-helper.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
'use strict';
import test from '../../';

import helper from './_es6-helper';

test(async t => {
t.is(await helper(), 'es6 helper');
t.end();
});
2 changes: 1 addition & 1 deletion test/fork.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ test('rejects on error and streams output', function (t) {
buffer += data;
})
.catch(function () {
t.ok(/no such file or directory/.test(buffer));
t.ok(/Cannot find module/.test(buffer));
t.end();
});
});
Expand Down
21 changes: 19 additions & 2 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -963,10 +963,27 @@ test('change process.cwd() to a test\'s directory', function (t) {
});
});

test('Babel require hook only applies to the test file', function (t) {
execCli('fixture/babel-hook.js', function (err) {
test('Babel require hook does apply to helpers ("_" prefix)', function (t) {
t.plan(1);

execCli('fixture/uses-es6-helper.js', function (err) {
t.ifError(err);
t.end();
});
});

test('Babel require does not apply to non-helper (no "_" prefix)', function (t) {
execCli('fixture/babel-hook.js', function (err, stdout) {
// TODO: This test was passing for the wrong reasons. Make sure this gets fixed in master regardless.
t.ok(err);
t.is(err.code, 1);

// module.exports = async () => {};
// ^
// SyntaxError: Unexpected reserved word

// TODO: Why standard error?
t.true(/module.exports = async \(\) => \{\};\s*\n.*?\n.*?Unexpected token >/.test(stdout));
t.end();
});
});
Expand Down

0 comments on commit f1973b9

Please sign in to comment.