You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

127 lines
5.3 KiB

2 years ago
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.RULE_NAME = void 0;
const create_testing_library_rule_1 = require("../create-testing-library-rule");
const node_utils_1 = require("../node-utils");
exports.RULE_NAME = 'no-wait-for-side-effects';
exports.default = (0, create_testing_library_rule_1.createTestingLibraryRule)({
name: exports.RULE_NAME,
meta: {
type: 'suggestion',
docs: {
description: 'Disallow the use of side effects in `waitFor`',
recommendedConfig: {
dom: 'error',
angular: 'error',
react: 'error',
vue: 'error',
marko: 'error',
},
},
messages: {
noSideEffectsWaitFor: 'Avoid using side effects within `waitFor` callback',
},
schema: [],
},
defaultOptions: [],
create(context, _, helpers) {
function isCallerWaitFor(node) {
if (!node.parent) {
return false;
}
const callExpressionNode = node.parent.parent;
const callExpressionIdentifier = (0, node_utils_1.getPropertyIdentifierNode)(callExpressionNode);
return (!!callExpressionIdentifier &&
helpers.isAsyncUtil(callExpressionIdentifier, ['waitFor']));
}
function isRenderInVariableDeclaration(node) {
return ((0, node_utils_1.isVariableDeclaration)(node) &&
node.declarations.some(helpers.isRenderVariableDeclarator));
}
function isRenderInExpressionStatement(node) {
if (!(0, node_utils_1.isExpressionStatement)(node) ||
!(0, node_utils_1.isAssignmentExpression)(node.expression)) {
return false;
}
const expressionIdentifier = (0, node_utils_1.getPropertyIdentifierNode)(node.expression.right);
if (!expressionIdentifier) {
return false;
}
return helpers.isRenderUtil(expressionIdentifier);
}
function isRenderInAssignmentExpression(node) {
if (!(0, node_utils_1.isAssignmentExpression)(node)) {
return false;
}
const expressionIdentifier = (0, node_utils_1.getPropertyIdentifierNode)(node.right);
if (!expressionIdentifier) {
return false;
}
return helpers.isRenderUtil(expressionIdentifier);
}
function isRenderInSequenceAssignment(node) {
if (!(0, node_utils_1.isSequenceExpression)(node)) {
return false;
}
return node.expressions.some(isRenderInAssignmentExpression);
}
function getSideEffectNodes(body) {
return body.filter((node) => {
if (!(0, node_utils_1.isExpressionStatement)(node) && !(0, node_utils_1.isVariableDeclaration)(node)) {
return false;
}
if (isRenderInVariableDeclaration(node) ||
isRenderInExpressionStatement(node)) {
return true;
}
const expressionIdentifier = (0, node_utils_1.getPropertyIdentifierNode)(node);
if (!expressionIdentifier) {
return false;
}
return (helpers.isFireEventUtil(expressionIdentifier) ||
helpers.isUserEventUtil(expressionIdentifier) ||
helpers.isRenderUtil(expressionIdentifier));
});
}
function reportSideEffects(node) {
if (!isCallerWaitFor(node)) {
return;
}
getSideEffectNodes(node.body).forEach((sideEffectNode) => context.report({
node: sideEffectNode,
messageId: 'noSideEffectsWaitFor',
}));
}
function reportImplicitReturnSideEffect(node) {
if (!isCallerWaitFor(node)) {
return;
}
const expressionIdentifier = (0, node_utils_1.isCallExpression)(node)
? (0, node_utils_1.getPropertyIdentifierNode)(node.callee)
: null;
if (!expressionIdentifier &&
!isRenderInAssignmentExpression(node) &&
!isRenderInSequenceAssignment(node)) {
return;
}
if (expressionIdentifier &&
!helpers.isFireEventUtil(expressionIdentifier) &&
!helpers.isUserEventUtil(expressionIdentifier) &&
!helpers.isRenderUtil(expressionIdentifier)) {
return;
}
context.report({
node,
messageId: 'noSideEffectsWaitFor',
});
}
return {
'CallExpression > ArrowFunctionExpression > BlockStatement': reportSideEffects,
'CallExpression > ArrowFunctionExpression > CallExpression': reportImplicitReturnSideEffect,
'CallExpression > ArrowFunctionExpression > AssignmentExpression': reportImplicitReturnSideEffect,
'CallExpression > ArrowFunctionExpression > SequenceExpression': reportImplicitReturnSideEffect,
'CallExpression > FunctionExpression > BlockStatement': reportSideEffects,
};
},
});