diff options
Diffstat (limited to 'node_modules/@ava/babel-plugin-throws-helper/index.js')
-rw-r--r-- | node_modules/@ava/babel-plugin-throws-helper/index.js | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/node_modules/@ava/babel-plugin-throws-helper/index.js b/node_modules/@ava/babel-plugin-throws-helper/index.js new file mode 100644 index 000000000..e370480f1 --- /dev/null +++ b/node_modules/@ava/babel-plugin-throws-helper/index.js @@ -0,0 +1,70 @@ +'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 + }); + } + } + }; +}; |