eslint-plugin-jest
Version:
Eslint rules for Jest
130 lines (110 loc) • 3.63 kB
JavaScript
const {
getDocsUrl,
expectCase,
expectResolveCase,
expectRejectCase,
method,
argument,
} = require('./util');
const isEqualityCheck = node =>
method(node) &&
(method(node).name === 'toBe' || method(node).name === 'toEqual');
const isArgumentValid = node =>
argument(node).value === true || argument(node).value === false;
const hasOneArgument = node => node.arguments && node.arguments.length === 1;
const isValidEqualityCheck = node =>
isEqualityCheck(node) &&
hasOneArgument(node.parent.parent) &&
isArgumentValid(node);
const isEqualityNegation = node =>
method(node).name === 'not' && isValidEqualityCheck(node.parent);
const hasIncludesMethod = node =>
node.arguments[0] &&
node.arguments[0].callee &&
node.arguments[0].callee.property &&
node.arguments[0].callee.property.name === 'includes';
const isValidIncludesMethod = node =>
hasIncludesMethod(node) && hasOneArgument(node.arguments[0]);
const getNegationFixes = (node, sourceCode, fixer) => {
const negationPropertyDot = sourceCode.getFirstTokenBetween(
node.parent.object,
node.parent.property,
token => token.value === '.'
);
const toContainFunc =
isEqualityNegation(node) && argument(node.parent).value
? 'not.toContain'
: 'toContain';
//.includes function argument
const [containArg] = node.arguments[0].arguments;
return [
fixer.remove(negationPropertyDot),
fixer.remove(method(node)),
fixer.replaceText(method(node.parent), toContainFunc),
fixer.replaceText(argument(node.parent), sourceCode.getText(containArg)),
];
};
const getCommonFixes = (node, sourceCode, fixer) => {
const [containArg] = node.arguments[0].arguments;
const includesCaller = node.arguments[0].callee;
const propertyDot = sourceCode.getFirstTokenBetween(
includesCaller.object,
includesCaller.property,
token => token.value === '.'
);
const closingParenthesis = sourceCode.getTokenAfter(containArg);
const openParenthesis = sourceCode.getTokenBefore(containArg);
return [
fixer.remove(containArg),
fixer.remove(includesCaller.property),
fixer.remove(propertyDot),
fixer.remove(closingParenthesis),
fixer.remove(openParenthesis),
];
};
module.exports = {
meta: {
docs: {
url: getDocsUrl(__filename),
},
fixable: 'code',
},
create(context) {
return {
CallExpression(node) {
if (
!(expectResolveCase(node) || expectRejectCase(node)) &&
expectCase(node) &&
(isEqualityNegation(node) || isValidEqualityCheck(node)) &&
isValidIncludesMethod(node)
) {
context.report({
fix(fixer) {
const sourceCode = context.getSourceCode();
let fixArr = getCommonFixes(node, sourceCode, fixer);
if (isEqualityNegation(node)) {
return getNegationFixes(node, sourceCode, fixer).concat(fixArr);
}
const toContainFunc = argument(node).value
? 'toContain'
: 'not.toContain';
//.includes function argument
const [containArg] = node.arguments[0].arguments;
fixArr.push(fixer.replaceText(method(node), toContainFunc));
fixArr.push(
fixer.replaceText(
argument(node),
sourceCode.getText(containArg)
)
);
return fixArr;
},
message: 'Use toContain() instead',
node: method(node),
});
}
},
};
},
};
;