Skip to content

Commit d2274f6

Browse files
committed
fix(prefer-screen-queries): false positives when using within method
1 parent 4d85337 commit d2274f6

File tree

3 files changed

+80
-2
lines changed

3 files changed

+80
-2
lines changed

docs/rules/prefer-screen-queries.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,29 @@ Examples of **incorrect** code for this rule:
1212
const { getByText } = render(<Component />);
1313
getByText('foo');
1414

15+
// calling a query from a variable returned from a `render` method
1516
const utils = render(<Component />);
1617
utils.getByText('foo');
18+
19+
// using after render
20+
render(<Component />).getByText('foo');
1721
```
1822

1923
Examples of **correct** code for this rule:
2024

2125
```js
2226
import { screen } from '@testing-library/any-framework';
2327

28+
// calling a query from the `screen` object
2429
render(<Component />);
2530
screen.getByText('foo');
31+
32+
// using after within clause
33+
within(screen.getByTestId('section')).getByText('foo');
34+
35+
// calling a query method returned from a within call
36+
const { getByText } = within(screen.getByText('foo'));
37+
getByText('foo');
2638
```
2739

2840
## Further Reading

lib/rules/prefer-screen-queries.js

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,51 @@ module.exports = {
3232
});
3333
}
3434

35+
const queriesRegex = new RegExp(ALL_QUERIES_COMBINATIONS_REGEXP);
36+
const queriesDestructuredInWithinDeclaration = [];
37+
3538
return {
36-
[`CallExpression > Identifier[name=/^${ALL_QUERIES_COMBINATIONS_REGEXP}$/]`]: reportInvalidUsage,
37-
[`MemberExpression[object.name!="screen"] > Identifier[name=/^${ALL_QUERIES_COMBINATIONS_REGEXP}$/]`]: reportInvalidUsage,
39+
VariableDeclarator(node) {
40+
const isWithinFunction =
41+
node.init.callee && node.init.callee.name === 'within';
42+
if (!isWithinFunction || node.id.type !== 'ObjectPattern') {
43+
return;
44+
}
45+
46+
// save the destructured query methods
47+
const identifiers = node.id.properties
48+
.filter(property => queriesRegex.test(property.key.name))
49+
.map(property => property.key.name);
50+
queriesDestructuredInWithinDeclaration.push(...identifiers);
51+
},
52+
[`CallExpression > Identifier[name=/^${ALL_QUERIES_COMBINATIONS_REGEXP}$/]`](
53+
node
54+
) {
55+
if (
56+
!queriesDestructuredInWithinDeclaration.some(
57+
queryName => queryName === node.name
58+
)
59+
) {
60+
reportInvalidUsage(node);
61+
}
62+
},
63+
[`MemberExpression > Identifier[name=/^${ALL_QUERIES_COMBINATIONS_REGEXP}$/]`](
64+
node
65+
) {
66+
if (
67+
node.parent.object.type === 'CallExpression' &&
68+
node.parent.object.callee.name !== 'within'
69+
) {
70+
reportInvalidUsage(node);
71+
return;
72+
}
73+
if (
74+
node.parent.object.type === 'Identifier' &&
75+
node.parent.object.name !== 'screen'
76+
) {
77+
reportInvalidUsage(node);
78+
}
79+
},
3880
};
3981
},
4082
};

tests/lib/rules/prefer-screen-queries.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,18 @@ ruleTester.run('prefer-screen-queries', rule, {
2020
{
2121
code: `component.otherFunctionShouldNotThrow()`,
2222
},
23+
...ALL_QUERIES_COMBINATIONS.map(queryMethod => ({
24+
code: `within(component).${queryMethod}()`,
25+
})),
26+
...ALL_QUERIES_COMBINATIONS.map(queryMethod => ({
27+
code: `within(screen.${queryMethod}()).${queryMethod}()`,
28+
})),
29+
...ALL_QUERIES_COMBINATIONS.map(queryMethod => ({
30+
code: `
31+
const { ${queryMethod} } = within(screen.getByText('foo'))
32+
${queryMethod}(baz)
33+
`,
34+
})),
2335
],
2436

2537
invalid: [
@@ -35,6 +47,18 @@ ruleTester.run('prefer-screen-queries', rule, {
3547
],
3648
})),
3749

50+
...ALL_QUERIES_COMBINATIONS.map(queryMethod => ({
51+
code: `render().${queryMethod}()`,
52+
errors: [
53+
{
54+
messageId: 'preferScreenQueries',
55+
data: {
56+
name: queryMethod,
57+
},
58+
},
59+
],
60+
})),
61+
3862
...ALL_QUERIES_COMBINATIONS.map(queryMethod => ({
3963
code: `component.${queryMethod}()`,
4064
errors: [

0 commit comments

Comments
 (0)