diff --git a/lib/rules/await-async-utils.ts b/lib/rules/await-async-utils.ts index f26bd958..56d2223b 100644 --- a/lib/rules/await-async-utils.ts +++ b/lib/rules/await-async-utils.ts @@ -121,20 +121,29 @@ export default createTestingLibraryRule({ functionWrappersNames.push((node.id as TSESTree.Identifier).name); } }, - 'CallExpression Identifier'(node: TSESTree.Identifier) { + CallExpression(node: TSESTree.CallExpression) { + const callExpressionIdentifier = getDeepestIdentifierNode(node); + + if (!callExpressionIdentifier) { + return; + } + const isAsyncUtilOrKnownAliasAroundIt = - helpers.isAsyncUtil(node) || - functionWrappersNames.includes(node.name); + helpers.isAsyncUtil(callExpressionIdentifier) || + functionWrappersNames.includes(callExpressionIdentifier.name); if (!isAsyncUtilOrKnownAliasAroundIt) { return; } // detect async query used within wrapper function for later analysis - if (helpers.isAsyncUtil(node)) { - detectAsyncUtilWrapper(node); + if (helpers.isAsyncUtil(callExpressionIdentifier)) { + detectAsyncUtilWrapper(callExpressionIdentifier); } - const closestCallExpression = findClosestCallExpressionNode(node, true); + const closestCallExpression = findClosestCallExpressionNode( + callExpressionIdentifier, + true + ); if (!closestCallExpression?.parent) { return; @@ -146,12 +155,12 @@ export default createTestingLibraryRule({ ); if (references.length === 0) { - if (!isPromiseHandled(node)) { + if (!isPromiseHandled(callExpressionIdentifier)) { context.report({ - node, - messageId: getMessageId(node), + node: callExpressionIdentifier, + messageId: getMessageId(callExpressionIdentifier), data: { - name: node.name, + name: callExpressionIdentifier.name, }, }); } @@ -160,10 +169,10 @@ export default createTestingLibraryRule({ const referenceNode = reference.identifier as TSESTree.Identifier; if (!isPromiseHandled(referenceNode)) { context.report({ - node, - messageId: getMessageId(node), + node: callExpressionIdentifier, + messageId: getMessageId(callExpressionIdentifier), data: { - name: node.name, + name: callExpressionIdentifier.name, }, }); return; diff --git a/tests/lib/rules/await-async-queries.test.ts b/tests/lib/rules/await-async-queries.test.ts index 8354d346..b661d2cb 100644 --- a/tests/lib/rules/await-async-queries.test.ts +++ b/tests/lib/rules/await-async-queries.test.ts @@ -113,6 +113,11 @@ ruleTester.run(RULE_NAME, rule, { testingFramework: '@marko/testing-library', }), + // async queries not called are valid + ...createTestCase((query) => `expect(screen.${query}).toBeDefined()`, { + isAsync: false, + }), + // async queries are valid with await operator ...createTestCase( (query) => ` diff --git a/tests/lib/rules/await-async-utils.test.ts b/tests/lib/rules/await-async-utils.test.ts index e018a223..cbf2cdc0 100644 --- a/tests/lib/rules/await-async-utils.test.ts +++ b/tests/lib/rules/await-async-utils.test.ts @@ -31,6 +31,14 @@ ruleTester.run(RULE_NAME, rule, { const aPromise = ${asyncUtil}(() => getByLabelText('email')); await aPromise; }); + `, + })), + ...ASYNC_UTILS.map((asyncUtil) => ({ + code: ` + import { ${asyncUtil} } from '${testingFramework}'; + test('${asyncUtil} util not called is valid', () => { + expect(${asyncUtil}).toBeDefined(); + }); `, })), ...ASYNC_UTILS.map((asyncUtil) => ({ @@ -286,6 +294,23 @@ ruleTester.run(RULE_NAME, rule, { test('edge case for no innermost function scope', () => { const foo = waitFor }) + `, + }, + { + // edge case for coverage: CallExpressions without deepest identifiers + code: ` + import { waitFor } from '${testingFramework}'; + test('coverage test for CallExpressions without identifiers', () => { + const asyncUtil = waitFor + + // These CallExpressions have no deepest identifier: + const funcs = [() => console.log('test')] + const obj = { [Symbol.iterator]: () => 'symbol' } + + funcs[0]() + obj[Symbol.iterator]() + (function() { return 'iife' })() + }); `, }, ...ASYNC_UTILS.map((asyncUtil) => ({