1- import { InvalidTestCase } from '@typescript-eslint/experimental-utils/dist/ts-eslint'
1+ import { InvalidTestCase , ValidTestCase } from '@typescript-eslint/experimental-utils/dist/ts-eslint'
22import { createRuleTester } from '../test-utils' ;
33import { 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' ;
55
66const ruleTester = createRuleTester ( {
77 ecmaFeatures : {
88 jsx : true ,
99 } ,
1010} ) ;
1111
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+
1225ruleTester . run ( RULE_NAME , rule , {
1326 valid : [
1427 ...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+ `
1632 } ) ) ,
1733 ...ASYNC_QUERIES_COMBINATIONS . map ( ( queryMethod ) => ( {
1834 code : `const submitButton = await screen.${ queryMethod } ('foo')`
@@ -60,35 +76,117 @@ ruleTester.run(RULE_NAME, rule, {
6076 }
6177 ] ,
6278 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+ }
93191 ] ,
94192} )
0 commit comments