You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
80 lines
1.9 KiB
JavaScript
80 lines
1.9 KiB
JavaScript
'use strict';
|
|
var t = require('babel-types');
|
|
var template = require('babel-template');
|
|
|
|
var wrapWithHelper = template([
|
|
'HELPER_ID(function () {',
|
|
' return EXP;',
|
|
'}, {',
|
|
' line: LINE,',
|
|
' column: COLUMN,',
|
|
' source: SOURCE,',
|
|
' filename: FILE',
|
|
'});'
|
|
].join('\n'));
|
|
|
|
var buildHelper = template([
|
|
'function HELPER_ID(fn, data) {',
|
|
' try {',
|
|
' return fn();',
|
|
' } catch (e) {',
|
|
' var type = typeof e;',
|
|
' if (e !== null && (type === "object" || type === "function")) {',
|
|
' try {',
|
|
' Object.defineProperty(e, "_avaThrowsHelperData", {',
|
|
' value: data',
|
|
' });',
|
|
' } catch (e) {}',
|
|
' }',
|
|
' throw e;',
|
|
' }',
|
|
'}'
|
|
].join('\n'));
|
|
|
|
var assertionVisitor = {
|
|
CallExpression: function (path, state) {
|
|
if (isThrowsMember(path.get('callee'))) {
|
|
var arg0 = path.node.arguments[0];
|
|
path.node.arguments[0] = wrapWithHelper({
|
|
HELPER_ID: t.identifier(this.avaThrowHelper()),
|
|
EXP: arg0,
|
|
LINE: t.numericLiteral(arg0.loc.start.line),
|
|
COLUMN: t.numericLiteral(arg0.loc.start.column),
|
|
SOURCE: t.stringLiteral(state.file.code.substring(arg0.start, arg0.end)),
|
|
FILE: t.stringLiteral(state.file.opts.filename)
|
|
}).expression;
|
|
}
|
|
}
|
|
};
|
|
|
|
module.exports = function () {
|
|
return {
|
|
visitor: {
|
|
Program: function (path, state) {
|
|
var HELPER_ID = path.scope.generateUid('avaThrowsHelper');
|
|
var created = false;
|
|
|
|
path.traverse(assertionVisitor, {
|
|
avaThrowHelper: function () {
|
|
if (!created) {
|
|
created = true;
|
|
path.unshiftContainer('body', buildHelper({
|
|
HELPER_ID: t.identifier(HELPER_ID)
|
|
}));
|
|
}
|
|
return HELPER_ID;
|
|
},
|
|
file: state.file
|
|
});
|
|
}
|
|
}
|
|
};
|
|
};
|
|
|
|
function isThrowsMember(path) {
|
|
return path.isMemberExpression() && path.get('object').isIdentifier({name: 't'}) && (
|
|
path.get('property').isIdentifier({name: 'throws'}) ||
|
|
path.get('property').isIdentifier({name: 'notThrows'})
|
|
);
|
|
}
|