From ac3b73b6fb6d8200b6febc7789f61ba2036145d0 Mon Sep 17 00:00:00 2001 From: renatoagds Date: Tue, 16 Jun 2020 00:15:11 -0300 Subject: [PATCH 01/15] feat: add initial files for no-multiple-expect-wait-for rule --- lib/index.ts | 2 ++ lib/rules/no-multiple-expect-wait-for.ts | 5 +++++ .../rules/no-multiple-expect-wait-for.test.ts | 21 +++++++++++++++++++ 3 files changed, 28 insertions(+) create mode 100644 lib/rules/no-multiple-expect-wait-for.ts create mode 100644 tests/lib/rules/no-multiple-expect-wait-for.test.ts diff --git a/lib/index.ts b/lib/index.ts index 07f8a89b..7a32dd86 100644 --- a/lib/index.ts +++ b/lib/index.ts @@ -11,6 +11,7 @@ import preferExplicitAssert from './rules/prefer-explicit-assert'; import preferPresenceQueries from './rules/prefer-presence-queries'; import preferScreenQueries from './rules/prefer-screen-queries'; import preferWaitFor from './rules/prefer-wait-for'; +import noMultipleExpectWaitFor from './rules/no-multiple-expect-wait-for' const rules = { 'await-async-query': awaitAsyncQuery, @@ -21,6 +22,7 @@ const rules = { 'no-debug': noDebug, 'no-dom-import': noDomImport, 'no-manual-cleanup': noManualCleanup, + 'no-multiple-expect-wait-for': noMultipleExpectWaitFor, 'no-wait-for-empty-callback': noWaitForEmptyCallback, 'prefer-explicit-assert': preferExplicitAssert, 'prefer-presence-queries': preferPresenceQueries, diff --git a/lib/rules/no-multiple-expect-wait-for.ts b/lib/rules/no-multiple-expect-wait-for.ts new file mode 100644 index 00000000..89fc69b2 --- /dev/null +++ b/lib/rules/no-multiple-expect-wait-for.ts @@ -0,0 +1,5 @@ +export { ESLintUtils } from '@typescript-eslint/experimental-utils' + +export const RULE_NAME = 'no-multiple-expect-wait-for'; + +export default () => {} diff --git a/tests/lib/rules/no-multiple-expect-wait-for.test.ts b/tests/lib/rules/no-multiple-expect-wait-for.test.ts new file mode 100644 index 00000000..ea17c009 --- /dev/null +++ b/tests/lib/rules/no-multiple-expect-wait-for.test.ts @@ -0,0 +1,21 @@ +import { createRuleTester } from '../test-utils'; +import rule, { RULE_NAME } from '../../../lib/rules/no-multiple-expect-wait-for'; + +const ruleTester = createRuleTester({ + ecmaFeatures: { + jsx: true, + }, +}); + +ruleTester.run(RULE_NAME, rule, { + invalid: [ + { + code: ` + await waitFor(() => { + expect(a).toEqual('a') + expect(b).toEqual('b') + }) + ` + } + ] +}) From b5042f877338e1f45ce0468ca936043223709ab3 Mon Sep 17 00:00:00 2001 From: renatoagds Date: Mon, 22 Jun 2020 00:27:07 -0300 Subject: [PATCH 02/15] fix: add expect fields in test --- tests/lib/rules/no-multiple-expect-wait-for.test.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/lib/rules/no-multiple-expect-wait-for.test.ts b/tests/lib/rules/no-multiple-expect-wait-for.test.ts index ea17c009..ed380f61 100644 --- a/tests/lib/rules/no-multiple-expect-wait-for.test.ts +++ b/tests/lib/rules/no-multiple-expect-wait-for.test.ts @@ -8,6 +8,7 @@ const ruleTester = createRuleTester({ }); ruleTester.run(RULE_NAME, rule, { + valid: [], invalid: [ { code: ` @@ -15,7 +16,8 @@ ruleTester.run(RULE_NAME, rule, { expect(a).toEqual('a') expect(b).toEqual('b') }) - ` + `, + errors: [] } ] }) From a1ce5296cc8189135fbd9b66a5cc40a34ed595ea Mon Sep 17 00:00:00 2001 From: renatoagds Date: Mon, 22 Jun 2020 00:27:31 -0300 Subject: [PATCH 03/15] feat: add no-multiple-assertion-wait-for logic --- lib/rules/no-multiple-expect-wait-for.ts | 54 +++++++++++++++++++++++- 1 file changed, 52 insertions(+), 2 deletions(-) diff --git a/lib/rules/no-multiple-expect-wait-for.ts b/lib/rules/no-multiple-expect-wait-for.ts index 89fc69b2..5ddb91ae 100644 --- a/lib/rules/no-multiple-expect-wait-for.ts +++ b/lib/rules/no-multiple-expect-wait-for.ts @@ -1,5 +1,55 @@ -export { ESLintUtils } from '@typescript-eslint/experimental-utils' +import { ESLintUtils, TSESTree } from '@typescript-eslint/experimental-utils' +import { getDocsUrl } from '../utils' +import { isBlockStatement } from '../node-utils' export const RULE_NAME = 'no-multiple-expect-wait-for'; -export default () => {} +const WAIT_EXPRESSION_QUERY = + 'CallExpression[callee.name=/^(waitFor)$/]'; + +export type MessageIds = 'noMultipleAssertionWaitFor'; +type Options = []; + +export default ESLintUtils.RuleCreator(getDocsUrl)({ + name: RULE_NAME, + meta: { + type: 'suggestion', + docs: { + description: + "It's preferred to avoid multiple assertions in `waitFor`", + category: 'Best Practices', + recommended: false, + }, + messages: { + noMultipleAssertionWaitFor: 'Avoid use multiple assertions to `{{ methodName }}`', + }, + fixable: null, + schema: [], + }, + defaultOptions: [], + create: function(context) { + function reporttMultipleAssertion( + node: TSESTree.BlockStatement + ) { + if (isBlockStatement(node) && node.body.length > 1) { + const waitForCall: TSESTree.CallExpression = node.parent.parent as TSESTree.CallExpression + const waitForIdentifier: TSESTree.Identifier = waitForCall.callee as TSESTree.Identifier + const methodName = waitForIdentifier.name + + context.report({ + node, + loc: node.loc.start, + messageId: 'noMultipleAssertionWaitFor', + data: { + methodName, + }, + }); + } + } + + return { + [`${WAIT_EXPRESSION_QUERY} > ArrowFunctionExpression > BlockStatement`]: reporttMultipleAssertion, + [`${WAIT_EXPRESSION_QUERY} > FunctionExpression > BlockStatement`]: reporttMultipleAssertion, + }; + } +}) From 9210399073b445e9e7ba6858e40c6f459f962e78 Mon Sep 17 00:00:00 2001 From: renatoagds Date: Wed, 24 Jun 2020 01:02:17 -0300 Subject: [PATCH 04/15] feat: add findClosestCalleName in node-utils --- lib/node-utils.ts | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/lib/node-utils.ts b/lib/node-utils.ts index bf84eed7..1ab33ef5 100644 --- a/lib/node-utils.ts +++ b/lib/node-utils.ts @@ -95,6 +95,23 @@ export function findClosestCallNode( } } +export function findClosestCalleName( + node: TSESTree.Node +): string { + if (!node.parent) { + return ''; + } + + if ( + isCallExpression(node) && + isIdentifier(node.callee) + ) { + return node.callee.name; + } else { + return findClosestCalleName(node.parent); + } +} + export function hasThenProperty(node: TSESTree.Node) { return ( isMemberExpression(node) && From e406e4080bfc2ef015fe037c4cdd7d342610301b Mon Sep 17 00:00:00 2001 From: renatoagds Date: Wed, 24 Jun 2020 02:27:46 -0300 Subject: [PATCH 05/15] feat: add check for expect and rename file --- lib/index.ts | 4 +- ....ts => no-multiple-assertions-wait-for.ts} | 22 +++++++-- .../no-multiple-assertions-wait-for.test.ts | 46 +++++++++++++++++++ .../rules/no-multiple-expect-wait-for.test.ts | 23 ---------- 4 files changed, 65 insertions(+), 30 deletions(-) rename lib/rules/{no-multiple-expect-wait-for.ts => no-multiple-assertions-wait-for.ts} (59%) create mode 100644 tests/lib/rules/no-multiple-assertions-wait-for.test.ts delete mode 100644 tests/lib/rules/no-multiple-expect-wait-for.test.ts diff --git a/lib/index.ts b/lib/index.ts index 7a32dd86..cbedb09f 100644 --- a/lib/index.ts +++ b/lib/index.ts @@ -11,7 +11,7 @@ import preferExplicitAssert from './rules/prefer-explicit-assert'; import preferPresenceQueries from './rules/prefer-presence-queries'; import preferScreenQueries from './rules/prefer-screen-queries'; import preferWaitFor from './rules/prefer-wait-for'; -import noMultipleExpectWaitFor from './rules/no-multiple-expect-wait-for' +import noMultipleAssertionsWaitFor from './rules/no-multiple-assertions-wait-for' const rules = { 'await-async-query': awaitAsyncQuery, @@ -22,7 +22,7 @@ const rules = { 'no-debug': noDebug, 'no-dom-import': noDomImport, 'no-manual-cleanup': noManualCleanup, - 'no-multiple-expect-wait-for': noMultipleExpectWaitFor, + 'no-multiple-assertions-wait-for': noMultipleAssertionsWaitFor, 'no-wait-for-empty-callback': noWaitForEmptyCallback, 'prefer-explicit-assert': preferExplicitAssert, 'prefer-presence-queries': preferPresenceQueries, diff --git a/lib/rules/no-multiple-expect-wait-for.ts b/lib/rules/no-multiple-assertions-wait-for.ts similarity index 59% rename from lib/rules/no-multiple-expect-wait-for.ts rename to lib/rules/no-multiple-assertions-wait-for.ts index 5ddb91ae..9b0c46b1 100644 --- a/lib/rules/no-multiple-expect-wait-for.ts +++ b/lib/rules/no-multiple-assertions-wait-for.ts @@ -1,6 +1,6 @@ import { ESLintUtils, TSESTree } from '@typescript-eslint/experimental-utils' import { getDocsUrl } from '../utils' -import { isBlockStatement } from '../node-utils' +import { isBlockStatement, findClosestCalleName, isMemberExpression, isCallExpression, isIdentifier } from '../node-utils' export const RULE_NAME = 'no-multiple-expect-wait-for'; @@ -31,11 +31,23 @@ export default ESLintUtils.RuleCreator(getDocsUrl)({ function reporttMultipleAssertion( node: TSESTree.BlockStatement ) { - if (isBlockStatement(node) && node.body.length > 1) { - const waitForCall: TSESTree.CallExpression = node.parent.parent as TSESTree.CallExpression - const waitForIdentifier: TSESTree.Identifier = waitForCall.callee as TSESTree.Identifier - const methodName = waitForIdentifier.name + const hasMultipleExpects = (body: Array): boolean => + body.every((node: TSESTree.ExpressionStatement) => { + if ( + isCallExpression(node?.expression) && + isMemberExpression(node?.expression?.callee) && + isCallExpression(node?.expression?.callee?.object) + ) { + const object: TSESTree.CallExpression = node?.expression?.callee?.object + const expressionName: string = (object?.callee as TSESTree.Identifier)?.name + return expressionName === 'expect' + } else { + return false + } + }) + if (isBlockStatement(node) && node.body.length > 1 && hasMultipleExpects(node.body)) { + const methodName: string = findClosestCalleName(node) context.report({ node, loc: node.loc.start, diff --git a/tests/lib/rules/no-multiple-assertions-wait-for.test.ts b/tests/lib/rules/no-multiple-assertions-wait-for.test.ts new file mode 100644 index 00000000..e0e30ef8 --- /dev/null +++ b/tests/lib/rules/no-multiple-assertions-wait-for.test.ts @@ -0,0 +1,46 @@ +import { createRuleTester } from '../test-utils'; +import rule, { RULE_NAME } from '../../../lib/rules/no-multiple-assertions-wait-for'; + +const ruleTester = createRuleTester({ + ecmaFeatures: { + jsx: true, + }, +}); + +ruleTester.run(RULE_NAME, rule, { + valid: [ + { + code: ` + await waitFor(() => expect(a).toEqual('a')) + `, + }, + // this needs to be check by other rule + { + code: ` + await waitFor(() => { + fireEvent.keyDown(input, {key: 'ArrowDown'}) + expect(b).toEqual('b') + }) + `, + }, + { + code: ` + await waitFor(() => { + console.log('testing-library') + expect(b).toEqual('b') + }) + `, + } + ], + invalid: [ + { + code: ` + await waitFor(() => { + expect(a).toEqual('a') + expect(b).toEqual('b') + }) + `, + errors: [{ messageId: 'noMultipleAssertionWaitFor' }] + } + ] +}) diff --git a/tests/lib/rules/no-multiple-expect-wait-for.test.ts b/tests/lib/rules/no-multiple-expect-wait-for.test.ts deleted file mode 100644 index ed380f61..00000000 --- a/tests/lib/rules/no-multiple-expect-wait-for.test.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { createRuleTester } from '../test-utils'; -import rule, { RULE_NAME } from '../../../lib/rules/no-multiple-expect-wait-for'; - -const ruleTester = createRuleTester({ - ecmaFeatures: { - jsx: true, - }, -}); - -ruleTester.run(RULE_NAME, rule, { - valid: [], - invalid: [ - { - code: ` - await waitFor(() => { - expect(a).toEqual('a') - expect(b).toEqual('b') - }) - `, - errors: [] - } - ] -}) From aaab50544a9210ee2da211707a1c2d52059ffaf7 Mon Sep 17 00:00:00 2001 From: renatoagds Date: Wed, 24 Jun 2020 22:53:16 -0300 Subject: [PATCH 06/15] docs: add no-multiple-assertions-wait-for rule doc --- docs/rules/no-multiple-assertions-wait-for.md | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 docs/rules/no-multiple-assertions-wait-for.md diff --git a/docs/rules/no-multiple-assertions-wait-for.md b/docs/rules/no-multiple-assertions-wait-for.md new file mode 100644 index 00000000..6608ee33 --- /dev/null +++ b/docs/rules/no-multiple-assertions-wait-for.md @@ -0,0 +1,43 @@ +# Multiple assertions inside `waitFor` are not preferred (no-multiple-assertions-wait-for) + +## Rule Details + +This rule aims to ensure the correct usage of `expect` inside `waitFor`, in the way that they're intended to be used. +When using multiples assertions inside `waitFor`, if one fails, you have to wait for timeout before see it failing. +Putting one assertion, you can both wait for the UI to settle to the state you want to assert on, +and also fail faster if one of the assertions do end up failing + +Example of **incorrect** code for this rule: + +```js +const foo = async () => { + await waitFor(() => { + expect(a).toEqual('a'); + expect(b).toEqual('b'); + }); +}; +``` + +Examples of **correct** code for this rule: + +```js +const foo = async () => { + await waitFor(() => expect(a).toEqual('a')); + + // this rule only looks for expect + await waitFor(() => { + fireEvent.keyDown(input, { key: 'ArrowDown' }); + expect(b).toEqual('b'); + }); + + // or + await waitFor(() => { + console.log('testing-library'); + expect(b).toEqual('b'); + }); +}; +``` + +## Further Reading + +- [about `waitFor`](https://testing-library.com/docs/dom-testing-library/api-async#waitfor) From 8a016e29107c9425a78e4c974be62a341ca7fd03 Mon Sep 17 00:00:00 2001 From: renatoagds Date: Thu, 25 Jun 2020 21:06:49 -0300 Subject: [PATCH 07/15] docs: add link for no-multiple-assertions-wait-for doc --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 203d34ce..5ab81c5c 100644 --- a/README.md +++ b/README.md @@ -136,6 +136,7 @@ To enable this configuration use the `extends` property in your | [no-debug](docs/rules/no-debug.md) | Disallow the use of `debug` | ![angular-badge][] ![react-badge][] ![vue-badge][] | | | [no-dom-import](docs/rules/no-dom-import.md) | Disallow importing from DOM Testing Library | ![angular-badge][] ![react-badge][] ![vue-badge][] | ![fixable-badge][] | | [no-manual-cleanup](docs/rules/no-manual-cleanup.md) | Disallow the use of `cleanup` | | | +| [no-multiple-assertions-wait-for](docs/rules/no-multiple-assertions-wait-for.md) | Disallow the use of multiple expect inside `waitFor` | | | | [no-promise-in-fire-event](docs/rules/no-promise-in-fire-event.md) | Disallow the use of promises passed to a `fireEvent` method | | | | [no-wait-for-empty-callback](docs/rules/no-wait-for-empty-callback.md) | Disallow empty callbacks for `waitFor` and `waitForElementToBeRemoved` | ![dom-badge][] ![angular-badge][] ![react-badge][] ![vue-badge][] | | | [prefer-explicit-assert](docs/rules/prefer-explicit-assert.md) | Suggest using explicit assertions rather than just `getBy*` queries | | | From 2edcd969ae607a754da76a4ea93e5cd893f9d3d2 Mon Sep 17 00:00:00 2001 From: renatoagds Date: Thu, 25 Jun 2020 21:56:26 -0300 Subject: [PATCH 08/15] docs: insert function example in no-multiple-assertions-wait-for --- docs/rules/no-multiple-assertions-wait-for.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/docs/rules/no-multiple-assertions-wait-for.md b/docs/rules/no-multiple-assertions-wait-for.md index 6608ee33..a6d00b92 100644 --- a/docs/rules/no-multiple-assertions-wait-for.md +++ b/docs/rules/no-multiple-assertions-wait-for.md @@ -15,6 +15,12 @@ const foo = async () => { expect(a).toEqual('a'); expect(b).toEqual('b'); }); + + // or + await waitFor(function() { + expect(a).toEqual('a') + expect(b).toEqual('b'); + }) }; ``` @@ -35,6 +41,11 @@ const foo = async () => { console.log('testing-library'); expect(b).toEqual('b'); }); + + // or + await waitFor(function() { + expect(a).toEqual('a') + }) }; ``` From 303f2a959bb54b8f19488d9eafa835a590e28e72 Mon Sep 17 00:00:00 2001 From: renatoagds Date: Thu, 25 Jun 2020 22:04:39 -0300 Subject: [PATCH 09/15] refactor: remove find closest call node from node-utils --- lib/node-utils.ts | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/lib/node-utils.ts b/lib/node-utils.ts index f80e9ecc..60e88db3 100644 --- a/lib/node-utils.ts +++ b/lib/node-utils.ts @@ -101,23 +101,6 @@ export function findClosestCallNode( } } -export function findClosestCalleName( - node: TSESTree.Node -): string { - if (!node.parent) { - return ''; - } - - if ( - isCallExpression(node) && - isIdentifier(node.callee) - ) { - return node.callee.name; - } else { - return findClosestCalleName(node.parent); - } -} - export function hasThenProperty(node: TSESTree.Node) { return ( isMemberExpression(node) && From c4396edc206f22e55e9e09634afd7b4b7a748021 Mon Sep 17 00:00:00 2001 From: renatoagds Date: Thu, 25 Jun 2020 22:05:26 -0300 Subject: [PATCH 10/15] fix: check expect based in total --- lib/rules/no-multiple-assertions-wait-for.ts | 24 +++---- .../no-multiple-assertions-wait-for.test.ts | 71 ++++++++++++++++++- 2 files changed, 80 insertions(+), 15 deletions(-) diff --git a/lib/rules/no-multiple-assertions-wait-for.ts b/lib/rules/no-multiple-assertions-wait-for.ts index 9b0c46b1..0dc3ae42 100644 --- a/lib/rules/no-multiple-assertions-wait-for.ts +++ b/lib/rules/no-multiple-assertions-wait-for.ts @@ -1,6 +1,6 @@ import { ESLintUtils, TSESTree } from '@typescript-eslint/experimental-utils' import { getDocsUrl } from '../utils' -import { isBlockStatement, findClosestCalleName, isMemberExpression, isCallExpression, isIdentifier } from '../node-utils' +import { isBlockStatement, findClosestCallNode, isMemberExpression, isCallExpression, isIdentifier } from '../node-utils' export const RULE_NAME = 'no-multiple-expect-wait-for'; @@ -21,7 +21,7 @@ export default ESLintUtils.RuleCreator(getDocsUrl)({ recommended: false, }, messages: { - noMultipleAssertionWaitFor: 'Avoid use multiple assertions to `{{ methodName }}`', + noMultipleAssertionWaitFor: 'Avoid use multiple assertions to `waitFor`', }, fixable: null, schema: [], @@ -31,30 +31,26 @@ export default ESLintUtils.RuleCreator(getDocsUrl)({ function reporttMultipleAssertion( node: TSESTree.BlockStatement ) { - const hasMultipleExpects = (body: Array): boolean => - body.every((node: TSESTree.ExpressionStatement) => { + const totalExpect = (body: Array): Array => + body.filter((node: TSESTree.ExpressionStatement) => { if ( - isCallExpression(node?.expression) && - isMemberExpression(node?.expression?.callee) && - isCallExpression(node?.expression?.callee?.object) + isCallExpression(node.expression) && + isMemberExpression(node.expression.callee) && + isCallExpression(node.expression.callee.object) ) { - const object: TSESTree.CallExpression = node?.expression?.callee?.object - const expressionName: string = (object?.callee as TSESTree.Identifier)?.name + const object: TSESTree.CallExpression = node.expression.callee.object + const expressionName: string = isIdentifier(object.callee) && object.callee.name return expressionName === 'expect' } else { return false } }) - if (isBlockStatement(node) && node.body.length > 1 && hasMultipleExpects(node.body)) { - const methodName: string = findClosestCalleName(node) + if (isBlockStatement(node) && totalExpect(node.body).length > 1) { context.report({ node, loc: node.loc.start, messageId: 'noMultipleAssertionWaitFor', - data: { - methodName, - }, }); } } diff --git a/tests/lib/rules/no-multiple-assertions-wait-for.test.ts b/tests/lib/rules/no-multiple-assertions-wait-for.test.ts index e0e30ef8..18b061bf 100644 --- a/tests/lib/rules/no-multiple-assertions-wait-for.test.ts +++ b/tests/lib/rules/no-multiple-assertions-wait-for.test.ts @@ -14,6 +14,13 @@ ruleTester.run(RULE_NAME, rule, { await waitFor(() => expect(a).toEqual('a')) `, }, + { + code: ` + await waitFor(function() { + expect(a).toEqual('a') + }) + `, + }, // this needs to be check by other rule { code: ` @@ -23,6 +30,14 @@ ruleTester.run(RULE_NAME, rule, { }) `, }, + { + code: ` + await waitFor(function() { + fireEvent.keyDown(input, {key: 'ArrowDown'}) + expect(b).toEqual('b') + }) + `, + }, { code: ` await waitFor(() => { @@ -30,7 +45,32 @@ ruleTester.run(RULE_NAME, rule, { expect(b).toEqual('b') }) `, - } + }, + { + code: ` + await waitFor(function() { + console.log('testing-library') + expect(b).toEqual('b') + }) + `, + }, + { + code: ` + await waitFor(() => {}) + `, + }, + { + code: ` + await waitFor(function() {}) + `, + }, + { + code: ` + await waitFor(() => { + // testing + }) + `, + }, ], invalid: [ { @@ -41,6 +81,35 @@ ruleTester.run(RULE_NAME, rule, { }) `, errors: [{ messageId: 'noMultipleAssertionWaitFor' }] + }, + { + code: ` + await waitFor(() => { + expect(a).toEqual('a') + console.log('testing-library') + expect(b).toEqual('b') + }) + `, + errors: [{ messageId: 'noMultipleAssertionWaitFor' }] + }, + { + code: ` + await waitFor(function() { + expect(a).toEqual('a') + expect(b).toEqual('b') + }) + `, + errors: [{ messageId: 'noMultipleAssertionWaitFor' }] + }, + { + code: ` + await waitFor(function() { + expect(a).toEqual('a') + console.log('testing-library') + expect(b).toEqual('b') + }) + `, + errors: [{ messageId: 'noMultipleAssertionWaitFor' }] } ] }) From bea31aab1b4bba97a976e861d2a95b0f30b38d04 Mon Sep 17 00:00:00 2001 From: Renato Augusto Gama dos Santos Date: Fri, 26 Jun 2020 11:06:22 -0300 Subject: [PATCH 11/15] docs: better english in no-multiple-assertions-wait-for rule details Co-authored-by: Tim Deschryver <28659384+timdeschryver@users.noreply.github.com> --- docs/rules/no-multiple-assertions-wait-for.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/rules/no-multiple-assertions-wait-for.md b/docs/rules/no-multiple-assertions-wait-for.md index a6d00b92..09ab922e 100644 --- a/docs/rules/no-multiple-assertions-wait-for.md +++ b/docs/rules/no-multiple-assertions-wait-for.md @@ -3,7 +3,7 @@ ## Rule Details This rule aims to ensure the correct usage of `expect` inside `waitFor`, in the way that they're intended to be used. -When using multiples assertions inside `waitFor`, if one fails, you have to wait for timeout before see it failing. +When using multiples assertions inside `waitFor`, if one fails, you have to wait for a timeout before seeing it failing. Putting one assertion, you can both wait for the UI to settle to the state you want to assert on, and also fail faster if one of the assertions do end up failing From 15fd206e30afe11453cc7dde50396c09ac0c2618 Mon Sep 17 00:00:00 2001 From: Renato Augusto Gama dos Santos Date: Fri, 26 Jun 2020 11:06:48 -0300 Subject: [PATCH 12/15] fix: use correct rule name in no-multiple-assertions-wait-for Co-authored-by: Tim Deschryver <28659384+timdeschryver@users.noreply.github.com> --- lib/rules/no-multiple-assertions-wait-for.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/rules/no-multiple-assertions-wait-for.ts b/lib/rules/no-multiple-assertions-wait-for.ts index 0dc3ae42..f2088f1c 100644 --- a/lib/rules/no-multiple-assertions-wait-for.ts +++ b/lib/rules/no-multiple-assertions-wait-for.ts @@ -2,7 +2,7 @@ import { ESLintUtils, TSESTree } from '@typescript-eslint/experimental-utils' import { getDocsUrl } from '../utils' import { isBlockStatement, findClosestCallNode, isMemberExpression, isCallExpression, isIdentifier } from '../node-utils' -export const RULE_NAME = 'no-multiple-expect-wait-for'; +export const RULE_NAME = 'no-multiple-assertions-wait-for'; const WAIT_EXPRESSION_QUERY = 'CallExpression[callee.name=/^(waitFor)$/]'; From e693ae3ba4e71ee41f7efb312600ab65e37c9b6d Mon Sep 17 00:00:00 2001 From: renatoagds Date: Tue, 30 Jun 2020 00:07:04 -0300 Subject: [PATCH 13/15] docs: improve docs for no-multiple-assertions-wait-for --- docs/rules/no-multiple-assertions-wait-for.md | 22 +++++++++---------- 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/docs/rules/no-multiple-assertions-wait-for.md b/docs/rules/no-multiple-assertions-wait-for.md index 09ab922e..4259187f 100644 --- a/docs/rules/no-multiple-assertions-wait-for.md +++ b/docs/rules/no-multiple-assertions-wait-for.md @@ -29,26 +29,24 @@ Examples of **correct** code for this rule: ```js const foo = async () => { await waitFor(() => expect(a).toEqual('a')); + expect(b).toEqual('b'); + + // or + await waitFor(function() { + expect(a).toEqual('a') + }) + expect(b).toEqual('b'); - // this rule only looks for expect + // it only detects expect + // so this case doesn't generate warnings await waitFor(() => { fireEvent.keyDown(input, { key: 'ArrowDown' }); expect(b).toEqual('b'); }); - - // or - await waitFor(() => { - console.log('testing-library'); - expect(b).toEqual('b'); - }); - - // or - await waitFor(function() { - expect(a).toEqual('a') - }) }; ``` ## Further Reading - [about `waitFor`](https://testing-library.com/docs/dom-testing-library/api-async#waitfor) +- [inspiration for this rule](https://kentcdodds.com/blog/common-mistakes-with-react-testing-library#having-multiple-assertions-in-a-single-waitfor-callback) From 352d8a1073632b4987d33174a6a9f744903baf93 Mon Sep 17 00:00:00 2001 From: renatoagds Date: Tue, 30 Jun 2020 00:07:54 -0300 Subject: [PATCH 14/15] fix: typo in no-multiple-assertions-wait-for --- lib/rules/no-multiple-assertions-wait-for.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/rules/no-multiple-assertions-wait-for.ts b/lib/rules/no-multiple-assertions-wait-for.ts index f2088f1c..cb9ab920 100644 --- a/lib/rules/no-multiple-assertions-wait-for.ts +++ b/lib/rules/no-multiple-assertions-wait-for.ts @@ -28,7 +28,7 @@ export default ESLintUtils.RuleCreator(getDocsUrl)({ }, defaultOptions: [], create: function(context) { - function reporttMultipleAssertion( + function reportMultipleAssertion( node: TSESTree.BlockStatement ) { const totalExpect = (body: Array): Array => @@ -56,8 +56,8 @@ export default ESLintUtils.RuleCreator(getDocsUrl)({ } return { - [`${WAIT_EXPRESSION_QUERY} > ArrowFunctionExpression > BlockStatement`]: reporttMultipleAssertion, - [`${WAIT_EXPRESSION_QUERY} > FunctionExpression > BlockStatement`]: reporttMultipleAssertion, + [`${WAIT_EXPRESSION_QUERY} > ArrowFunctionExpression > BlockStatement`]: reportMultipleAssertion, + [`${WAIT_EXPRESSION_QUERY} > FunctionExpression > BlockStatement`]: reportMultipleAssertion, }; } }) From a7612dd9bd0e068d353f6bec813320af028543da Mon Sep 17 00:00:00 2001 From: renatoagds Date: Tue, 30 Jun 2020 00:09:33 -0300 Subject: [PATCH 15/15] fix: better english in no-multiple-assertions-wait-for --- lib/rules/no-multiple-assertions-wait-for.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/rules/no-multiple-assertions-wait-for.ts b/lib/rules/no-multiple-assertions-wait-for.ts index cb9ab920..0b05ade6 100644 --- a/lib/rules/no-multiple-assertions-wait-for.ts +++ b/lib/rules/no-multiple-assertions-wait-for.ts @@ -21,7 +21,7 @@ export default ESLintUtils.RuleCreator(getDocsUrl)({ recommended: false, }, messages: { - noMultipleAssertionWaitFor: 'Avoid use multiple assertions to `waitFor`', + noMultipleAssertionWaitFor: 'Avoid using multiple assertions within `waitFor` callback', }, fixable: null, schema: [],