UNPKG

eslint-plugin-ava

Version:
112 lines (95 loc) 2.56 kB
import createAvaRule, {visitIf} from '../create-ava-rule.js'; import util from '../util.js'; const MESSAGE_ID = 'no-negated-assertion'; const negatedPairs = { assert: 'falsy', true: 'falsy', false: 'truthy', truthy: 'falsy', falsy: 'truthy', }; const doubleNegatedPairs = { assert: 'truthy', true: 'truthy', false: 'falsy', truthy: 'truthy', falsy: 'falsy', }; const getArgumentText = (source, argument) => argument.type === 'SequenceExpression' ? `(${source.getText(argument)})` : source.getText(argument); const create = context => { const ava = createAvaRule(context.sourceCode); return ava.merge({ CallExpression: visitIf([ ava.isInTestFile, ava.isInTestNode, ])(node => { if (node.callee.type !== 'MemberExpression') { return; } const root = util.getRootNode(node.callee); if (!util.isTestObject(root.object.name)) { return; } const methodName = util.getAssertionName(node.callee); if (!methodName || !negatedPairs[methodName]) { return; } const argument = node.arguments[0]; if (!argument || argument.type !== 'UnaryExpression' || argument.operator !== '!') { return; } // Double negation: `t.true(!!x)` → `t.truthy(x)` to preserve behavior for non-boolean values. if (argument.argument.type === 'UnaryExpression' && argument.argument.operator === '!') { const replacement = doubleNegatedPairs[methodName]; context.report({ node, messageId: MESSAGE_ID, data: { assertion: methodName, replacement, }, fix(fixer) { const source = context.sourceCode; return [ fixer.replaceText(root.property, replacement), fixer.replaceText(argument, getArgumentText(source, argument.argument.argument)), ]; }, }); return; } const replacement = negatedPairs[methodName]; context.report({ node, messageId: MESSAGE_ID, data: { assertion: methodName, replacement, }, fix(fixer) { const source = context.sourceCode; return [ fixer.replaceText(root.property, replacement), fixer.replaceText(argument, getArgumentText(source, argument.argument)), ]; }, }); }), }); }; export default { create, meta: { type: 'suggestion', docs: { description: 'Disallow negated assertions.', recommended: true, url: util.getDocsUrl(import.meta.filename), }, fixable: 'code', schema: [], messages: { [MESSAGE_ID]: 'Prefer `t.{{replacement}}()` over negating the argument of `t.{{assertion}}()`.', }, }, };