1
- import {
2
- ESLintUtils ,
3
- TSESTree ,
4
- ASTUtils ,
5
- } from '@typescript-eslint/experimental-utils' ;
1
+ import { TSESTree , ASTUtils } from '@typescript-eslint/experimental-utils' ;
6
2
import {
7
3
ReportFixFunction ,
8
4
RuleFix ,
@@ -15,7 +11,7 @@ import {
15
11
isObjectPattern ,
16
12
isProperty ,
17
13
} from '../node-utils' ;
18
- import { getDocsUrl , SYNC_QUERIES_COMBINATIONS } from '../utils ' ;
14
+ import { createTestingLibraryRule } from '../create-testing-library-rule ' ;
19
15
20
16
export const RULE_NAME = 'prefer-find-by' ;
21
17
export type MessageIds = 'preferFindBy' ;
@@ -51,7 +47,7 @@ function findRenderDefinitionDeclaration(
51
47
return findRenderDefinitionDeclaration ( scope . upper , query ) ;
52
48
}
53
49
54
- export default ESLintUtils . RuleCreator ( getDocsUrl ) < Options , MessageIds > ( {
50
+ export default createTestingLibraryRule < Options , MessageIds > ( {
55
51
name : RULE_NAME ,
56
52
meta : {
57
53
type : 'suggestion' ,
@@ -70,7 +66,7 @@ export default ESLintUtils.RuleCreator(getDocsUrl)<Options, MessageIds>({
70
66
} ,
71
67
defaultOptions : [ ] ,
72
68
73
- create ( context ) {
69
+ create ( context , _ , helpers ) {
74
70
const sourceCode = context . getSourceCode ( ) ;
75
71
76
72
/**
@@ -126,7 +122,7 @@ export default ESLintUtils.RuleCreator(getDocsUrl)<Options, MessageIds>({
126
122
isMemberExpression ( argument . body . callee ) &&
127
123
ASTUtils . isIdentifier ( argument . body . callee . property ) &&
128
124
ASTUtils . isIdentifier ( argument . body . callee . object ) &&
129
- SYNC_QUERIES_COMBINATIONS . includes ( argument . body . callee . property . name )
125
+ helpers . isSyncQuery ( argument . body . callee . property )
130
126
) {
131
127
// shape of () => screen.getByText
132
128
const fullQueryMethod = argument . body . callee . property . name ;
@@ -139,6 +135,11 @@ export default ESLintUtils.RuleCreator(getDocsUrl)<Options, MessageIds>({
139
135
queryMethod,
140
136
queryVariant,
141
137
fix ( fixer ) {
138
+ const property = ( ( argument . body as TSESTree . CallExpression )
139
+ . callee as TSESTree . MemberExpression ) . property ;
140
+ if ( helpers . isCustomQuery ( property as TSESTree . Identifier ) ) {
141
+ return ;
142
+ }
142
143
const newCode = `${ caller } .${ queryVariant } ${ queryMethod } (${ callArguments
143
144
. map ( ( node ) => sourceCode . getText ( node ) )
144
145
. join ( ', ' ) } )`;
@@ -148,65 +149,74 @@ export default ESLintUtils.RuleCreator(getDocsUrl)<Options, MessageIds>({
148
149
return ;
149
150
}
150
151
if (
151
- ASTUtils . isIdentifier ( argument . body . callee ) &&
152
- SYNC_QUERIES_COMBINATIONS . includes ( argument . body . callee . name )
152
+ ! ASTUtils . isIdentifier ( argument . body . callee ) ||
153
+ ! helpers . isSyncQuery ( argument . body . callee )
153
154
) {
154
- // shape of () => getByText
155
- const fullQueryMethod = argument . body . callee . name ;
156
- const queryMethod = fullQueryMethod . split ( 'By' ) [ 1 ] ;
157
- const queryVariant = getFindByQueryVariant ( fullQueryMethod ) ;
158
- const callArguments = argument . body . arguments ;
155
+ return ;
156
+ }
157
+ // shape of () => getByText
158
+ const fullQueryMethod = argument . body . callee . name ;
159
+ const queryMethod = fullQueryMethod . split ( 'By' ) [ 1 ] ;
160
+ const queryVariant = getFindByQueryVariant ( fullQueryMethod ) ;
161
+ const callArguments = argument . body . arguments ;
159
162
160
- reportInvalidUsage ( node , {
161
- queryMethod,
162
- queryVariant,
163
- fix ( fixer ) {
164
- const findByMethod = `${ queryVariant } ${ queryMethod } ` ;
165
- const allFixes : RuleFix [ ] = [ ] ;
166
- // this updates waitFor with findBy*
167
- const newCode = `${ findByMethod } (${ callArguments
168
- . map ( ( node ) => sourceCode . getText ( node ) )
169
- . join ( ', ' ) } )`;
170
- allFixes . push ( fixer . replaceText ( node , newCode ) ) ;
163
+ reportInvalidUsage ( node , {
164
+ queryMethod,
165
+ queryVariant,
166
+ fix ( fixer ) {
167
+ // we know from above callee is an Identifier
168
+ if (
169
+ helpers . isCustomQuery (
170
+ ( argument . body as TSESTree . CallExpression )
171
+ . callee as TSESTree . Identifier
172
+ )
173
+ ) {
174
+ return ;
175
+ }
176
+ const findByMethod = `${ queryVariant } ${ queryMethod } ` ;
177
+ const allFixes : RuleFix [ ] = [ ] ;
178
+ // this updates waitFor with findBy*
179
+ const newCode = `${ findByMethod } (${ callArguments
180
+ . map ( ( node ) => sourceCode . getText ( node ) )
181
+ . join ( ', ' ) } )`;
182
+ allFixes . push ( fixer . replaceText ( node , newCode ) ) ;
171
183
172
- // this adds the findBy* declaration - adding it to the list of destructured variables { findBy* } = render()
173
- const definition = findRenderDefinitionDeclaration (
174
- context . getScope ( ) ,
175
- fullQueryMethod
176
- ) ;
177
- // I think it should always find it, otherwise code should not be valid (it'd be using undeclared variables)
178
- if ( ! definition ) {
184
+ // this adds the findBy* declaration - adding it to the list of destructured variables { findBy* } = render()
185
+ const definition = findRenderDefinitionDeclaration (
186
+ context . getScope ( ) ,
187
+ fullQueryMethod
188
+ ) ;
189
+ // I think it should always find it, otherwise code should not be valid (it'd be using undeclared variables)
190
+ if ( ! definition ) {
191
+ return allFixes ;
192
+ }
193
+ // check the declaration is part of a destructuring
194
+ if ( isObjectPattern ( definition . parent . parent ) ) {
195
+ const allVariableDeclarations = definition . parent . parent ;
196
+ // verify if the findBy* method was already declared
197
+ if (
198
+ allVariableDeclarations . properties . some (
199
+ ( p ) =>
200
+ isProperty ( p ) &&
201
+ ASTUtils . isIdentifier ( p . key ) &&
202
+ p . key . name === findByMethod
203
+ )
204
+ ) {
179
205
return allFixes ;
180
206
}
181
- // check the declaration is part of a destructuring
182
- if ( isObjectPattern ( definition . parent . parent ) ) {
183
- const allVariableDeclarations = definition . parent . parent ;
184
- // verify if the findBy* method was already declared
185
- if (
186
- allVariableDeclarations . properties . some (
187
- ( p ) =>
188
- isProperty ( p ) &&
189
- ASTUtils . isIdentifier ( p . key ) &&
190
- p . key . name === findByMethod
191
- )
192
- ) {
193
- return allFixes ;
194
- }
195
- // the last character of a destructuring is always a " }", so we should replace it with the findBy* declaration
196
- const textDestructuring = sourceCode . getText (
197
- allVariableDeclarations
198
- ) ;
199
- const text =
200
- textDestructuring . substring ( 0 , textDestructuring . length - 2 ) +
201
- `, ${ findByMethod } }` ;
202
- allFixes . push ( fixer . replaceText ( allVariableDeclarations , text ) ) ;
203
- }
207
+ // the last character of a destructuring is always a " }", so we should replace it with the findBy* declaration
208
+ const textDestructuring = sourceCode . getText (
209
+ allVariableDeclarations
210
+ ) ;
211
+ const text =
212
+ textDestructuring . substring ( 0 , textDestructuring . length - 2 ) +
213
+ `, ${ findByMethod } }` ;
214
+ allFixes . push ( fixer . replaceText ( allVariableDeclarations , text ) ) ;
215
+ }
204
216
205
- return allFixes ;
206
- } ,
207
- } ) ;
208
- return ;
209
- }
217
+ return allFixes ;
218
+ } ,
219
+ } ) ;
210
220
} ,
211
221
} ;
212
222
} ,
0 commit comments