Skip to content

Commit 88246fc

Browse files
authored
fix(no-await-sync-events): stop reporting user-event by default (#803)
1 parent d55569b commit 88246fc

File tree

6 files changed

+62
-29
lines changed

6 files changed

+62
-29
lines changed

docs/rules/no-await-sync-events.md

+15-9
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
<!-- end auto-generated rule header -->
66

7-
Ensure that sync simulated events are not awaited unnecessarily.
7+
Ensure that sync events are not awaited unnecessarily.
88

99
## Rule Details
1010

@@ -22,6 +22,12 @@ Some examples of simulating events not returning any Promise are:
2222

2323
This rule aims to prevent users from waiting for those function calls.
2424

25+
> ⚠️ `fire-event` methods are async only on following Testing Library packages:
26+
>
27+
> - `@testing-library/vue` (supported by this plugin)
28+
> - `@testing-library/svelte` (not supported yet by this plugin)
29+
> - `@marko/testing-library` (supported by this plugin)
30+
2531
Examples of **incorrect** code for this rule:
2632

2733
```js
@@ -87,13 +93,9 @@ const qux = async () => {
8793

8894
This rule provides the following options:
8995

90-
- `eventModules`: array of strings. The possibilities are: `"fire-event"` and `"user-event"`. Defaults to `["fire-event", "user-event"]`
91-
92-
### `eventModules`
93-
94-
This option gives you more granular control of which event modules you want to report, so you can choose to only report methods from either `fire-event`, `user-event` or both.
96+
- `eventModules`: array of strings. Defines which event module should be linted for sync event methods. The possibilities are: `"fire-event"` and `"user-event"`. Defaults to `["fire-event"]`.
9597

96-
Example:
98+
### Example:
9799

98100
```js
99101
module.exports = {
@@ -106,7 +108,11 @@ module.exports = {
106108
};
107109
```
108110

111+
## When Not To Use It
112+
113+
- `"fire-event"` option: should be disabled only for those Testing Library packages where fire-event methods are async.
114+
- `"user-event"` option: should be disabled only if using v14 or greater.
115+
109116
## Notes
110117

111-
- Since `user-event` v14 all its methods are async, so you should disable reporting them by setting the `eventModules` to just `"fire-event"` so `user-event` methods are not reported.
112-
- There is another rule `await-async-events`, which is for awaiting async events for `user-event` v14 or `fire-event` only in Vue Testing Library. Please do not confuse with this rule.
118+
There is another rule `await-async-events`, which is for awaiting async events for `user-event` v14 or `fire-event` only in Testing Library packages with async methods. Please do not confuse with this rule.

lib/configs/angular.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,10 @@ export = {
1111
],
1212
'testing-library/await-async-queries': 'error',
1313
'testing-library/await-async-utils': 'error',
14-
'testing-library/no-await-sync-events': 'error',
14+
'testing-library/no-await-sync-events': [
15+
'error',
16+
{ eventModules: ['fire-event'] },
17+
],
1518
'testing-library/no-await-sync-queries': 'error',
1619
'testing-library/no-container': 'error',
1720
'testing-library/no-debugging-utils': 'warn',

lib/configs/dom.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,10 @@ export = {
1111
],
1212
'testing-library/await-async-queries': 'error',
1313
'testing-library/await-async-utils': 'error',
14-
'testing-library/no-await-sync-events': 'error',
14+
'testing-library/no-await-sync-events': [
15+
'error',
16+
{ eventModules: ['fire-event'] },
17+
],
1518
'testing-library/no-await-sync-queries': 'error',
1619
'testing-library/no-global-regexp-flag-in-query': 'error',
1720
'testing-library/no-node-access': 'error',

lib/configs/react.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,10 @@ export = {
1111
],
1212
'testing-library/await-async-queries': 'error',
1313
'testing-library/await-async-utils': 'error',
14-
'testing-library/no-await-sync-events': 'error',
14+
'testing-library/no-await-sync-events': [
15+
'error',
16+
{ eventModules: ['fire-event'] },
17+
],
1518
'testing-library/no-await-sync-queries': 'error',
1619
'testing-library/no-container': 'error',
1720
'testing-library/no-debugging-utils': 'warn',

lib/rules/no-await-sync-events.ts

+17-14
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,17 @@ import {
1010
} from '../node-utils';
1111

1212
const USER_EVENT_ASYNC_EXCEPTIONS: string[] = ['type', 'keyboard'];
13-
const VALID_EVENT_MODULES = ['fire-event', 'user-event'] as const;
13+
const FIRE_EVENT_OPTION = 'fire-event' as const;
14+
const USER_EVENT_OPTION = 'user-event' as const;
15+
const VALID_EVENT_MODULES = [FIRE_EVENT_OPTION, USER_EVENT_OPTION];
16+
const DEFAULT_EVENT_MODULES = [FIRE_EVENT_OPTION];
1417

1518
export const RULE_NAME = 'no-await-sync-events';
1619
export type MessageIds = 'noAwaitSyncEvents';
17-
type Options = [
18-
{ eventModules?: readonly (typeof VALID_EVENT_MODULES)[number][] }
19-
];
20+
21+
type ValidEventModules = (typeof VALID_EVENT_MODULES)[number];
22+
type EventModulesOptions = ReadonlyArray<ValidEventModules>;
23+
type Options = [{ eventModules?: EventModulesOptions }];
2024

2125
export default createTestingLibraryRule<Options, MessageIds>({
2226
name: RULE_NAME,
@@ -25,9 +29,9 @@ export default createTestingLibraryRule<Options, MessageIds>({
2529
docs: {
2630
description: 'Disallow unnecessary `await` for sync events',
2731
recommendedConfig: {
28-
dom: 'error',
29-
angular: 'error',
30-
react: 'error',
32+
dom: ['error', { eventModules: DEFAULT_EVENT_MODULES }],
33+
angular: ['error', { eventModules: DEFAULT_EVENT_MODULES }],
34+
react: ['error', { eventModules: DEFAULT_EVENT_MODULES }],
3135
vue: false,
3236
marko: false,
3337
},
@@ -42,20 +46,19 @@ export default createTestingLibraryRule<Options, MessageIds>({
4246
properties: {
4347
eventModules: {
4448
type: 'array',
49+
items: { type: 'string', enum: VALID_EVENT_MODULES },
4550
minItems: 1,
46-
items: {
47-
enum: VALID_EVENT_MODULES,
48-
},
51+
default: DEFAULT_EVENT_MODULES,
4952
},
5053
},
5154
additionalProperties: false,
5255
},
5356
],
5457
},
55-
defaultOptions: [{ eventModules: VALID_EVENT_MODULES }],
58+
defaultOptions: [{ eventModules: DEFAULT_EVENT_MODULES }],
5659

5760
create(context, [options], helpers) {
58-
const { eventModules = VALID_EVENT_MODULES } = options;
61+
const { eventModules = DEFAULT_EVENT_MODULES } = options;
5962
let hasDelayDeclarationOrAssignmentGTZero: boolean;
6063

6164
// userEvent.type() and userEvent.keyboard() are exceptions, which returns a
@@ -107,10 +110,10 @@ export default createTestingLibraryRule<Options, MessageIds>({
107110
return;
108111
}
109112

110-
if (isFireEventMethod && !eventModules.includes('fire-event')) {
113+
if (isFireEventMethod && !eventModules.includes(FIRE_EVENT_OPTION)) {
111114
return;
112115
}
113-
if (isUserEventMethod && !eventModules.includes('user-event')) {
116+
if (isUserEventMethod && !eventModules.includes(USER_EVENT_OPTION)) {
114117
return;
115118
}
116119

tests/lib/rules/no-await-sync-events.test.ts

+18-3
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,16 @@ ruleTester.run(RULE_NAME, rule, {
219219
`,
220220
options: [{ eventModules: ['fire-event'] }],
221221
})),
222+
223+
// valid tests for user-event with default options (user-event disabled)
224+
...USER_EVENT_SYNC_FUNCTIONS.map((func) => ({
225+
code: `
226+
import userEvent from '@testing-library/user-event';
227+
test('should not report userEvent.${func} by default', async() => {
228+
await userEvent.${func}('foo');
229+
});
230+
`,
231+
})),
222232
],
223233

224234
invalid: [
@@ -254,6 +264,7 @@ ruleTester.run(RULE_NAME, rule, {
254264
await userEvent.${func}('foo');
255265
});
256266
`,
267+
options: [{ eventModules: ['user-event'] }],
257268
errors: [
258269
{
259270
line: 4,
@@ -277,7 +288,6 @@ ruleTester.run(RULE_NAME, rule, {
277288
await fireEvent.${func}('foo');
278289
});
279290
`,
280-
options: [{ eventModules: ['fire-event'] }],
281291
errors: [
282292
{
283293
line: 4,
@@ -289,8 +299,7 @@ ruleTester.run(RULE_NAME, rule, {
289299
} as const)
290300
)
291301
),
292-
// sync userEvent sync methods with await operator are not valid
293-
// when only fire-event set in eventModules
302+
294303
...USER_EVENT_SYNC_FUNCTIONS.map(
295304
(func) =>
296305
({
@@ -320,6 +329,7 @@ ruleTester.run(RULE_NAME, rule, {
320329
await userEvent.keyboard('foo');
321330
});
322331
`,
332+
options: [{ eventModules: ['user-event'] }],
323333
errors: [
324334
{
325335
line: 4,
@@ -343,6 +353,7 @@ ruleTester.run(RULE_NAME, rule, {
343353
await userEvent.keyboard('foo', { delay: 0 });
344354
});
345355
`,
356+
options: [{ eventModules: ['user-event'] }],
346357
errors: [
347358
{
348359
line: 4,
@@ -370,6 +381,7 @@ ruleTester.run(RULE_NAME, rule, {
370381
await renamedUserEvent.keyboard('foo', { delay: 0 });
371382
});
372383
`,
384+
options: [{ eventModules: ['user-event', 'fire-event'] }],
373385
errors: [
374386
{
375387
line: 6,
@@ -397,6 +409,7 @@ ruleTester.run(RULE_NAME, rule, {
397409
await userEvent.type('foo', { delay });
398410
}
399411
`,
412+
options: [{ eventModules: ['user-event'] }],
400413
errors: [
401414
{
402415
line: 3,
@@ -414,6 +427,7 @@ ruleTester.run(RULE_NAME, rule, {
414427
await userEvent.type('foo', { delay, skipHover });
415428
}
416429
`,
430+
options: [{ eventModules: ['user-event'] }],
417431
errors: [
418432
{
419433
line: 5,
@@ -433,6 +447,7 @@ ruleTester.run(RULE_NAME, rule, {
433447
await userEvent.type('foo', { delay, skipHover });
434448
}
435449
`,
450+
options: [{ eventModules: ['user-event'] }],
436451
errors: [
437452
{
438453
line: 7,

0 commit comments

Comments
 (0)