1
- import { InvalidTestCase } from '@typescript-eslint/experimental-utils/dist/ts-eslint'
1
+ import { InvalidTestCase , ValidTestCase } from '@typescript-eslint/experimental-utils/dist/ts-eslint'
2
2
import { createRuleTester } from '../test-utils' ;
3
3
import { ASYNC_QUERIES_COMBINATIONS , SYNC_QUERIES_COMBINATIONS } from '../../../lib/utils' ;
4
- import rule , { WAIT_METHODS , RULE_NAME } from '../../../lib/rules/prefer-find-by' ;
4
+ import rule , { WAIT_METHODS , RULE_NAME , getFindByQueryVariant , MessageIds } from '../../../lib/rules/prefer-find-by' ;
5
5
6
6
const ruleTester = createRuleTester ( {
7
7
ecmaFeatures : {
8
8
jsx : true ,
9
9
} ,
10
10
} ) ;
11
11
12
+ function buildFindByMethod ( queryMethod : string ) {
13
+ return `${ getFindByQueryVariant ( queryMethod ) } ${ queryMethod . split ( 'By' ) [ 1 ] } `
14
+ }
15
+
16
+ function createScenario < T extends ValidTestCase < [ ] > | InvalidTestCase < MessageIds , [ ] > > ( callback : ( waitMethod : string , queryMethod : string ) => T ) {
17
+ return WAIT_METHODS . reduce ( ( acc : T [ ] , waitMethod ) =>
18
+ acc . concat (
19
+ SYNC_QUERIES_COMBINATIONS
20
+ . map ( ( queryMethod ) => callback ( waitMethod , queryMethod ) )
21
+ )
22
+ , [ ] )
23
+ }
24
+
12
25
ruleTester . run ( RULE_NAME , rule , {
13
26
valid : [
14
27
...ASYNC_QUERIES_COMBINATIONS . map ( ( queryMethod ) => ( {
15
- code : `const submitButton = await ${ queryMethod } ('foo')`
28
+ code : `
29
+ const { ${ queryMethod } } = setup()
30
+ const submitButton = await ${ queryMethod } ('foo')
31
+ `
16
32
} ) ) ,
17
33
...ASYNC_QUERIES_COMBINATIONS . map ( ( queryMethod ) => ( {
18
34
code : `const submitButton = await screen.${ queryMethod } ('foo')`
@@ -60,35 +76,117 @@ ruleTester.run(RULE_NAME, rule, {
60
76
}
61
77
] ,
62
78
invalid : [
63
- // using reduce + concat 'cause flatMap is not available in node10.x
64
- ...WAIT_METHODS . reduce ( ( acc : InvalidTestCase < 'preferFindBy' , [ ] > [ ] , waitMethod ) => acc
65
- . concat (
66
- SYNC_QUERIES_COMBINATIONS . map ( ( queryMethod : string ) => ( {
67
- code : `const submitButton = await ${ waitMethod } (() => ${ queryMethod } ('foo', { name: 'baz' }))` ,
68
- errors : [ {
69
- messageId : 'preferFindBy' ,
70
- data : {
71
- queryVariant : queryMethod . includes ( 'All' ) ? 'findAllBy' : 'findBy' ,
72
- queryMethod : queryMethod . split ( 'By' ) [ 1 ] ,
73
- fullQuery : `${ waitMethod } (() => ${ queryMethod } ('foo', { name: 'baz' }))` ,
74
- } ,
75
- } ] ,
76
- output : `const submitButton = await ${ queryMethod . includes ( 'All' ) ? 'findAllBy' : 'findBy' } ${ queryMethod . split ( 'By' ) [ 1 ] } ('foo', { name: 'baz' })`
77
- } ) )
78
- ) . concat (
79
- SYNC_QUERIES_COMBINATIONS . map ( ( queryMethod : string ) => ( {
80
- code : `const submitButton = await ${ waitMethod } (() => screen.${ queryMethod } ('foo', { name: 'baz' }))` ,
81
- errors : [ {
82
- messageId : 'preferFindBy' ,
83
- data : {
84
- queryVariant : queryMethod . includes ( 'All' ) ? 'findAllBy' : 'findBy' ,
85
- queryMethod : queryMethod . split ( 'By' ) [ 1 ] ,
86
- fullQuery : `${ waitMethod } (() => screen.${ queryMethod } ('foo', { name: 'baz' }))` ,
87
- }
88
- } ] ,
89
- output : `const submitButton = await screen.${ queryMethod . includes ( 'All' ) ? 'findAllBy' : 'findBy' } ${ queryMethod . split ( 'By' ) [ 1 ] } ('foo', { name: 'baz' })`
90
- } ) )
91
- ) ,
92
- [ ] )
79
+ ...createScenario ( ( waitMethod : string , queryMethod : string ) => ( {
80
+ code : `
81
+ const { ${ queryMethod } } = render()
82
+ const submitButton = await ${ waitMethod } (() => ${ queryMethod } ('foo', { name: 'baz' }))
83
+ ` ,
84
+ errors : [ {
85
+ messageId : 'preferFindBy' ,
86
+ data : {
87
+ queryVariant : getFindByQueryVariant ( queryMethod ) ,
88
+ queryMethod : queryMethod . split ( 'By' ) [ 1 ] ,
89
+ fullQuery : `${ waitMethod } (() => ${ queryMethod } ('foo', { name: 'baz' }))` ,
90
+ } ,
91
+ } ] ,
92
+ output : `
93
+ const { ${ queryMethod } , ${ buildFindByMethod ( queryMethod ) } } = render()
94
+ const submitButton = await ${ buildFindByMethod ( queryMethod ) } ('foo', { name: 'baz' })
95
+ `
96
+ } ) ) ,
97
+ ...createScenario ( ( waitMethod : string , queryMethod : string ) => ( {
98
+ code : `const submitButton = await ${ waitMethod } (() => screen.${ queryMethod } ('foo', { name: 'baz' }))` ,
99
+ errors : [ {
100
+ messageId : 'preferFindBy' ,
101
+ data : {
102
+ queryVariant : getFindByQueryVariant ( queryMethod ) ,
103
+ queryMethod : queryMethod . split ( 'By' ) [ 1 ] ,
104
+ fullQuery : `${ waitMethod } (() => screen.${ queryMethod } ('foo', { name: 'baz' }))` ,
105
+ }
106
+ } ] ,
107
+ output : `const submitButton = await screen.${ buildFindByMethod ( queryMethod ) } ('foo', { name: 'baz' })`
108
+ } ) ) ,
109
+ // // this scenario verifies it works when the render function is defined in another scope
110
+ ...WAIT_METHODS . map ( ( waitMethod : string ) => ( {
111
+ code : `
112
+ const { getByText, queryByLabelText, findAllByRole } = customRender()
113
+ it('foo', async () => {
114
+ const submitButton = await ${ waitMethod } (() => getByText('baz', { name: 'button' }))
115
+ })
116
+ ` ,
117
+ errors : [ {
118
+ messageId : 'preferFindBy' ,
119
+ data : {
120
+ queryVariant : 'findBy' ,
121
+ queryMethod : 'Text' ,
122
+ fullQuery : `${ waitMethod } (() => getByText('baz', { name: 'button' }))` ,
123
+ }
124
+ } ] ,
125
+ output : `
126
+ const { getByText, queryByLabelText, findAllByRole, findByText } = customRender()
127
+ it('foo', async () => {
128
+ const submitButton = await findByText('baz', { name: 'button' })
129
+ })
130
+ `
131
+ } ) ) ,
132
+ // // this scenario verifies when findBy* were already defined (because it was used elsewhere)
133
+ ...WAIT_METHODS . map ( ( waitMethod : string ) => ( {
134
+ code : `
135
+ const { getAllByRole, findAllByRole } = customRender()
136
+ describe('some scenario', () => {
137
+ it('foo', async () => {
138
+ const submitButton = await ${ waitMethod } (() => getAllByRole('baz', { name: 'button' }))
139
+ })
140
+ })
141
+ ` ,
142
+ errors : [ {
143
+ messageId : 'preferFindBy' ,
144
+ data : {
145
+ queryVariant : 'findAllBy' ,
146
+ queryMethod : 'Role' ,
147
+ fullQuery : `${ waitMethod } (() => getAllByRole('baz', { name: 'button' }))` ,
148
+ }
149
+ } ] ,
150
+ output : `
151
+ const { getAllByRole, findAllByRole } = customRender()
152
+ describe('some scenario', () => {
153
+ it('foo', async () => {
154
+ const submitButton = await findAllByRole('baz', { name: 'button' })
155
+ })
156
+ })
157
+ `
158
+ } ) ) ,
159
+ // invalid code, as we need findBy* to be defined somewhere, but required for getting 100% coverage
160
+ {
161
+ code : `const submitButton = await waitFor(() => getByText('baz', { name: 'button' }))` ,
162
+ errors : [ {
163
+ messageId : 'preferFindBy' ,
164
+ data : {
165
+ queryVariant : 'findBy' ,
166
+ queryMethod : 'Text' ,
167
+ fullQuery : `waitFor(() => getByText('baz', { name: 'button' }))`
168
+ }
169
+ } ] ,
170
+ output : `const submitButton = await findByText('baz', { name: 'button' })`
171
+ } ,
172
+ // this code would be invalid too, as findByRole is not defined anywhere.
173
+ {
174
+ code : `
175
+ const getByRole = render().getByRole
176
+ const submitButton = await waitFor(() => getByRole('baz', { name: 'button' }))
177
+ ` ,
178
+ errors : [ {
179
+ messageId : 'preferFindBy' ,
180
+ data : {
181
+ queryVariant : 'findBy' ,
182
+ queryMethod : 'Role' ,
183
+ fullQuery : `waitFor(() => getByRole('baz', { name: 'button' }))`
184
+ }
185
+ } ] ,
186
+ output : `
187
+ const getByRole = render().getByRole
188
+ const submitButton = await findByRole('baz', { name: 'button' })
189
+ `
190
+ }
93
191
] ,
94
192
} )
0 commit comments