From 32aede1f3cee5e5576a90b5479eab9b1ee93e0ca Mon Sep 17 00:00:00 2001 From: Victor Cordova Date: Sat, 18 Apr 2020 09:28:41 +0200 Subject: [PATCH 1/5] refactor(await-async-query): remove redundant checks While running Program:exit(), nodes were tested again unnecessarily for isAwaited and isPromiseResolved --- lib/rules/await-async-query.js | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/lib/rules/await-async-query.js b/lib/rules/await-async-query.js index d46ef702..0f655266 100644 --- a/lib/rules/await-async-query.js +++ b/lib/rules/await-async-query.js @@ -49,12 +49,7 @@ module.exports = { .references.slice(1)) || []; - if ( - references && - references.length === 0 && - !isAwaited(node.parent.parent) && - !isPromiseResolved(node) - ) { + if (references && references.length === 0) { context.report({ node, messageId: 'awaitAsyncQuery', From b924ac70262380a34ea8d655988914bd2ace20ee Mon Sep 17 00:00:00 2001 From: Victor Cordova Date: Sat, 18 Apr 2020 09:46:26 +0200 Subject: [PATCH 2/5] fix(await-async-query): check queries being called as member expressions First, abstract a isQueryUsage function to check if a node should be checked for this rule. Then, add new selector for queries being called as part of MemberExpression and check their parent against the rule. Finally, use the queryName prop to make sure the right error message is printed --- lib/rules/await-async-query.js | 26 +++++++++++++++++--------- tests/lib/rules/await-async-query.js | 27 +++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 9 deletions(-) diff --git a/lib/rules/await-async-query.js b/lib/rules/await-async-query.js index 0f655266..9b8adc85 100644 --- a/lib/rules/await-async-query.js +++ b/lib/rules/await-async-query.js @@ -28,18 +28,26 @@ module.exports = { create: function(context) { const testingLibraryQueryUsage = []; + const isQueryUsage = node => + !isAwaited(node.parent.parent) && + !isPromiseResolved(node) && + !hasClosestExpectResolvesRejects(node); + return { [`CallExpression > Identifier[name=${ASYNC_QUERIES_REGEXP}]`](node) { - if ( - !isAwaited(node.parent.parent) && - !isPromiseResolved(node) && - !hasClosestExpectResolvesRejects(node) - ) { - testingLibraryQueryUsage.push(node); + if (isQueryUsage(node)) { + testingLibraryQueryUsage.push({ node, queryName: node.name }); + } + }, + [`MemberExpression > Identifier[name=${ASYNC_QUERIES_REGEXP}]`](node) { + // Perform checks in parent MemberExpression insted of current identifier + const parent = node.parent; + if (isQueryUsage(parent)) { + testingLibraryQueryUsage.push({ node: parent, queryName: node.name }); } }, 'Program:exit'() { - testingLibraryQueryUsage.forEach(node => { + testingLibraryQueryUsage.forEach(({ node, queryName }) => { const variableDeclaratorParent = node.parent.parent; const references = @@ -54,7 +62,7 @@ module.exports = { node, messageId: 'awaitAsyncQuery', data: { - name: node.name, + name: queryName, }, }); } else { @@ -68,7 +76,7 @@ module.exports = { node, messageId: 'awaitAsyncQuery', data: { - name: node.name, + name: queryName, }, }); diff --git a/tests/lib/rules/await-async-query.js b/tests/lib/rules/await-async-query.js index b21d6a8c..6919f8ee 100644 --- a/tests/lib/rules/await-async-query.js +++ b/tests/lib/rules/await-async-query.js @@ -25,6 +25,14 @@ ruleTester.run('await-async-query', rule, { `, })), + // async queries declaration are valid + ...ASYNC_QUERIES_COMBINATIONS.map(query => ({ + code: `async () => { + await screen.${query}('foo') + } + `, + })), + // async queries with await operator are valid ...ASYNC_QUERIES_COMBINATIONS.map(query => ({ code: `async () => { @@ -151,6 +159,25 @@ ruleTester.run('await-async-query', rule, { }, ], })), + ...ASYNC_QUERIES_COMBINATIONS.map(query => ({ + code: `async () => { + screen.${query}('foo') + } + `, + errors: [ + { + messageId: 'awaitAsyncQuery', + }, + ], + })), + ...ASYNC_QUERIES_COMBINATIONS.map(query => ({ + code: `const foo = screen.${query}('foo')`, + errors: [ + { + messageId: 'awaitAsyncQuery', + }, + ], + })), ...ASYNC_QUERIES_COMBINATIONS.map(query => ({ code: `async () => { const foo = ${query}('foo') From 494960f13fbcfaaba19be9af15e99ec0693ec61b Mon Sep 17 00:00:00 2001 From: Victor Cordova Date: Sat, 18 Apr 2020 09:47:11 +0200 Subject: [PATCH 3/5] docs(await-async-query): add valid and invalid examples using screen --- docs/rules/await-async-query.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/docs/rules/await-async-query.md b/docs/rules/await-async-query.md index bb556ab6..493b7d03 100644 --- a/docs/rules/await-async-query.md +++ b/docs/rules/await-async-query.md @@ -30,6 +30,12 @@ const bar = () => { findByText('submit'); // ... }; + +const baz = () => { + // ... + screen.findAllByPlaceholderText('name'); + // ... +}; ``` Examples of **correct** code for this rule: @@ -50,6 +56,12 @@ const bar = () => { }); }; +const baz = () => { + // ... + await screen.findAllByPlaceholderText('name'); + // ... +}; + // return the promise within a function is correct too! const findMyButton = () => findByText('my button'); From 27505b2f07b76e11d5e7c55d2980cc132cca88d8 Mon Sep 17 00:00:00 2001 From: Victor Cordova Date: Sat, 18 Apr 2020 10:01:57 +0200 Subject: [PATCH 4/5] fix(no-await-sync-query): prevent screen sync queries from using await First, abstract reportError function. Then, create selector for MemberExpression queries. --- lib/rules/no-await-sync-query.js | 21 ++++++++++----------- tests/lib/rules/no-await-sync-query.js | 18 ++++++++++++++++-- 2 files changed, 26 insertions(+), 13 deletions(-) diff --git a/lib/rules/no-await-sync-query.js b/lib/rules/no-await-sync-query.js index ada23267..b74a7be3 100644 --- a/lib/rules/no-await-sync-query.js +++ b/lib/rules/no-await-sync-query.js @@ -21,18 +21,17 @@ module.exports = { }, create: function(context) { + const reportError = node => + context.report({ + node, + messageId: 'noAwaitSyncQuery', + data: { + name: node.name, + }, + }); return { - [`AwaitExpression > CallExpression > Identifier[name=${SYNC_QUERIES_REGEXP}]`]( - node - ) { - context.report({ - node, - messageId: 'noAwaitSyncQuery', - data: { - name: node.name, - }, - }); - }, + [`AwaitExpression > CallExpression > Identifier[name=${SYNC_QUERIES_REGEXP}]`]: reportError, + [`AwaitExpression > CallExpression > MemberExpression > Identifier[name=${SYNC_QUERIES_REGEXP}]`]: reportError, }; }, }; diff --git a/tests/lib/rules/no-await-sync-query.js b/tests/lib/rules/no-await-sync-query.js index 01af671a..fa8113a7 100644 --- a/tests/lib/rules/no-await-sync-query.js +++ b/tests/lib/rules/no-await-sync-query.js @@ -43,9 +43,9 @@ ruleTester.run('no-await-sync-query', rule, { })), ], - invalid: + invalid: [ // sync queries with await operator are not valid - SYNC_QUERIES_COMBINATIONS.map(query => ({ + ...SYNC_QUERIES_COMBINATIONS.map(query => ({ code: `async () => { await ${query}('foo') } @@ -56,4 +56,18 @@ ruleTester.run('no-await-sync-query', rule, { }, ], })), + + // sync queries in screen with await operator are not valid + ...SYNC_QUERIES_COMBINATIONS.map(query => ({ + code: `async () => { + await screen.${query}('foo') + } + `, + errors: [ + { + messageId: 'noAwaitSyncQuery', + }, + ], + })), + ], }); From a7fca52b7fb0fd463908675866287b223436424a Mon Sep 17 00:00:00 2001 From: Victor Cordova Date: Sat, 18 Apr 2020 10:03:35 +0200 Subject: [PATCH 5/5] docs(no-await-sync-query): add valid and invalid examples using screen --- docs/rules/no-await-sync-query.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/rules/no-await-sync-query.md b/docs/rules/no-await-sync-query.md index 394b76d4..b84f117c 100644 --- a/docs/rules/no-await-sync-query.md +++ b/docs/rules/no-await-sync-query.md @@ -29,6 +29,11 @@ const bar = () => { // ... }); }; + +const baz = () => { + // ... + const button = await screen.getByText('submit'); +}; ``` Examples of **correct** code for this rule: @@ -45,6 +50,11 @@ const bar = () => { const button = getByText('submit'); // ... }; + +const baz = () => { + // ... + const button = screen.getByText('submit'); +}; ``` ## Further Reading