Skip to content

Commit 9011b9b

Browse files
committed
feat(no-unnecessary-act): first bunch of tests
1 parent c907890 commit 9011b9b

File tree

2 files changed

+217
-0
lines changed

2 files changed

+217
-0
lines changed

lib/rules/no-unnecessary-act.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ export default createTestingLibraryRule<[], MessageIds>({
3535
function hasNonTestingLibraryCall(
3636
statements: TSESTree.Statement[]
3737
): boolean {
38+
// TODO: refactor to use Array.every
3839
for (const statement of statements) {
3940
if (!isExpressionStatement(statement)) {
4041
continue;
@@ -88,6 +89,11 @@ export default createTestingLibraryRule<[], MessageIds>({
8889
if (hasNonTestingLibraryCall(blockStatementNode.body)) {
8990
return;
9091
}
92+
93+
context.report({
94+
node: callExpressionIdentifier,
95+
messageId: 'noUnnecessaryActTestingLibraryUtil',
96+
});
9197
}
9298

9399
return {
Lines changed: 211 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,211 @@
1+
import { createRuleTester } from '../test-utils';
2+
import rule, { RULE_NAME } from '../../../lib/rules/no-unnecessary-act';
3+
4+
const ruleTester = createRuleTester();
5+
6+
/**
7+
* - AGR stands for Aggressive Reporting
8+
* - RTL stands for react-testing-library (@testing-library/react)
9+
* - RTU stands for react-test-utils (react-dom/test-utils)
10+
*/
11+
ruleTester.run(RULE_NAME, rule, {
12+
valid: [
13+
{
14+
code: `// case: RTL act wrapping non-RTL calls
15+
import { act } from '@testing-library/react'
16+
17+
test('valid case', async () => {
18+
act(() => {
19+
stuffThatDoesNotUseRTL();
20+
});
21+
22+
await act(async () => {
23+
stuffThatDoesNotUseRTL();
24+
});
25+
26+
act(function() {
27+
stuffThatDoesNotUseRTL();
28+
});
29+
30+
/* TODO get this one back
31+
act(function() {
32+
return stuffThatDoesNotUseRTL();
33+
});
34+
*/
35+
36+
act(() => stuffThatDoesNotUseRTL());
37+
});
38+
`,
39+
},
40+
{
41+
code: `// case: RTU act wrapping non-RTL
42+
import { act } from 'react-dom/test-utils'
43+
44+
test('valid case', async () => {
45+
act(() => {
46+
stuffThatDoesNotUseRTL();
47+
});
48+
49+
await act(async () => {
50+
stuffThatDoesNotUseRTL();
51+
});
52+
53+
act(function() {
54+
stuffThatDoesNotUseRTL();
55+
});
56+
57+
/* TODO get this one back
58+
act(function() {
59+
return stuffThatDoesNotUseRTL();
60+
});
61+
*/
62+
63+
act(() => stuffThatDoesNotUseRTL());
64+
});
65+
`,
66+
},
67+
{
68+
settings: {
69+
'testing-library/utils-module': 'test-utils',
70+
},
71+
code: `// case: RTL act wrapping non-RTL - AGR disabled
72+
import { act } from '@testing-library/react'
73+
import { waitFor } from 'somewhere-else'
74+
75+
test('valid case', async () => {
76+
act(() => {
77+
waitFor();
78+
});
79+
80+
await act(async () => {
81+
waitFor();
82+
});
83+
84+
act(function() {
85+
waitFor();
86+
});
87+
88+
/* TODO get this one back
89+
act(function() {
90+
return waitFor();
91+
});
92+
*/
93+
94+
act(() => waitFor());
95+
});
96+
`,
97+
},
98+
{
99+
code: `// case: RTL act wrapping both RTL and non-RTL calls
100+
import { act, render, waitFor } from '@testing-library/react'
101+
102+
test('valid case', async () => {
103+
act(() => {
104+
render(<Foo />);
105+
stuffThatDoesNotUseRTL();
106+
});
107+
108+
await act(async () => {
109+
waitFor();
110+
stuffThatDoesNotUseRTL();
111+
});
112+
113+
act(function() {
114+
waitFor();
115+
stuffThatDoesNotUseRTL();
116+
});
117+
});
118+
`,
119+
},
120+
],
121+
invalid: [
122+
{
123+
code: `// case: RTL act wrapping RTL calls - callbacks with body (BlockStatement)
124+
import { act, fireEvent, screen, render, waitFor, waitForElementToBeRemoved } from '@testing-library/react'
125+
import userEvent from '@testing-library/user-event'
126+
127+
test('invalid case', async () => {
128+
act(() => {
129+
fireEvent.click(el);
130+
});
131+
132+
await act(async () => {
133+
waitFor(() => {});
134+
});
135+
136+
await act(async () => {
137+
waitForElementToBeRemoved(el);
138+
});
139+
140+
act(function() {
141+
const blah = screen.getByText('blah');
142+
});
143+
144+
act(function() {
145+
render(something);
146+
});
147+
148+
await act(() => {
149+
const button = findByRole('button')
150+
});
151+
152+
act(() => {
153+
userEvent.click(el)
154+
});
155+
156+
act(() => {
157+
waitFor();
158+
const element = screen.getByText('blah');
159+
userEvent.click(element)
160+
});
161+
});
162+
`,
163+
errors: [
164+
{ messageId: 'noUnnecessaryActTestingLibraryUtil', line: 6, column: 9 },
165+
{
166+
messageId: 'noUnnecessaryActTestingLibraryUtil',
167+
line: 10,
168+
column: 15,
169+
},
170+
{
171+
messageId: 'noUnnecessaryActTestingLibraryUtil',
172+
line: 14,
173+
column: 15,
174+
},
175+
{
176+
messageId: 'noUnnecessaryActTestingLibraryUtil',
177+
line: 18,
178+
column: 9,
179+
},
180+
{
181+
messageId: 'noUnnecessaryActTestingLibraryUtil',
182+
line: 22,
183+
column: 9,
184+
},
185+
{
186+
messageId: 'noUnnecessaryActTestingLibraryUtil',
187+
line: 26,
188+
column: 15,
189+
},
190+
{
191+
messageId: 'noUnnecessaryActTestingLibraryUtil',
192+
line: 30,
193+
column: 9,
194+
},
195+
{
196+
messageId: 'noUnnecessaryActTestingLibraryUtil',
197+
line: 34,
198+
column: 9,
199+
},
200+
],
201+
},
202+
203+
// TODO case: RTL act wrapping RTL calls - callbacks with return
204+
// TODO case: RTU act wrapping RTL calls - callbacks with body (BlockStatement)
205+
// TODO case: RTU act wrapping RTL calls - callbacks with return
206+
// TODO case: RTL act wrapping empty callback
207+
// TODO case: RTU act wrapping empty callback
208+
209+
// TODO cases like previous ones but with AGR disabled
210+
],
211+
});

0 commit comments

Comments
 (0)