Skip to content

Commit 7430be3

Browse files
committed
refactor(no-wait-for-empty-callback): use new rule creator and helpers
1 parent 50727e6 commit 7430be3

File tree

3 files changed

+54
-20
lines changed

3 files changed

+54
-20
lines changed

lib/detect-testing-library-utils.ts

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import {
2222
ASYNC_UTILS,
2323
PRESENCE_MATCHERS,
2424
ALL_QUERIES_COMBINATIONS,
25+
VALID_ASYNC_UTILS,
2526
} from './utils';
2627

2728
export type TestingLibrarySettings = {
@@ -62,7 +63,10 @@ type IsFindQueryVariantFn = (node: TSESTree.Identifier) => boolean;
6263
type IsSyncQueryFn = (node: TSESTree.Identifier) => boolean;
6364
type IsAsyncQueryFn = (node: TSESTree.Identifier) => boolean;
6465
type IsCustomQueryFn = (node: TSESTree.Identifier) => boolean;
65-
type IsAsyncUtilFn = (node: TSESTree.Identifier) => boolean;
66+
type IsAsyncUtilFn = (
67+
node: TSESTree.Identifier,
68+
validNames?: VALID_ASYNC_UTILS[]
69+
) => boolean;
6670
type IsFireEventMethodFn = (node: TSESTree.Identifier) => boolean;
6771
type IsRenderUtilFn = (node: TSESTree.Identifier) => boolean;
6872
type IsPresenceAssertFn = (node: TSESTree.MemberExpression) => boolean;
@@ -291,10 +295,13 @@ export function detectTestingLibraryUtils<
291295
* Otherwise, it means `custom-module` has been set up, so only those nodes
292296
* coming from Testing Library will be considered as valid.
293297
*/
294-
const isAsyncUtil: IsAsyncUtilFn = (node) => {
295-
return isTestingLibraryUtil(node, (identifierNodeName) =>
296-
ASYNC_UTILS.includes(identifierNodeName)
297-
);
298+
const isAsyncUtil: IsAsyncUtilFn = (node, validNames) => {
299+
return isTestingLibraryUtil(node, (identifierNodeName) => {
300+
if (validNames && validNames.length > 0) {
301+
return (validNames as string[]).includes(identifierNodeName);
302+
}
303+
return ASYNC_UTILS.includes(identifierNodeName);
304+
});
298305
};
299306

300307
/**

lib/rules/no-wait-for-empty-callback.ts

Lines changed: 35 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,16 @@
1+
import { ASTUtils, TSESTree } from '@typescript-eslint/experimental-utils';
12
import {
2-
ESLintUtils,
3-
TSESTree,
4-
ASTUtils,
5-
} from '@typescript-eslint/experimental-utils';
6-
import { getDocsUrl } from '../utils';
7-
import { isBlockStatement, isCallExpression } from '../node-utils';
3+
getPropertyIdentifierNode,
4+
isBlockStatement,
5+
isCallExpression,
6+
} from '../node-utils';
7+
import { createTestingLibraryRule } from '../create-testing-library-rule';
88

99
export const RULE_NAME = 'no-wait-for-empty-callback';
1010
export type MessageIds = 'noWaitForEmptyCallback';
1111
type Options = [];
1212

13-
const WAIT_EXPRESSION_QUERY =
14-
'CallExpression[callee.name=/^(waitFor|waitForElementToBeRemoved)$/]';
15-
16-
export default ESLintUtils.RuleCreator(getDocsUrl)<Options, MessageIds>({
13+
export default createTestingLibraryRule<Options, MessageIds>({
1714
name: RULE_NAME,
1815
meta: {
1916
type: 'suggestion',
@@ -33,11 +30,24 @@ export default ESLintUtils.RuleCreator(getDocsUrl)<Options, MessageIds>({
3330
defaultOptions: [],
3431

3532
// trimmed down implementation of https://github.com/eslint/eslint/blob/master/lib/rules/no-empty-function.js
36-
// TODO: var referencing any of previously mentioned?
37-
create: function (context) {
33+
create(context, _, helpers) {
34+
function isValidWaitFor(node: TSESTree.Node): boolean {
35+
const parentCallExpression = node.parent as TSESTree.CallExpression;
36+
const parentIdentifier = getPropertyIdentifierNode(parentCallExpression);
37+
38+
return helpers.isAsyncUtil(parentIdentifier, [
39+
'waitFor',
40+
'waitForElementToBeRemoved',
41+
]);
42+
}
43+
3844
function reportIfEmpty(
3945
node: TSESTree.ArrowFunctionExpression | TSESTree.FunctionExpression
4046
) {
47+
if (!isValidWaitFor(node)) {
48+
return;
49+
}
50+
4151
if (
4252
isBlockStatement(node.body) &&
4353
node.body.body.length === 0 &&
@@ -56,17 +66,27 @@ export default ESLintUtils.RuleCreator(getDocsUrl)<Options, MessageIds>({
5666
}
5767

5868
function reportNoop(node: TSESTree.Identifier) {
69+
if (!isValidWaitFor(node)) {
70+
return;
71+
}
72+
5973
context.report({
6074
node,
6175
loc: node.loc.start,
6276
messageId: 'noWaitForEmptyCallback',
77+
data: {
78+
methodName:
79+
isCallExpression(node.parent) &&
80+
ASTUtils.isIdentifier(node.parent.callee) &&
81+
node.parent.callee.name,
82+
},
6383
});
6484
}
6585

6686
return {
67-
[`${WAIT_EXPRESSION_QUERY} > ArrowFunctionExpression`]: reportIfEmpty,
68-
[`${WAIT_EXPRESSION_QUERY} > FunctionExpression`]: reportIfEmpty,
69-
[`${WAIT_EXPRESSION_QUERY} > Identifier[name="noop"]`]: reportNoop,
87+
'CallExpression > ArrowFunctionExpression': reportIfEmpty,
88+
'CallExpression > FunctionExpression': reportIfEmpty,
89+
'CallExpression > Identifier[name="noop"]': reportNoop,
7090
};
7191
},
7292
});

lib/utils.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,13 @@ const ALL_RETURNING_NODES = [
114114
const PRESENCE_MATCHERS = ['toBeInTheDocument', 'toBeTruthy', 'toBeDefined'];
115115
const ABSENCE_MATCHERS = ['toBeNull', 'toBeFalsy'];
116116

117+
export type VALID_ASYNC_UTILS =
118+
| 'waitFor'
119+
| 'waitForElementToBeRemoved'
120+
| 'wait'
121+
| 'waitForElement'
122+
| 'waitForDomChange';
123+
117124
export {
118125
combineQueries,
119126
getDocsUrl,

0 commit comments

Comments
 (0)