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.
 
 
 
 

116 lines
3.3 KiB

'use strict';
const createAstUtils = require('../util/ast');
const FUNCTION = 1;
const DESCRIBE = 2;
// "Pure" nodes are hooks (like `beforeEach`) or `it` calls
const PURE = 3;
module.exports = {
meta: {
type: 'suggestion',
docs: {
description: 'Disallow setup in describe blocks'
}
},
create(context) {
const nesting = [];
const astUtils = createAstUtils(context.settings);
function isPureNode(node) {
return astUtils.isHookCall(node) ||
astUtils.isTestCase(node) ||
astUtils.isSuiteConfigCall(node);
}
function reportCallExpression(callExpression) {
const message = 'Unexpected function call in describe block.';
context.report({
message,
node: callExpression.callee
});
}
function reportMemberExpression(memberExpression) {
const message = 'Unexpected member expression in describe block. ' +
'Member expressions may call functions via getters.';
context.report({
message,
node: memberExpression
});
}
function isNestedInDescribeBlock() {
return nesting.length &&
!nesting.includes(PURE) &&
nesting.lastIndexOf(FUNCTION) < nesting.lastIndexOf(DESCRIBE);
}
function handleCallExpressionInDescribe(node) {
if (isPureNode(node)) {
nesting.push(PURE);
} else if (isNestedInDescribeBlock()) {
reportCallExpression(node);
}
}
function isDescribe(node) {
return astUtils.isDescribe(node);
}
function isParentDescribe(node) {
return isDescribe(node.parent);
}
return {
CallExpression(node) {
if (isDescribe(node)) {
nesting.push(DESCRIBE);
return;
}
// don't process anything else if the first describe hasn't been processed
if (!nesting.length) {
return;
}
handleCallExpressionInDescribe(node);
},
'CallExpression:exit'(node) {
if (isDescribe(node) || nesting.length && isPureNode(node)) {
nesting.pop();
}
},
MemberExpression(node) {
if (!isDescribe(node.parent) && isNestedInDescribeBlock()) {
reportMemberExpression(node);
}
},
FunctionDeclaration() {
if (nesting.length) {
nesting.push(FUNCTION);
}
},
'FunctionDeclaration:exit'() {
if (nesting.length) {
nesting.pop();
}
},
ArrowFunctionExpression(node) {
if (nesting.length && !isParentDescribe(node)) {
nesting.push(FUNCTION);
}
},
'ArrowFunctionExpression:exit'(node) {
if (nesting.length && !isParentDescribe(node)) {
nesting.pop();
}
}
};
}
};