Skip to content

Commit 81b1f2f

Browse files
committed
include eslint rule
1 parent f1114ec commit 81b1f2f

File tree

1 file changed

+89
-0
lines changed

1 file changed

+89
-0
lines changed
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
/*
2+
* Copyright 2021 Adobe. All rights reserved.
3+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License. You may obtain a copy
5+
* of the License at http://www.apache.org/licenses/LICENSE-2.0
6+
*
7+
* Unless required by applicable law or agreed to in writing, software distributed under
8+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9+
* OF ANY KIND, either express or implied. See the License for the specific language
10+
* governing permissions and limitations under the License.
11+
*/
12+
13+
const rule = {
14+
create: (context) => ({
15+
CallExpression: function (node) {
16+
if (node?.callee?.object?.name === 'userEvent' && node?.callee?.property?.name === 'tab') {
17+
let foundAct = false;
18+
let visited = new Set();
19+
let parent = node?.parent;
20+
while (!foundAct && parent && !visited.has(parent)) {
21+
visited.add(parent);
22+
if (parent?.type === 'CallExpression' && (parent?.callee?.name === 'act' || parent?.callee?.name === 'actDOM')) {
23+
foundAct = true;
24+
break;
25+
}
26+
parent = parent?.parent;
27+
}
28+
if (!foundAct) {
29+
context.report({
30+
node: node.parent,
31+
message: 'userEvent.tab must be wrapped in an act or actDOM.',
32+
fix: (fixer) => [
33+
fixer.insertTextBefore(node.parent, 'act(() => {\n'),
34+
fixer.insertTextAfter(node.parent, '\n});')
35+
]
36+
});
37+
}
38+
}
39+
if (node?.callee?.property?.name === 'focus' || node?.callee?.property?.name === 'blur') {
40+
let foundAct = false;
41+
let visited = new Set();
42+
let parent = node?.parent;
43+
while (!foundAct && parent && !visited.has(parent)) {
44+
visited.add(parent);
45+
if (parent?.type === 'CallExpression' && (parent?.callee?.name === 'act' || parent?.callee?.name === 'actDOM')) {
46+
foundAct = true;
47+
break;
48+
}
49+
parent = parent?.parent;
50+
}
51+
if (!foundAct) {
52+
context.report({
53+
node: node.parent,
54+
message: 'Focus and blur must be wrapped in an act or actDOM',
55+
fix: (fixer) => [
56+
fixer.insertTextBefore(node.parent, 'act(() => {\n'),
57+
fixer.insertTextAfter(node.parent, '\n});')
58+
]
59+
});
60+
}
61+
}
62+
if (node?.callee?.property?.name === 'runAllTimers' || node?.callee?.property?.name === 'advanceTimersByTime' || node?.callee?.property?.name === 'runOnlyPendingTimers') {
63+
let foundAct = false;
64+
let visited = new Set();
65+
let parent = node?.parent;
66+
while (!foundAct && parent && !visited.has(parent)) {
67+
visited.add(parent);
68+
if (parent?.type === 'CallExpression' && (parent?.callee?.name === 'act' || parent?.callee?.name === 'actDOM')) {
69+
foundAct = true;
70+
break;
71+
}
72+
parent = parent?.parent;
73+
}
74+
if (!foundAct) {
75+
context.report({
76+
node: node.parent,
77+
message: 'All timer advancing must be wrapped in an act or actDOM',
78+
fix: (fixer) => [
79+
fixer.insertTextBefore(node.parent, 'act(() => {\n'),
80+
fixer.insertTextAfter(node.parent, '\n});')
81+
]
82+
});
83+
}
84+
}
85+
}
86+
})
87+
};
88+
89+
module.exports = rule;

0 commit comments

Comments
 (0)