71 lines
1.8 KiB
JavaScript
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
|
|
});
|
|
}
|
|
}
|
|
};
|
|
};
|