Skip to content

Commit

Permalink
feat: switch rules over to using scoped jest function checks
Browse files Browse the repository at this point in the history
  • Loading branch information
G-Rath committed Apr 29, 2022
1 parent 0df949e commit 5c96b5a
Show file tree
Hide file tree
Showing 25 changed files with 179 additions and 111 deletions.
9 changes: 5 additions & 4 deletions src/rules/consistent-test-it.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ export default createRule<
},
defaultOptions: [{ fn: TestCaseName.test, withinDescribe: TestCaseName.it }],
create(context) {
const scope = context.getScope();
const configObj = context.options[0] || {};
const testKeyword = configObj.fn || TestCaseName.test;
const testKeywordWithinDescribe =
Expand All @@ -79,7 +80,7 @@ export default createRule<
return;
}

if (isDescribeCall(node)) {
if (isDescribeCall(node, scope)) {
describeNestingLevel++;
}

Expand All @@ -91,7 +92,7 @@ export default createRule<
: node.callee;

if (
isTestCaseCall(node) &&
isTestCaseCall(node, scope) &&
describeNestingLevel === 0 &&
!nodeName.includes(testKeyword)
) {
Expand All @@ -106,7 +107,7 @@ export default createRule<
}

if (
isTestCaseCall(node) &&
isTestCaseCall(node, scope) &&
describeNestingLevel > 0 &&
!nodeName.includes(testKeywordWithinDescribe)
) {
Expand All @@ -123,7 +124,7 @@ export default createRule<
}
},
'CallExpression:exit'(node) {
if (isDescribeCall(node)) {
if (isDescribeCall(node, scope)) {
describeNestingLevel--;
}
},
Expand Down
6 changes: 5 additions & 1 deletion src/rules/expect-expect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ export default createRule<
context,
[{ assertFunctionNames = ['expect'], additionalTestBlockFunctions = [] }],
) {
const scope = context.getScope();
const unchecked: TSESTree.CallExpression[] = [];

function checkCallExpressionUsed(nodes: TSESTree.Node[]) {
Expand All @@ -94,7 +95,10 @@ export default createRule<
if (node.type === AST_NODE_TYPES.FunctionDeclaration) {
const declaredVariables = context.getDeclaredVariables(node);
const testCallExpressions =
getTestCallExpressionsFromDeclaredVariables(declaredVariables);
getTestCallExpressionsFromDeclaredVariables(
declaredVariables,
scope,
);

checkCallExpressionUsed(testCallExpressions);
}
Expand Down
5 changes: 3 additions & 2 deletions src/rules/max-nested-describe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export default createRule({
},
defaultOptions: [{ max: 5 }],
create(context, [{ max }]) {
const scope = context.getScope();
const describeCallbackStack: number[] = [];

function pushDescribeCallback(
Expand All @@ -38,7 +39,7 @@ export default createRule({

if (
parent?.type !== AST_NODE_TYPES.CallExpression ||
!isDescribeCall(parent)
!isDescribeCall(parent, scope)
) {
return;
}
Expand All @@ -61,7 +62,7 @@ export default createRule({

if (
parent?.type === AST_NODE_TYPES.CallExpression &&
isDescribeCall(parent)
isDescribeCall(parent, scope)
) {
describeCallbackStack.pop();
}
Expand Down
11 changes: 7 additions & 4 deletions src/rules/no-conditional-expect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export default createRule({
},
defaultOptions: [],
create(context) {
const scope = context.getScope();
let conditionalDepth = 0;
let inTestCase = false;
let inPromiseCatch = false;
Expand All @@ -40,15 +41,17 @@ export default createRule({
return {
FunctionDeclaration(node) {
const declaredVariables = context.getDeclaredVariables(node);
const testCallExpressions =
getTestCallExpressionsFromDeclaredVariables(declaredVariables);
const testCallExpressions = getTestCallExpressionsFromDeclaredVariables(
declaredVariables,
scope,
);

if (testCallExpressions.length > 0) {
inTestCase = true;
}
},
CallExpression(node: TSESTree.CallExpression) {
if (isTestCaseCall(node)) {
if (isTestCaseCall(node, scope)) {
inTestCase = true;
}

Expand All @@ -71,7 +74,7 @@ export default createRule({
}
},
'CallExpression:exit'(node) {
if (isTestCaseCall(node)) {
if (isTestCaseCall(node, scope)) {
inTestCase = false;
}

Expand Down
5 changes: 3 additions & 2 deletions src/rules/no-conditional-in-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export default createRule({
},
defaultOptions: [],
create(context) {
const scope = context.getScope();
let inTestCase = false;

const maybeReportConditional = (node: TSESTree.Node) => {
Expand All @@ -30,12 +31,12 @@ export default createRule({

return {
CallExpression(node: TSESTree.CallExpression) {
if (isTestCaseCall(node)) {
if (isTestCaseCall(node, scope)) {
inTestCase = true;
}
},
'CallExpression:exit'(node) {
if (isTestCaseCall(node)) {
if (isTestCaseCall(node, scope)) {
inTestCase = false;
}
},
Expand Down
9 changes: 6 additions & 3 deletions src/rules/no-done-callback.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { AST_NODE_TYPES, TSESTree } from '@typescript-eslint/utils';
import { AST_NODE_TYPES, TSESLint, TSESTree } from '@typescript-eslint/utils';
import {
createRule,
getNodeName,
Expand All @@ -10,6 +10,7 @@ import {
const findCallbackArg = (
node: TSESTree.CallExpression,
isJestEach: boolean,
scope: TSESLint.Scope.Scope,
): TSESTree.CallExpression['arguments'][0] | null => {
if (isJestEach) {
return node.arguments[1];
Expand All @@ -19,7 +20,7 @@ const findCallbackArg = (
return node.arguments[0];
}

if (isTestCaseCall(node) && node.arguments.length >= 2) {
if (isTestCaseCall(node, scope) && node.arguments.length >= 2) {
return node.arguments[1];
}

Expand Down Expand Up @@ -48,6 +49,8 @@ export default createRule({
},
defaultOptions: [],
create(context) {
const scope = context.getScope();

return {
CallExpression(node) {
// done is the second argument for it.each, not the first
Expand All @@ -63,7 +66,7 @@ export default createRule({
return;
}

const callback = findCallbackArg(node, isJestEach);
const callback = findCallbackArg(node, isJestEach, scope);
const callbackArgIndex = Number(isJestEach);

if (
Expand Down
5 changes: 3 additions & 2 deletions src/rules/no-duplicate-hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,12 @@ export default createRule({
},
defaultOptions: [],
create(context) {
const scope = context.getScope();
const hookContexts = [newHookContext()];

return {
CallExpression(node) {
if (isDescribeCall(node)) {
if (isDescribeCall(node, scope)) {
hookContexts.push(newHookContext());
}

Expand All @@ -45,7 +46,7 @@ export default createRule({
}
},
'CallExpression:exit'(node) {
if (isDescribeCall(node)) {
if (isDescribeCall(node, scope)) {
hookContexts.pop();
}
},
Expand Down
3 changes: 2 additions & 1 deletion src/rules/no-export.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export default createRule({
},
defaultOptions: [],
create(context) {
const scope = context.getScope();
const exportNodes: Array<
| TSESTree.ExportNamedDeclaration
| TSESTree.ExportDefaultDeclaration
Expand All @@ -34,7 +35,7 @@ export default createRule({
},

CallExpression(node) {
if (isTestCaseCall(node)) {
if (isTestCaseCall(node, scope)) {
hasTestCase = true;
}
},
Expand Down
74 changes: 39 additions & 35 deletions src/rules/no-focused-tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,49 +52,53 @@ export default createRule({
hasSuggestions: true,
},
defaultOptions: [],
create: context => ({
CallExpression(node) {
if (!isDescribeCall(node) && !isTestCaseCall(node)) {
return;
}
create(context) {
const scope = context.getScope();

return {
CallExpression(node) {
if (!isDescribeCall(node, scope) && !isTestCaseCall(node, scope)) {
return;
}

if (getNodeName(node).startsWith('f')) {
context.report({
messageId: 'focusedTest',
node,
suggest: [
{
messageId: 'suggestRemoveFocus',
fix: fixer =>
fixer.removeRange([node.range[0], node.range[0] + 1]),
},
],
});

return;
}

const onlyNode = findOnlyNode(node);

if (!onlyNode) {
return;
}

if (getNodeName(node).startsWith('f')) {
context.report({
messageId: 'focusedTest',
node,
node: onlyNode,
suggest: [
{
messageId: 'suggestRemoveFocus',
fix: fixer =>
fixer.removeRange([node.range[0], node.range[0] + 1]),
fixer.removeRange([
onlyNode.range[0] - 1,
onlyNode.range[1] +
Number(onlyNode.type !== AST_NODE_TYPES.Identifier),
]),
},
],
});

return;
}

const onlyNode = findOnlyNode(node);

if (!onlyNode) {
return;
}

context.report({
messageId: 'focusedTest',
node: onlyNode,
suggest: [
{
messageId: 'suggestRemoveFocus',
fix: fixer =>
fixer.removeRange([
onlyNode.range[0] - 1,
onlyNode.range[1] +
Number(onlyNode.type !== AST_NODE_TYPES.Identifier),
]),
},
],
});
},
}),
},
};
},
});
9 changes: 5 additions & 4 deletions src/rules/no-identical-title.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,14 @@ export default createRule({
},
defaultOptions: [],
create(context) {
const scope = context.getScope();
const contexts = [newDescribeContext()];

return {
CallExpression(node) {
const currentLayer = contexts[contexts.length - 1];

if (isDescribeCall(node)) {
if (isDescribeCall(node, scope)) {
contexts.push(newDescribeContext());
}

Expand All @@ -58,7 +59,7 @@ export default createRule({

const title = getStringValue(argument);

if (isTestCaseCall(node)) {
if (isTestCaseCall(node, scope)) {
if (currentLayer.testTitles.includes(title)) {
context.report({
messageId: 'multipleTestTitle',
Expand All @@ -68,7 +69,7 @@ export default createRule({
currentLayer.testTitles.push(title);
}

if (!isDescribeCall(node)) {
if (!isDescribeCall(node, scope)) {
return;
}
if (currentLayer.describeTitles.includes(title)) {
Expand All @@ -80,7 +81,7 @@ export default createRule({
currentLayer.describeTitles.push(title);
},
'CallExpression:exit'(node) {
if (isDescribeCall(node)) {
if (isDescribeCall(node, scope)) {
contexts.pop();
}
},
Expand Down
9 changes: 6 additions & 3 deletions src/rules/no-if.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ export default createRule({
},
defaultOptions: [],
create(context) {
const scope = context.getScope();
const stack: boolean[] = [];

function validate(
Expand All @@ -74,7 +75,7 @@ export default createRule({

return {
CallExpression(node) {
if (isTestCaseCall(node)) {
if (isTestCaseCall(node, scope)) {
stack.push(true);

if (getNodeName(node).endsWith('each')) {
Expand All @@ -87,8 +88,10 @@ export default createRule({
},
FunctionDeclaration(node) {
const declaredVariables = context.getDeclaredVariables(node);
const testCallExpressions =
getTestCallExpressionsFromDeclaredVariables(declaredVariables);
const testCallExpressions = getTestCallExpressionsFromDeclaredVariables(
declaredVariables,
scope,
);

stack.push(testCallExpressions.length > 0);
},
Expand Down

0 comments on commit 5c96b5a

Please sign in to comment.