wallet-core/node_modules/@ava/babel-plugin-throws-helper/index.js
2017-05-28 00:40:43 +02:00

71 lines
1.8 KiB
JavaScript

'use strict';
module.exports = babelCore => {
const t = babelCore.types;
const wrapArg = babelCore.template('(START(t, ASSERTION, FILE, LINE), END(t, ARG))');
const helpers = babelCore.template(`function START(t, assertion, file, line) {
if (t._throwsArgStart) {
t._throwsArgStart(assertion, file, line);
}
}
function END(t, arg) {
if (t._throwsArgEnd) {
t._throwsArgEnd();
}
return arg;
}`);
const assertionVisitor = {
CallExpression(path, state) {
const callee = path.get('callee');
if (!callee.isMemberExpression() || !callee.get('object').isIdentifier({name: 't'}) || !callee.get('property').isIdentifier()) {
return;
}
const assertion = callee.get('property').get('name').node;
if (assertion !== 'throws' && assertion !== 'notThrows') {
return;
}
const arg0 = path.node.arguments[0];
if (!(arg0 && arg0.loc && (typeof arg0.start === 'number') && (typeof arg0.end === 'number'))) {
return;
}
// Wrap the argument expression, so that the stack trace of the assertion
// isn't affected.
path.node.arguments[0] = wrapArg(Object.assign({
ARG: arg0,
ASSERTION: t.stringLiteral(assertion),
FILE: t.stringLiteral(state.file.opts.filename),
LINE: t.numericLiteral(arg0.loc.start.line)
}, this.installHelper())).expression;
}
};
return {
visitor: {
Program(path, state) {
const START = t.identifier(path.scope.generateUid('avaThrowsHelperStart'));
const END = t.identifier(path.scope.generateUid('avaThrowsHelperEnd'));
const helperIdentifiers = {START, END};
let created = false;
path.traverse(assertionVisitor, {
installHelper() {
if (!created) {
created = true;
path.unshiftContainer('body', helpers(helperIdentifiers));
}
return helperIdentifiers;
},
file: state.file
});
}
}
};
};