1+ import { ASTUtils , TSESTree } from '@typescript-eslint/experimental-utils' ;
2+ import { createTestingLibraryRule } from '../create-testing-library-rule' ;
13import {
2- TSESTree ,
3- ESLintUtils ,
4- ASTUtils ,
5- } from '@typescript-eslint/experimental-utils' ;
6- import { getDocsUrl , ASYNC_QUERIES_VARIANTS } from '../utils' ;
7- import {
8- isNewExpression ,
9- isImportSpecifier ,
4+ findClosestCallExpressionNode ,
5+ getIdentifierNode ,
106 isCallExpression ,
7+ isNewExpression ,
8+ isPromiseIdentifier ,
119} from '../node-utils' ;
1210
1311export const RULE_NAME = 'no-promise-in-fire-event' ;
1412export type MessageIds = 'noPromiseInFireEvent' ;
1513type Options = [ ] ;
1614
17- export default ESLintUtils . RuleCreator ( getDocsUrl ) < Options , MessageIds > ( {
15+ export default createTestingLibraryRule < Options , MessageIds > ( {
1816 name : RULE_NAME ,
1917 meta : {
2018 type : 'problem' ,
@@ -28,49 +26,74 @@ export default ESLintUtils.RuleCreator(getDocsUrl)<Options, MessageIds>({
2826 noPromiseInFireEvent :
2927 "A promise shouldn't be passed to a `fireEvent` method, instead pass the DOM element" ,
3028 } ,
31- fixable : 'code' ,
29+ fixable : null ,
3230 schema : [ ] ,
3331 } ,
3432 defaultOptions : [ ] ,
3533
36- create ( context ) {
37- return {
38- 'ImportDeclaration[source.value=/testing-library/]' (
39- node : TSESTree . ImportDeclaration
40- ) {
41- const fireEventImportNode = node . specifiers . find (
42- ( specifier ) =>
43- isImportSpecifier ( specifier ) &&
44- specifier . imported &&
45- 'fireEvent' === specifier . imported . name
46- ) as TSESTree . ImportSpecifier ;
34+ create ( context , _ , helpers ) {
35+ function checkSuspiciousNode (
36+ node : TSESTree . Node ,
37+ originalNode ?: TSESTree . Node
38+ ) : void {
39+ if ( ASTUtils . isAwaitExpression ( node ) ) {
40+ return ;
41+ }
4742
48- const { references } = context . getDeclaredVariables (
49- fireEventImportNode
50- ) [ 0 ] ;
43+ if ( isNewExpression ( node ) ) {
44+ if ( isPromiseIdentifier ( node . callee ) ) {
45+ return context . report ( {
46+ node : originalNode ?? node ,
47+ messageId : 'noPromiseInFireEvent' ,
48+ } ) ;
49+ }
50+ }
5151
52- for ( const reference of references ) {
53- const referenceNode = reference . identifier ;
54- const callExpression = referenceNode . parent
55- . parent as TSESTree . CallExpression ;
56- const [ element ] = callExpression . arguments as TSESTree . Node [ ] ;
57- if ( isCallExpression ( element ) || isNewExpression ( element ) ) {
58- const methodName = ASTUtils . isIdentifier ( element . callee )
59- ? element . callee . name
60- : ( ( element . callee as TSESTree . MemberExpression )
61- . property as TSESTree . Identifier ) . name ;
52+ if ( isCallExpression ( node ) ) {
53+ const domElementIdentifier = getIdentifierNode ( node ) ;
54+
55+ if (
56+ helpers . isAsyncQuery ( domElementIdentifier ) ||
57+ isPromiseIdentifier ( domElementIdentifier )
58+ ) {
59+ return context . report ( {
60+ node : originalNode ?? node ,
61+ messageId : 'noPromiseInFireEvent' ,
62+ } ) ;
63+ }
64+ }
65+
66+ if ( ASTUtils . isIdentifier ( node ) ) {
67+ const nodeVariable = ASTUtils . findVariable (
68+ context . getScope ( ) ,
69+ node . name
70+ ) ;
71+ if ( ! nodeVariable || ! nodeVariable . defs ) {
72+ return ;
73+ }
6274
63- if (
64- ASYNC_QUERIES_VARIANTS . some ( ( q ) => methodName . startsWith ( q ) ) ||
65- methodName === 'Promise'
66- ) {
67- context . report ( {
68- node : element ,
69- messageId : 'noPromiseInFireEvent' ,
70- } ) ;
71- }
72- }
75+ for ( const definition of nodeVariable . defs ) {
76+ const variableDeclarator = definition . node as TSESTree . VariableDeclarator ;
77+ checkSuspiciousNode ( variableDeclarator . init , node ) ;
7378 }
79+ }
80+ }
81+
82+ return {
83+ 'CallExpression Identifier' ( node : TSESTree . Identifier ) {
84+ if ( ! helpers . isFireEventMethod ( node ) ) {
85+ return ;
86+ }
87+
88+ const closestCallExpression = findClosestCallExpressionNode ( node , true ) ;
89+
90+ if ( ! closestCallExpression ) {
91+ return ;
92+ }
93+
94+ const domElementArgument = closestCallExpression . arguments [ 0 ] ;
95+
96+ checkSuspiciousNode ( domElementArgument ) ;
7497 } ,
7598 } ;
7699 } ,
0 commit comments