From ec38b92193204ef0bde785d3e141d87230d189ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kuba=20Jastrz=C4=99bski?= Date: Fri, 31 Jan 2020 21:13:19 +0100 Subject: [PATCH 1/5] feat(no-debug): scan for `screen.debug()` --- lib/rules/no-debug.js | 60 +++++++++++++++++++++++++++++++++++++ tests/lib/rules/no-debug.js | 50 +++++++++++++++++++++++++++++++ 2 files changed, 110 insertions(+) diff --git a/lib/rules/no-debug.js b/lib/rules/no-debug.js index 16662a63..83086af2 100644 --- a/lib/rules/no-debug.js +++ b/lib/rules/no-debug.js @@ -2,6 +2,14 @@ const { getDocsUrl } = require('../utils'); +const LIBRARY_MODULES_WITH_SCREEN = [ + '@testing-library/dom', + '@testing-library/react', + '@testing-library/preact', + '@testing-library/vue', + '@testing-library/svelte', +]; + module.exports = { meta: { type: 'problem', @@ -36,6 +44,8 @@ module.exports = { [{ renderFunctions }] = context.options; } + let hasImportedScreen = false; + return { VariableDeclarator(node) { if ( @@ -57,6 +67,44 @@ module.exports = { } } }, + [`VariableDeclarator > CallExpression > Identifier[name="require"]`]( + node + ) { + const { arguments: args } = node.parent; + + const literalNodeScreenModuleName = args.find(args => + LIBRARY_MODULES_WITH_SCREEN.includes(args.value) + ); + + if (!literalNodeScreenModuleName) { + return; + } + + const declaratorNode = node.parent.parent; + + if ( + declaratorNode.id.type === 'ObjectPattern' && + declaratorNode.id.properties.some( + property => property.key.name === 'screen' + ) + ) { + hasImportedScreen = true; + } + }, + ImportDeclaration(node) { + const screenModuleName = LIBRARY_MODULES_WITH_SCREEN.find( + module => module === node.source.value + ); + + if ( + screenModuleName && + node.specifiers.some( + specifier => specifier.imported.name === 'screen' + ) + ) { + hasImportedScreen = true; + } + }, [`CallExpression > Identifier[name="debug"]`](node) { if (hasDestructuredDebugStatement) { context.report({ @@ -65,6 +113,18 @@ module.exports = { }); } }, + [`CallExpression > MemberExpression > Identifier[name="debug"]`](node) { + if ( + hasImportedScreen && + node.parent && + node.parent.object.name === 'screen' + ) { + context.report({ + node, + messageId: 'noDebug', + }); + } + }, 'Program:exit'() { renderVariableDeclarators.forEach(renderVar => { const renderVarReferences = context diff --git a/tests/lib/rules/no-debug.js b/tests/lib/rules/no-debug.js index 16b87a93..6d2e7357 100644 --- a/tests/lib/rules/no-debug.js +++ b/tests/lib/rules/no-debug.js @@ -17,6 +17,7 @@ const ruleTester = new RuleTester({ ecmaFeatures: { jsx: true, }, + sourceType: 'module', }, }); ruleTester.run('no-debug', rule, { @@ -56,6 +57,33 @@ ruleTester.run('no-debug', rule, { utils.foo() `, }, + { + code: `screen.debug()`, + }, + { + code: ` + const { screen } = require('@testing-library/dom') + screen.debug + `, + }, + { + code: ` + import { screen } from '@testing-library/dom' + screen.debug + `, + }, + { + code: ` + const { screen } = require('something-else') + screen.debug() + `, + }, + { + code: ` + import { screen } from 'something-else' + screen.debug() + `, + }, ], invalid: [ @@ -113,5 +141,27 @@ ruleTester.run('no-debug', rule, { }, ], }, + { + code: ` + const { screen } = require('@testing-library/dom') + screen.debug() + `, + errors: [ + { + messageId: 'noDebug', + }, + ], + }, + { + code: ` + import { screen } from '@testing-library/dom' + screen.debug() + `, + errors: [ + { + messageId: 'noDebug', + }, + ], + }, ], }); From 9707c06ad633bec9a41af7fee24a7dcf938de42c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kuba=20Jastrz=C4=99bski?= Date: Fri, 31 Jan 2020 21:23:12 +0100 Subject: [PATCH 2/5] test(no-debug): improve coverage after ec38b92 --- tests/lib/rules/no-debug.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/lib/rules/no-debug.js b/tests/lib/rules/no-debug.js index 6d2e7357..5b9cca2b 100644 --- a/tests/lib/rules/no-debug.js +++ b/tests/lib/rules/no-debug.js @@ -72,6 +72,12 @@ ruleTester.run('no-debug', rule, { screen.debug `, }, + { + code: `const { queries } = require('@testing-library/dom')`, + }, + { + code: `import { queries } from '@testing-library/dom'`, + }, { code: ` const { screen } = require('something-else') From 762f8a0ff884ff9d36bdd293cdec111317cf3f3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kuba=20Jastrz=C4=99bski?= Date: Fri, 31 Jan 2020 21:37:34 +0100 Subject: [PATCH 3/5] docs(no-debug): add `screen.debug` example --- docs/rules/no-debug.md | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/docs/rules/no-debug.md b/docs/rules/no-debug.md index ae51cfc2..92e2a637 100644 --- a/docs/rules/no-debug.md +++ b/docs/rules/no-debug.md @@ -2,20 +2,35 @@ Just like `console.log` statements pollutes the browser's output, debug statements also pollutes the tests if one of your team mates forgot to remove it. `debug` statements should be used when you actually want to debug your tests but should not be pushed to the codebase. +In addition, it also checks for `debug` on [`screen` object](https://testing-library.com/docs/dom-testing-library/api-queries#screen) from `@testing-library/dom` +and libraries that re-export it, such as `@testing-library/react`. + ## Rule Details -This rule aims to disallow the use of `debug` in your tests. +This rule aims to disallow the use of `debug` and `screen.debug` in your tests. Examples of **incorrect** code for this rule: ```js const { debug } = render(); debug(); -// OR +``` + +```js const utils = render(); utils.debug(); ``` +```js +import { screen } from '@testing-library/dom'; +screen.debug(); +``` + +```js +const { screen } = require('@testing-library/react'); +screen.debug(); +``` + If you use [custom render functions](https://testing-library.com/docs/example-react-redux) then you can set a config option in your `.eslintrc` to look for these. ``` From 901cefb66e5e5e963a07b2adabfea8f94f5bc11d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kuba=20Jastrz=C4=99bski?= Date: Fri, 31 Jan 2020 21:41:29 +0100 Subject: [PATCH 4/5] docs(no-debug): add link to `screen.debug` docs --- docs/rules/no-debug.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/rules/no-debug.md b/docs/rules/no-debug.md index 92e2a637..ad20aab7 100644 --- a/docs/rules/no-debug.md +++ b/docs/rules/no-debug.md @@ -40,3 +40,4 @@ If you use [custom render functions](https://testing-library.com/docs/example-re ## Further Reading - [debug API in React Testing Library](https://testing-library.com/docs/react-testing-library/api#debug) +- [`screen.debug` in Dom Testing Library](https://testing-library.com/docs/dom-testing-library/api-queries#screendebug) From d764bc9f4ebd6d91e3e3628bbe22bae376544711 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kuba=20Jastrz=C4=99bski?= Date: Fri, 31 Jan 2020 21:45:20 +0100 Subject: [PATCH 5/5] docs(no-debug): remove unnecessary note --- docs/rules/no-debug.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/docs/rules/no-debug.md b/docs/rules/no-debug.md index ad20aab7..ef848d85 100644 --- a/docs/rules/no-debug.md +++ b/docs/rules/no-debug.md @@ -2,12 +2,9 @@ Just like `console.log` statements pollutes the browser's output, debug statements also pollutes the tests if one of your team mates forgot to remove it. `debug` statements should be used when you actually want to debug your tests but should not be pushed to the codebase. -In addition, it also checks for `debug` on [`screen` object](https://testing-library.com/docs/dom-testing-library/api-queries#screen) from `@testing-library/dom` -and libraries that re-export it, such as `@testing-library/react`. - ## Rule Details -This rule aims to disallow the use of `debug` and `screen.debug` in your tests. +This rule aims to disallow the use of `debug` in your tests. Examples of **incorrect** code for this rule: