Skip to content

Commit c344c33

Browse files
committed
refactor(prefer-screen-queries): detect queries with helper
1 parent d3df673 commit c344c33

File tree

3 files changed

+89
-56
lines changed

3 files changed

+89
-56
lines changed

lib/detect-testing-library-utils.ts

+12-4
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ type IsQueryQueryVariantFn = (node: TSESTree.Identifier) => boolean;
6161
type IsFindQueryVariantFn = (node: TSESTree.Identifier) => boolean;
6262
type IsSyncQueryFn = (node: TSESTree.Identifier) => boolean;
6363
type IsAsyncQueryFn = (node: TSESTree.Identifier) => boolean;
64+
type IsQueryFn = (node: TSESTree.Identifier) => boolean;
6465
type IsCustomQueryFn = (node: TSESTree.Identifier) => boolean;
6566
type IsAsyncUtilFn = (node: TSESTree.Identifier) => boolean;
6667
type IsFireEventMethodFn = (node: TSESTree.Identifier) => boolean;
@@ -87,6 +88,7 @@ export interface DetectionHelpers {
8788
isFindQueryVariant: IsFindQueryVariantFn;
8889
isSyncQuery: IsSyncQueryFn;
8990
isAsyncQuery: IsAsyncQueryFn;
91+
isQuery: IsQueryFn;
9092
isCustomQuery: IsCustomQueryFn;
9193
isAsyncUtil: IsAsyncUtilFn;
9294
isFireEventMethod: IsFireEventMethodFn;
@@ -271,11 +273,16 @@ export function detectTestingLibraryUtils<
271273
return isFindQueryVariant(node);
272274
};
273275

276+
/**
277+
* Determines whether a given node is a valid query,
278+
* either built-in or custom
279+
*/
280+
const isQuery: IsQueryFn = (node) => {
281+
return isSyncQuery(node) || isAsyncQuery(node);
282+
};
283+
274284
const isCustomQuery: IsCustomQueryFn = (node) => {
275-
return (
276-
(isSyncQuery(node) || isAsyncQuery(node)) &&
277-
!ALL_QUERIES_COMBINATIONS.includes(node.name)
278-
);
285+
return isQuery(node) && !ALL_QUERIES_COMBINATIONS.includes(node.name);
279286
};
280287

281288
/**
@@ -528,6 +535,7 @@ export function detectTestingLibraryUtils<
528535
isFindQueryVariant,
529536
isSyncQuery,
530537
isAsyncQuery,
538+
isQuery,
531539
isCustomQuery,
532540
isAsyncUtil,
533541
isFireEventMethod,

lib/rules/prefer-screen-queries.ts

+11-10
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { ASTUtils, TSESTree } from '@typescript-eslint/experimental-utils';
2-
import { ALL_QUERIES_COMBINATIONS } from '../utils';
32
import {
43
isCallExpression,
54
isMemberExpression,
@@ -17,7 +16,6 @@ const ALLOWED_RENDER_PROPERTIES_FOR_DESTRUCTURING = [
1716
'container',
1817
'baseElement',
1918
];
20-
const ALL_QUERIES_COMBINATIONS_REGEXP = ALL_QUERIES_COMBINATIONS.join('|');
2119

2220
function usesContainerOrBaseElement(node: TSESTree.CallExpression) {
2321
const secondArgument = node.arguments[1];
@@ -61,7 +59,6 @@ export default createTestingLibraryRule<Options, MessageIds>({
6159
});
6260
}
6361

64-
const queriesRegex = new RegExp(ALL_QUERIES_COMBINATIONS_REGEXP);
6562
const queriesDestructuredInWithinDeclaration: string[] = [];
6663
// use an array as within might be used more than once in a test
6764
const withinDeclaredVariables: string[] = [];
@@ -90,7 +87,7 @@ export default createTestingLibraryRule<Options, MessageIds>({
9087
(property) =>
9188
isProperty(property) &&
9289
ASTUtils.isIdentifier(property.key) &&
93-
queriesRegex.test(property.key.name)
90+
helpers.isQuery(property.key)
9491
)
9592
.map(
9693
(property: TSESTree.Property) =>
@@ -105,9 +102,11 @@ export default createTestingLibraryRule<Options, MessageIds>({
105102
withinDeclaredVariables.push(node.id.name);
106103
}
107104
},
108-
[`CallExpression > Identifier[name=/^${ALL_QUERIES_COMBINATIONS_REGEXP}$/]`](
109-
node: TSESTree.Identifier
110-
) {
105+
'CallExpression > Identifier'(node: TSESTree.Identifier) {
106+
if (!helpers.isQuery(node)) {
107+
return;
108+
}
109+
111110
if (
112111
!queriesDestructuredInWithinDeclaration.some(
113112
(queryName) => queryName === node.name
@@ -116,13 +115,15 @@ export default createTestingLibraryRule<Options, MessageIds>({
116115
reportInvalidUsage(node);
117116
}
118117
},
119-
[`MemberExpression > Identifier[name=/^${ALL_QUERIES_COMBINATIONS_REGEXP}$/]`](
120-
node: TSESTree.Identifier
121-
) {
118+
'MemberExpression > Identifier'(node: TSESTree.Identifier) {
122119
function isIdentifierAllowed(name: string) {
123120
return ['screen', ...withinDeclaredVariables].includes(name);
124121
}
125122

123+
if (!helpers.isQuery(node)) {
124+
return;
125+
}
126+
126127
if (
127128
ASTUtils.isIdentifier(node) &&
128129
isMemberExpression(node.parent) &&

tests/lib/rules/prefer-screen-queries.test.ts

+66-42
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,27 @@
11
import { createRuleTester } from '../test-utils';
22
import rule, { RULE_NAME } from '../../../lib/rules/prefer-screen-queries';
3-
import { ALL_QUERIES_COMBINATIONS } from '../../../lib/utils';
3+
import {
4+
ALL_QUERIES_COMBINATIONS,
5+
ALL_QUERIES_VARIANTS,
6+
combineQueries,
7+
} from '../../../lib/utils';
48

59
const ruleTester = createRuleTester();
610

7-
// TODO: include custom queries in test cases
11+
const CUSTOM_QUERY_COMBINATIONS = combineQueries(ALL_QUERIES_VARIANTS, [
12+
'ByIcon',
13+
]);
14+
const ALL_BUILTIN_AND_CUSTOM_QUERIES_COMBINATIONS = [
15+
...ALL_QUERIES_COMBINATIONS,
16+
...CUSTOM_QUERY_COMBINATIONS,
17+
];
818

919
ruleTester.run(RULE_NAME, rule, {
1020
valid: [
1121
{
1222
code: `const baz = () => 'foo'`,
1323
},
14-
...ALL_QUERIES_COMBINATIONS.map((queryMethod) => ({
24+
...ALL_BUILTIN_AND_CUSTOM_QUERIES_COMBINATIONS.map((queryMethod) => ({
1525
code: `screen.${queryMethod}()`,
1626
})),
1727
{
@@ -20,19 +30,19 @@ ruleTester.run(RULE_NAME, rule, {
2030
{
2131
code: `component.otherFunctionShouldNotThrow()`,
2232
},
23-
...ALL_QUERIES_COMBINATIONS.map((queryMethod) => ({
33+
...ALL_BUILTIN_AND_CUSTOM_QUERIES_COMBINATIONS.map((queryMethod) => ({
2434
code: `within(component).${queryMethod}()`,
2535
})),
26-
...ALL_QUERIES_COMBINATIONS.map((queryMethod) => ({
36+
...ALL_BUILTIN_AND_CUSTOM_QUERIES_COMBINATIONS.map((queryMethod) => ({
2737
code: `within(screen.${queryMethod}()).${queryMethod}()`,
2838
})),
29-
...ALL_QUERIES_COMBINATIONS.map((queryMethod) => ({
39+
...ALL_BUILTIN_AND_CUSTOM_QUERIES_COMBINATIONS.map((queryMethod) => ({
3040
code: `
3141
const { ${queryMethod} } = within(screen.getByText('foo'))
3242
${queryMethod}(baz)
3343
`,
3444
})),
35-
...ALL_QUERIES_COMBINATIONS.map((queryMethod) => ({
45+
...ALL_BUILTIN_AND_CUSTOM_QUERIES_COMBINATIONS.map((queryMethod) => ({
3646
code: `
3747
const myWithinVariable = within(foo)
3848
myWithinVariable.${queryMethod}('baz')
@@ -86,48 +96,62 @@ ruleTester.run(RULE_NAME, rule, {
8696
utils.unmount();
8797
`,
8898
},
89-
...ALL_QUERIES_COMBINATIONS.map((queryMethod: string) => ({
90-
code: `
99+
...ALL_BUILTIN_AND_CUSTOM_QUERIES_COMBINATIONS.map(
100+
(queryMethod: string) => ({
101+
code: `
91102
const { ${queryMethod} } = render(baz, { baseElement: treeA })
92103
expect(${queryMethod}(baz)).toBeDefined()
93104
`,
94-
})),
95-
...ALL_QUERIES_COMBINATIONS.map((queryMethod: string) => ({
96-
code: `
105+
})
106+
),
107+
...ALL_BUILTIN_AND_CUSTOM_QUERIES_COMBINATIONS.map(
108+
(queryMethod: string) => ({
109+
code: `
97110
const { ${queryMethod}: aliasMethod } = render(baz, { baseElement: treeA })
98111
expect(aliasMethod(baz)).toBeDefined()
99112
`,
100-
})),
101-
...ALL_QUERIES_COMBINATIONS.map((queryMethod: string) => ({
102-
code: `
113+
})
114+
),
115+
...ALL_BUILTIN_AND_CUSTOM_QUERIES_COMBINATIONS.map(
116+
(queryMethod: string) => ({
117+
code: `
103118
const { ${queryMethod} } = render(baz, { container: treeA })
104119
expect(${queryMethod}(baz)).toBeDefined()
105120
`,
106-
})),
107-
...ALL_QUERIES_COMBINATIONS.map((queryMethod: string) => ({
108-
code: `
121+
})
122+
),
123+
...ALL_BUILTIN_AND_CUSTOM_QUERIES_COMBINATIONS.map(
124+
(queryMethod: string) => ({
125+
code: `
109126
const { ${queryMethod}: aliasMethod } = render(baz, { container: treeA })
110127
expect(aliasMethod(baz)).toBeDefined()
111128
`,
112-
})),
113-
...ALL_QUERIES_COMBINATIONS.map((queryMethod: string) => ({
114-
code: `
129+
})
130+
),
131+
...ALL_BUILTIN_AND_CUSTOM_QUERIES_COMBINATIONS.map(
132+
(queryMethod: string) => ({
133+
code: `
115134
const { ${queryMethod} } = render(baz, { baseElement: treeB, container: treeA })
116135
expect(${queryMethod}(baz)).toBeDefined()
117136
`,
118-
})),
119-
...ALL_QUERIES_COMBINATIONS.map((queryMethod: string) => ({
120-
code: `
137+
})
138+
),
139+
...ALL_BUILTIN_AND_CUSTOM_QUERIES_COMBINATIONS.map(
140+
(queryMethod: string) => ({
141+
code: `
121142
const { ${queryMethod}: aliasMethod } = render(baz, { baseElement: treeB, container: treeA })
122143
expect(aliasMethod(baz)).toBeDefined()
123144
`,
124-
})),
125-
...ALL_QUERIES_COMBINATIONS.map((queryMethod: string) => ({
126-
code: `
145+
})
146+
),
147+
...ALL_BUILTIN_AND_CUSTOM_QUERIES_COMBINATIONS.map(
148+
(queryMethod: string) => ({
149+
code: `
127150
render(foo, { baseElement: treeA }).${queryMethod}()
128151
`,
129-
})),
130-
// ...ALL_QUERIES_COMBINATIONS.map((queryMethod) => ({
152+
})
153+
),
154+
// ...ALL_BUILTIN_AND_CUSTOM_QUERIES_COMBINATIONS.map((queryMethod) => ({
131155
// settings: {
132156
// 'testing-library/custom-renders': ['customRender'],
133157
// },
@@ -139,7 +163,7 @@ ruleTester.run(RULE_NAME, rule, {
139163
],
140164

141165
invalid: [
142-
...ALL_QUERIES_COMBINATIONS.map((queryMethod) => ({
166+
...ALL_BUILTIN_AND_CUSTOM_QUERIES_COMBINATIONS.map((queryMethod) => ({
143167
code: `
144168
const { ${queryMethod} } = render(foo)
145169
${queryMethod}()`,
@@ -152,7 +176,7 @@ ruleTester.run(RULE_NAME, rule, {
152176
},
153177
],
154178
})),
155-
...ALL_QUERIES_COMBINATIONS.map((queryMethod) => ({
179+
...ALL_BUILTIN_AND_CUSTOM_QUERIES_COMBINATIONS.map((queryMethod) => ({
156180
settings: { 'testing-library/utils-module': 'test-utils' },
157181
code: `
158182
import { render } from 'test-utils'
@@ -170,7 +194,7 @@ ruleTester.run(RULE_NAME, rule, {
170194
],
171195
})),
172196

173-
...ALL_QUERIES_COMBINATIONS.map((queryMethod) => ({
197+
...ALL_BUILTIN_AND_CUSTOM_QUERIES_COMBINATIONS.map((queryMethod) => ({
174198
settings: {
175199
'testing-library/custom-renders': ['customRender'],
176200
},
@@ -189,7 +213,7 @@ ruleTester.run(RULE_NAME, rule, {
189213
},
190214
],
191215
})),
192-
...ALL_QUERIES_COMBINATIONS.map((queryMethod) => ({
216+
...ALL_BUILTIN_AND_CUSTOM_QUERIES_COMBINATIONS.map((queryMethod) => ({
193217
settings: { 'testing-library/utils-module': 'test-utils' },
194218
code: `
195219
import { render as testingLibraryRender} from '@testing-library/react'
@@ -206,7 +230,7 @@ ruleTester.run(RULE_NAME, rule, {
206230
},
207231
],
208232
})),
209-
...ALL_QUERIES_COMBINATIONS.map((queryMethod) => ({
233+
...ALL_BUILTIN_AND_CUSTOM_QUERIES_COMBINATIONS.map((queryMethod) => ({
210234
settings: { 'testing-library/utils-module': 'test-utils' },
211235
code: `
212236
import { render } from 'test-utils'
@@ -223,7 +247,7 @@ ruleTester.run(RULE_NAME, rule, {
223247
},
224248
],
225249
})),
226-
...ALL_QUERIES_COMBINATIONS.map((queryMethod) => ({
250+
...ALL_BUILTIN_AND_CUSTOM_QUERIES_COMBINATIONS.map((queryMethod) => ({
227251
code: `render().${queryMethod}()`,
228252
errors: [
229253
{
@@ -234,7 +258,7 @@ ruleTester.run(RULE_NAME, rule, {
234258
},
235259
],
236260
})),
237-
...ALL_QUERIES_COMBINATIONS.map((queryMethod) => ({
261+
...ALL_BUILTIN_AND_CUSTOM_QUERIES_COMBINATIONS.map((queryMethod) => ({
238262
code: `render(foo, { hydrate: true }).${queryMethod}()`,
239263
errors: [
240264
{
@@ -245,7 +269,7 @@ ruleTester.run(RULE_NAME, rule, {
245269
},
246270
],
247271
})),
248-
...ALL_QUERIES_COMBINATIONS.map((queryMethod) => ({
272+
...ALL_BUILTIN_AND_CUSTOM_QUERIES_COMBINATIONS.map((queryMethod) => ({
249273
code: `component.${queryMethod}()`,
250274
errors: [
251275
{
@@ -256,7 +280,7 @@ ruleTester.run(RULE_NAME, rule, {
256280
},
257281
],
258282
})),
259-
...ALL_QUERIES_COMBINATIONS.map((queryMethod) => ({
283+
...ALL_BUILTIN_AND_CUSTOM_QUERIES_COMBINATIONS.map((queryMethod) => ({
260284
code: `
261285
const { ${queryMethod} } = render()
262286
${queryMethod}(baz)
@@ -270,7 +294,7 @@ ruleTester.run(RULE_NAME, rule, {
270294
},
271295
],
272296
})),
273-
...ALL_QUERIES_COMBINATIONS.map((queryMethod) => ({
297+
...ALL_BUILTIN_AND_CUSTOM_QUERIES_COMBINATIONS.map((queryMethod) => ({
274298
code: `
275299
const myRenderVariable = render()
276300
myRenderVariable.${queryMethod}(baz)
@@ -284,7 +308,7 @@ ruleTester.run(RULE_NAME, rule, {
284308
},
285309
],
286310
})),
287-
...ALL_QUERIES_COMBINATIONS.map((queryMethod) => ({
311+
...ALL_BUILTIN_AND_CUSTOM_QUERIES_COMBINATIONS.map((queryMethod) => ({
288312
code: `
289313
const [myVariable] = render()
290314
myVariable.${queryMethod}(baz)
@@ -298,7 +322,7 @@ ruleTester.run(RULE_NAME, rule, {
298322
},
299323
],
300324
})),
301-
...ALL_QUERIES_COMBINATIONS.map((queryMethod) => ({
325+
...ALL_BUILTIN_AND_CUSTOM_QUERIES_COMBINATIONS.map((queryMethod) => ({
302326
code: `
303327
const { ${queryMethod} } = render(baz, { hydrate: true })
304328
${queryMethod}(baz)
@@ -312,7 +336,7 @@ ruleTester.run(RULE_NAME, rule, {
312336
},
313337
],
314338
})),
315-
...ALL_QUERIES_COMBINATIONS.map((queryMethod) => ({
339+
...ALL_BUILTIN_AND_CUSTOM_QUERIES_COMBINATIONS.map((queryMethod) => ({
316340
code: `
317341
const [myVariable] = within()
318342
myVariable.${queryMethod}(baz)

0 commit comments

Comments
 (0)