Skip to content

Commit 247b205

Browse files
puglyfeCharley
andauthored
fix: handled promises assigned to vars are valid (#1047)
Fixes #1046 Co-authored-by: Charley <cpugmire@hubspot.com>
1 parent 35e2b40 commit 247b205

File tree

4 files changed

+166
-0
lines changed

4 files changed

+166
-0
lines changed

lib/rules/await-async-utils.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
getFunctionName,
88
getInnermostReturningFunction,
99
getVariableReferences,
10+
isCallExpression,
1011
isObjectPattern,
1112
isPromiseHandled,
1213
isProperty,
@@ -110,6 +111,8 @@ export default createTestingLibraryRule<Options, MessageIds>({
110111
const isAssigningKnownAsyncFunctionWrapper =
111112
ASTUtils.isIdentifier(node.id) &&
112113
node.init !== null &&
114+
!isCallExpression(node.init) &&
115+
!ASTUtils.isAwaitExpression(node.init) &&
113116
functionWrappersNames.includes(
114117
getDeepestIdentifierNode(node.init)?.name ?? ''
115118
);

tests/lib/rules/await-async-events.test.ts

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,21 @@ ruleTester.run(RULE_NAME, rule, {
134134
135135
await triggerEvent()
136136
})
137+
`,
138+
options: [{ eventModule: 'fireEvent' }] as const,
139+
})),
140+
...FIRE_EVENT_ASYNC_FUNCTIONS.map((eventMethod) => ({
141+
code: `
142+
import { fireEvent } from '${testingFramework}'
143+
test('await promise assigned to a variable from function wrapping event method is valid', () => {
144+
function triggerEvent() {
145+
doSomething()
146+
return fireEvent.${eventMethod}(getByLabelText('username'))
147+
}
148+
149+
const result = await triggerEvent()
150+
expect(result).toBe(undefined)
151+
})
137152
`,
138153
options: [{ eventModule: 'fireEvent' }] as const,
139154
})),
@@ -364,6 +379,21 @@ ruleTester.run(RULE_NAME, rule, {
364379
...USER_EVENT_ASYNC_FUNCTIONS.map((eventMethod) => ({
365380
code: `
366381
import userEvent from '${testingFramework}'
382+
test('await promise assigned to a variable from function wrapping event method is valid', () => {
383+
function triggerEvent() {
384+
doSomething()
385+
return userEvent.${eventMethod}(getByLabelText('username'))
386+
}
387+
388+
const result = await triggerEvent()
389+
expect(result).toBe(undefined)
390+
})
391+
`,
392+
options: [{ eventModule: 'userEvent' }] as const,
393+
})),
394+
...USER_EVENT_ASYNC_FUNCTIONS.map((eventMethod) => ({
395+
code: `
396+
import userEvent from '${testingFramework}'
367397
test('await expression that evaluates to promise is valid', async () => {
368398
await (null, userEvent.${eventMethod}(getByLabelText('username')));
369399
await (condition ? null : userEvent.${eventMethod}(getByLabelText('username')));
@@ -775,6 +805,44 @@ ruleTester.run(RULE_NAME, rule, {
775805
({
776806
code: `
777807
import { fireEvent } from '${testingFramework}'
808+
test('unhandled promise assigned to a variable returned from function wrapping event method is invalid', () => {
809+
function triggerEvent() {
810+
doSomething()
811+
return fireEvent.${eventMethod}(getByLabelText('username'))
812+
}
813+
814+
const result = triggerEvent()
815+
expect(result).toBe(undefined)
816+
})
817+
`,
818+
errors: [
819+
{
820+
line: 9,
821+
column: 24,
822+
messageId: 'awaitAsyncEventWrapper',
823+
data: { name: 'triggerEvent' },
824+
},
825+
],
826+
options: [{ eventModule: 'fireEvent' }],
827+
output: `
828+
import { fireEvent } from '${testingFramework}'
829+
test('unhandled promise assigned to a variable returned from function wrapping event method is invalid', async () => {
830+
function triggerEvent() {
831+
doSomething()
832+
return fireEvent.${eventMethod}(getByLabelText('username'))
833+
}
834+
835+
const result = await triggerEvent()
836+
expect(result).toBe(undefined)
837+
})
838+
`,
839+
}) as const
840+
),
841+
...FIRE_EVENT_ASYNC_FUNCTIONS.map(
842+
(eventMethod) =>
843+
({
844+
code: `
845+
import { fireEvent } from '${testingFramework}'
778846
779847
function triggerEvent() {
780848
doSomething()
@@ -977,6 +1045,44 @@ ruleTester.run(RULE_NAME, rule, {
9771045
({
9781046
code: `
9791047
import userEvent from '${testingFramework}'
1048+
test('unhandled promise assigned to a variable returned from function wrapping event method is invalid', function() {
1049+
function triggerEvent() {
1050+
doSomething()
1051+
return userEvent.${eventMethod}(getByLabelText('username'))
1052+
}
1053+
1054+
const result = triggerEvent()
1055+
expect(result).toBe(undefined)
1056+
})
1057+
`,
1058+
errors: [
1059+
{
1060+
line: 9,
1061+
column: 24,
1062+
messageId: 'awaitAsyncEventWrapper',
1063+
data: { name: 'triggerEvent' },
1064+
},
1065+
],
1066+
options: [{ eventModule: 'userEvent' }],
1067+
output: `
1068+
import userEvent from '${testingFramework}'
1069+
test('unhandled promise assigned to a variable returned from function wrapping event method is invalid', async function() {
1070+
function triggerEvent() {
1071+
doSomething()
1072+
return userEvent.${eventMethod}(getByLabelText('username'))
1073+
}
1074+
1075+
const result = await triggerEvent()
1076+
expect(result).toBe(undefined)
1077+
})
1078+
`,
1079+
}) as const
1080+
),
1081+
...USER_EVENT_ASYNC_FUNCTIONS.map(
1082+
(eventMethod) =>
1083+
({
1084+
code: `
1085+
import userEvent from '${testingFramework}'
9801086
9811087
function triggerEvent() {
9821088
doSomething()

tests/lib/rules/await-async-queries.test.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,23 @@ ruleTester.run(RULE_NAME, rule, {
291291
`,
292292
})),
293293

294+
// handled promise assigned to variable returned from async query wrapper is valid
295+
...ALL_ASYNC_COMBINATIONS_TO_TEST.map(
296+
(query) =>
297+
({
298+
code: `
299+
const queryWrapper = () => {
300+
return screen.${query}('foo')
301+
}
302+
303+
test("A valid example test", async () => {
304+
const element = await queryWrapper()
305+
expect(element).toBeVisible()
306+
})
307+
`,
308+
}) as const
309+
),
310+
294311
// non-matching query is valid
295312
`
296313
test('A valid example test', async () => {

tests/lib/rules/await-async-utils.test.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,20 @@ ruleTester.run(RULE_NAME, rule, {
250250
test('handled promise from function wrapping ${asyncUtil} util is valid', async () => {
251251
await waitForSomethingAsync()
252252
});
253+
`,
254+
})),
255+
...ASYNC_UTILS.map((asyncUtil) => ({
256+
code: `
257+
import { ${asyncUtil} } from '${testingFramework}';
258+
259+
function waitForSomethingAsync() {
260+
return ${asyncUtil}(() => somethingAsync())
261+
}
262+
263+
test('handled promise in variable declaration from function wrapping ${asyncUtil} util is valid', async () => {
264+
const result = await waitForSomethingAsync()
265+
expect(result).toBe('foo')
266+
});
253267
`,
254268
})),
255269
{
@@ -506,6 +520,32 @@ ruleTester.run(RULE_NAME, rule, {
506520
(asyncUtil) =>
507521
({
508522
code: `
523+
import { ${asyncUtil}, render } from '${testingFramework}';
524+
525+
function waitForSomethingAsync() {
526+
return ${asyncUtil}(() => somethingAsync())
527+
}
528+
529+
test('unhandled promise in variable declaration from function wrapping ${asyncUtil} util is invalid', async () => {
530+
render()
531+
const result = waitForSomethingAsync()
532+
expect(result).toBe('foo')
533+
});
534+
`,
535+
errors: [
536+
{
537+
messageId: 'asyncUtilWrapper',
538+
line: 10,
539+
column: 24,
540+
data: { name: 'waitForSomethingAsync' },
541+
},
542+
],
543+
}) as const
544+
),
545+
...ASYNC_UTILS.map(
546+
(asyncUtil) =>
547+
({
548+
code: `
509549
import { ${asyncUtil} } from 'some-other-library'; // rather than ${testingFramework}
510550
test(
511551
'aggressive reporting - util "${asyncUtil}" which is not related to testing library is invalid',

0 commit comments

Comments
 (0)