From a86ddf08d3c6a70fed5518aa6ffdb72556fc9596 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20Beltr=C3=A1n=20Alarc=C3=B3n?= Date: Tue, 16 Mar 2021 20:40:51 +0100 Subject: [PATCH 1/6] refactor(no-debug): use new rule creator --- lib/rules/no-debug.ts | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/lib/rules/no-debug.ts b/lib/rules/no-debug.ts index e2023e91..d39233f1 100644 --- a/lib/rules/no-debug.ts +++ b/lib/rules/no-debug.ts @@ -1,28 +1,21 @@ +import { ASTUtils, TSESTree } from '@typescript-eslint/experimental-utils'; +import { hasTestingLibraryImportModule, LIBRARY_MODULES } from '../utils'; import { - ESLintUtils, - TSESTree, - ASTUtils, -} from '@typescript-eslint/experimental-utils'; -import { - getDocsUrl, - LIBRARY_MODULES, - hasTestingLibraryImportModule, -} from '../utils'; -import { - isObjectPattern, - isProperty, isCallExpression, + isImportSpecifier, isLiteral, isMemberExpression, - isImportSpecifier, + isObjectPattern, + isProperty, isRenderVariableDeclarator, } from '../node-utils'; +import { createTestingLibraryRule } from '../create-testing-library-rule'; export const RULE_NAME = 'no-debug'; export type MessageIds = 'noDebug'; type Options = [{ renderFunctions?: string[] }]; -export default ESLintUtils.RuleCreator(getDocsUrl)({ +export default createTestingLibraryRule({ name: RULE_NAME, meta: { type: 'problem', From bf84c07f92eaa38d9c5b68280f16e68b22ac1bed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20Beltr=C3=A1n=20Alarc=C3=B3n?= Date: Tue, 16 Mar 2021 20:46:34 +0100 Subject: [PATCH 2/6] test(no-debug): improve current invalid error assertions --- tests/lib/rules/no-debug.test.ts | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/tests/lib/rules/no-debug.test.ts b/tests/lib/rules/no-debug.test.ts index 3e26b414..962bc82f 100644 --- a/tests/lib/rules/no-debug.test.ts +++ b/tests/lib/rules/no-debug.test.ts @@ -101,6 +101,8 @@ ruleTester.run(RULE_NAME, rule, { `, errors: [ { + line: 3, + column: 9, messageId: 'noDebug', }, ], @@ -117,6 +119,8 @@ ruleTester.run(RULE_NAME, rule, { ], errors: [ { + line: 3, + column: 9, messageId: 'noDebug', }, ], @@ -128,6 +132,8 @@ ruleTester.run(RULE_NAME, rule, { `, errors: [ { + line: 3, + column: 15, messageId: 'noDebug', }, ], @@ -141,9 +147,13 @@ ruleTester.run(RULE_NAME, rule, { `, errors: [ { + line: 3, + column: 15, messageId: 'noDebug', }, { + line: 5, + column: 15, messageId: 'noDebug', }, ], @@ -158,6 +168,8 @@ ruleTester.run(RULE_NAME, rule, { })`, errors: [ { + line: 5, + column: 11, messageId: 'noDebug', }, ], @@ -172,6 +184,8 @@ ruleTester.run(RULE_NAME, rule, { })`, errors: [ { + line: 5, + column: 17, messageId: 'noDebug', }, ], @@ -183,6 +197,8 @@ ruleTester.run(RULE_NAME, rule, { `, errors: [ { + line: 3, + column: 16, messageId: 'noDebug', }, ], @@ -194,6 +210,8 @@ ruleTester.run(RULE_NAME, rule, { `, errors: [ { + line: 3, + column: 16, messageId: 'noDebug', }, ], @@ -206,6 +224,8 @@ ruleTester.run(RULE_NAME, rule, { `, errors: [ { + line: 3, + column: 16, messageId: 'noDebug', }, ], From 02a8a7ba116e5a04ac60ec6d2a7d55a800ae1dff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20Beltr=C3=A1n=20Alarc=C3=B3n?= Date: Sat, 20 Mar 2021 12:09:12 +0100 Subject: [PATCH 3/6] docs(no-debug): fix typo --- docs/rules/no-debug.md | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/docs/rules/no-debug.md b/docs/rules/no-debug.md index ef848d85..e3278738 100644 --- a/docs/rules/no-debug.md +++ b/docs/rules/no-debug.md @@ -1,6 +1,6 @@ # Disallow the use of `debug` (no-debug) -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. +Just like `console.log` statements pollutes the browser's output, debug statements also pollutes the tests if one of your teammates 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. ## Rule Details @@ -28,12 +28,6 @@ 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. - -``` - "testing-library/no-debug": ["error", {"renderFunctions":["renderWithRedux", "renderWithRouter"]}], -``` - ## Further Reading - [debug API in React Testing Library](https://testing-library.com/docs/react-testing-library/api#debug) From 1593c38eb4c947f483b59e42a66ad9a805fba72b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20Beltr=C3=A1n=20Alarc=C3=B3n?= Date: Sat, 20 Mar 2021 12:43:22 +0100 Subject: [PATCH 4/6] refactor(no-debug): report debug call expressions with detection helpers --- lib/detect-testing-library-utils.ts | 14 +++ lib/rules/no-debug.ts | 160 +++------------------------- tests/lib/rules/no-debug.test.ts | 41 ++++++- 3 files changed, 64 insertions(+), 151 deletions(-) diff --git a/lib/detect-testing-library-utils.ts b/lib/detect-testing-library-utils.ts index 7559ae8f..316accf7 100644 --- a/lib/detect-testing-library-utils.ts +++ b/lib/detect-testing-library-utils.ts @@ -69,6 +69,7 @@ type IsAsyncUtilFn = ( ) => boolean; type IsFireEventMethodFn = (node: TSESTree.Identifier) => boolean; type IsRenderUtilFn = (node: TSESTree.Identifier) => boolean; +type IsDebugUtilFn = (node: TSESTree.Identifier) => boolean; type IsPresenceAssertFn = (node: TSESTree.MemberExpression) => boolean; type IsAbsenceAssertFn = (node: TSESTree.MemberExpression) => boolean; type CanReportErrorsFn = () => boolean; @@ -96,6 +97,7 @@ export interface DetectionHelpers { isAsyncUtil: IsAsyncUtilFn; isFireEventMethod: IsFireEventMethodFn; isRenderUtil: IsRenderUtilFn; + isDebugUtil: IsDebugUtilFn; isPresenceAssert: IsPresenceAssertFn; isAbsenceAssert: IsAbsenceAssertFn; canReportErrors: CanReportErrorsFn; @@ -406,6 +408,17 @@ export function detectTestingLibraryUtils< ); }; + const isDebugUtil: IsDebugUtilFn = (node) => { + return isTestingLibraryUtil( + node, + (identifierNodeName, originalNodeName) => { + return [identifierNodeName, originalNodeName] + .filter(Boolean) + .includes('debug'); + } + ); + }; + /** * Determines whether a given MemberExpression node is a presence assert * @@ -549,6 +562,7 @@ export function detectTestingLibraryUtils< isAsyncUtil, isFireEventMethod, isRenderUtil, + isDebugUtil, isPresenceAssert, isAbsenceAssert, canReportErrors, diff --git a/lib/rules/no-debug.ts b/lib/rules/no-debug.ts index d39233f1..a5cc6665 100644 --- a/lib/rules/no-debug.ts +++ b/lib/rules/no-debug.ts @@ -1,19 +1,9 @@ -import { ASTUtils, TSESTree } from '@typescript-eslint/experimental-utils'; -import { hasTestingLibraryImportModule, LIBRARY_MODULES } from '../utils'; -import { - isCallExpression, - isImportSpecifier, - isLiteral, - isMemberExpression, - isObjectPattern, - isProperty, - isRenderVariableDeclarator, -} from '../node-utils'; +import { getDeepestIdentifierNode } from '../node-utils'; import { createTestingLibraryRule } from '../create-testing-library-rule'; export const RULE_NAME = 'no-debug'; export type MessageIds = 'noDebug'; -type Options = [{ renderFunctions?: string[] }]; +type Options = []; export default createTestingLibraryRule({ name: RULE_NAME, @@ -39,152 +29,30 @@ export default createTestingLibraryRule({ }, ], }, - defaultOptions: [ - { - renderFunctions: [], - }, - ], - - create(context, [options]) { - let hasDestructuredDebugStatement = false; - const renderVariableDeclarators: TSESTree.VariableDeclarator[] = []; - - const { renderFunctions } = options; - - let hasImportedScreen = false; - let wildcardImportName: string = null; + defaultOptions: [], + create(context, [], helpers) { return { VariableDeclarator(node) { - if (isRenderVariableDeclarator(node, ['render', ...renderFunctions])) { - if ( - isObjectPattern(node.id) && - node.id.properties.some( - (property) => - isProperty(property) && - ASTUtils.isIdentifier(property.key) && - property.key.name === 'debug' - ) - ) { - hasDestructuredDebugStatement = true; - } + const initIdentifierNode = getDeepestIdentifierNode(node.init); - if (node.id.type === 'Identifier') { - renderVariableDeclarators.push(node); - } - } - }, - [`VariableDeclarator > CallExpression > Identifier[name="require"]`]( - node: TSESTree.Identifier - ) { - const { arguments: args } = node.parent as TSESTree.CallExpression; - - const literalNodeScreenModuleName = args.find( - (args) => - isLiteral(args) && - typeof args.value === 'string' && - LIBRARY_MODULES.includes(args.value) - ); - - if (!literalNodeScreenModuleName) { + if (!initIdentifierNode) { return; } - const declaratorNode = node.parent - .parent as TSESTree.VariableDeclarator; - - hasImportedScreen = - isObjectPattern(declaratorNode.id) && - declaratorNode.id.properties.some( - (property) => - isProperty(property) && - ASTUtils.isIdentifier(property.key) && - property.key.name === 'screen' - ); + // TODO: check if named 'debug' and coming from render, + // and add it to suspicious list if so. }, - // checks if import has shape: - // import { screen } from '@testing-library/dom'; - ImportDeclaration(node: TSESTree.ImportDeclaration) { - if (!hasTestingLibraryImportModule(node)) { - return; - } + CallExpression(node) { + const callExpressionIdentifier = getDeepestIdentifierNode(node); - hasImportedScreen = node.specifiers.some( - (s) => isImportSpecifier(s) && s.imported.name === 'screen' - ); - }, - // checks if import has shape: - // import * as dtl from '@testing-library/dom'; - 'ImportDeclaration ImportNamespaceSpecifier'( - node: TSESTree.ImportNamespaceSpecifier - ) { - const importDeclarationNode = node.parent as TSESTree.ImportDeclaration; - if (!hasTestingLibraryImportModule(importDeclarationNode)) { + if (!helpers.isDebugUtil(callExpressionIdentifier)) { return; } - wildcardImportName = node.local && node.local.name; - }, - [`CallExpression > Identifier[name="debug"]`](node: TSESTree.Identifier) { - if (hasDestructuredDebugStatement) { - context.report({ - node, - messageId: 'noDebug', - }); - } - }, - [`CallExpression > MemberExpression > Identifier[name="debug"]`]( - node: TSESTree.Identifier - ) { - const memberExpression = node.parent as TSESTree.MemberExpression; - const identifier = memberExpression.object as TSESTree.Identifier; - const memberExpressionName = identifier.name; - /* - check if `debug` used following the pattern: - - import { screen } from '@testing-library/dom'; - ... - screen.debug(); - */ - const isScreenDebugUsed = - hasImportedScreen && memberExpressionName === 'screen'; - - /* - check if `debug` used following the pattern: - - import * as dtl from '@testing-library/dom'; - ... - dtl.debug(); - */ - const isNamespaceDebugUsed = - wildcardImportName && memberExpressionName === wildcardImportName; - - if (isScreenDebugUsed || isNamespaceDebugUsed) { - context.report({ - node, - messageId: 'noDebug', - }); - } - }, - 'Program:exit'() { - renderVariableDeclarators.forEach((renderVar) => { - const renderVarReferences = context - .getDeclaredVariables(renderVar)[0] - .references.slice(1); - renderVarReferences.forEach((ref) => { - const parent = ref.identifier.parent; - if ( - isMemberExpression(parent) && - ASTUtils.isIdentifier(parent.property) && - parent.property.name === 'debug' && - isCallExpression(parent.parent) - ) { - context.report({ - node: parent.property, - messageId: 'noDebug', - }); - } - }); + context.report({ + node: callExpressionIdentifier, + messageId: 'noDebug', }); }, }; diff --git a/tests/lib/rules/no-debug.test.ts b/tests/lib/rules/no-debug.test.ts index 962bc82f..f4c51859 100644 --- a/tests/lib/rules/no-debug.test.ts +++ b/tests/lib/rules/no-debug.test.ts @@ -6,9 +6,18 @@ const ruleTester = createRuleTester(); ruleTester.run(RULE_NAME, rule, { valid: [ { + settings: { 'testing-library/utils-module': 'test-utils' }, code: `debug()`, }, { + settings: { 'testing-library/utils-module': 'test-utils' }, + code: ` + import { screen } from 'somewhere-else' + screen.debug() + `, + }, + { + settings: { 'testing-library/utils-module': 'test-utils' }, code: `() => { const somethingElse = {} const { debug } = foo() @@ -16,6 +25,7 @@ ruleTester.run(RULE_NAME, rule, { }`, }, { + settings: { 'testing-library/utils-module': 'test-utils' }, code: ` let foo const debug = require('debug') @@ -41,6 +51,7 @@ ruleTester.run(RULE_NAME, rule, { `, }, { + settings: { 'testing-library/utils-module': 'test-utils' }, code: `screen.debug()`, }, { @@ -64,6 +75,7 @@ ruleTester.run(RULE_NAME, rule, { `, }, { + settings: { 'testing-library/utils-module': 'test-utils' }, code: ` import * as foo from '@somewhere/else'; foo.debug(); @@ -73,12 +85,14 @@ ruleTester.run(RULE_NAME, rule, { code: `import { queries } from '@testing-library/dom'`, }, { + settings: { 'testing-library/utils-module': 'test-utils' }, code: ` const { screen } = require('something-else') screen.debug() `, }, { + settings: { 'testing-library/utils-module': 'test-utils' }, code: ` import { screen } from 'something-else' screen.debug() @@ -94,6 +108,25 @@ ruleTester.run(RULE_NAME, rule, { ], invalid: [ + { + code: `debug()`, + errors: [{ line: 1, column: 1, messageId: 'noDebug' }], + }, + { + code: ` + import { screen } from 'aggressive-reporting' + screen.debug() + `, + errors: [{ line: 3, column: 14, messageId: 'noDebug' }], + }, + { + settings: { 'testing-library/utils-module': 'test-utils' }, + code: ` + import { screen } from 'test-utils' + screen.debug() + `, + errors: [{ line: 3, column: 14, messageId: 'noDebug' }], + }, { code: ` const { debug } = render() @@ -108,15 +141,13 @@ ruleTester.run(RULE_NAME, rule, { ], }, { + settings: { + 'testing-library/custom-renders': ['customRender', 'renderWithRedux'], + }, code: ` const { debug } = renderWithRedux() debug() `, - options: [ - { - renderFunctions: ['renderWithRedux'], - }, - ], errors: [ { line: 3, From 9861eb49234d4c20f8d3bda72fbcf087ed79372d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20Beltr=C3=A1n=20Alarc=C3=B3n?= Date: Sat, 20 Mar 2021 14:47:07 +0100 Subject: [PATCH 5/6] refactor(no-debug): report debug from renders with detection helpers --- lib/node-utils.ts | 8 +- lib/rules/no-debug.ts | 66 ++++++++-- tests/lib/rules/no-debug.test.ts | 220 +++++++++++++++++++++++++++++++ 3 files changed, 282 insertions(+), 12 deletions(-) diff --git a/lib/node-utils.ts b/lib/node-utils.ts index 4aba63cd..c6a76253 100644 --- a/lib/node-utils.ts +++ b/lib/node-utils.ts @@ -392,7 +392,7 @@ export function getPropertyIdentifierNode( } /** - * Gets the deepest identifier node from a given node. + * Gets the deepest identifier node in the expression from a given node. * * Opposite of {@link getReferenceNode} * @@ -416,11 +416,15 @@ export function getDeepestIdentifierNode( return getDeepestIdentifierNode(node.callee); } + if (ASTUtils.isAwaitExpression(node)) { + return getDeepestIdentifierNode(node.argument); + } + return null; } /** - * Gets the farthest node from a given node. + * Gets the farthest node in the expression from a given node. * * Opposite of {@link getDeepestIdentifierNode} diff --git a/lib/rules/no-debug.ts b/lib/rules/no-debug.ts index a5cc6665..98a506ba 100644 --- a/lib/rules/no-debug.ts +++ b/lib/rules/no-debug.ts @@ -1,5 +1,12 @@ -import { getDeepestIdentifierNode } from '../node-utils'; +import { + getDeepestIdentifierNode, + getPropertyIdentifierNode, + getReferenceNode, + isObjectPattern, + isProperty, +} from '../node-utils'; import { createTestingLibraryRule } from '../create-testing-library-rule'; +import { ASTUtils, TSESTree } from '@typescript-eslint/experimental-utils'; export const RULE_NAME = 'no-debug'; export type MessageIds = 'noDebug'; @@ -32,6 +39,9 @@ export default createTestingLibraryRule({ defaultOptions: [], create(context, [], helpers) { + const suspiciousDebugVariableNames: string[] = []; + const suspiciousReferenceNodes: TSESTree.Identifier[] = []; + return { VariableDeclarator(node) { const initIdentifierNode = getDeepestIdentifierNode(node.init); @@ -40,20 +50,56 @@ export default createTestingLibraryRule({ return; } - // TODO: check if named 'debug' and coming from render, - // and add it to suspicious list if so. + if (!helpers.isRenderUtil(initIdentifierNode)) { + return; + } + + // find debug obtained from render and save their name, like: + // const { debug } = render(); + if (isObjectPattern(node.id)) { + for (const property of node.id.properties) { + if ( + isProperty(property) && + ASTUtils.isIdentifier(property.key) && + property.key.name === 'debug' + ) { + suspiciousDebugVariableNames.push( + getDeepestIdentifierNode(property.value).name + ); + } + } + } else { + // find utils kept from render and save their node, like: + // const utils = render(); + if (ASTUtils.isIdentifier(node.id)) { + suspiciousReferenceNodes.push(node.id); + } + } }, CallExpression(node) { const callExpressionIdentifier = getDeepestIdentifierNode(node); + const referenceNode = getReferenceNode(node); + const referenceIdentifier = getPropertyIdentifierNode(referenceNode); - if (!helpers.isDebugUtil(callExpressionIdentifier)) { - return; - } + const isDebugUtil = helpers.isDebugUtil(callExpressionIdentifier); + const isDeclaredDebugVariable = suspiciousDebugVariableNames.includes( + callExpressionIdentifier.name + ); + const isChainedReferenceDebug = suspiciousReferenceNodes.some( + (suspiciousReferenceIdentifier) => { + return ( + callExpressionIdentifier.name === 'debug' && + suspiciousReferenceIdentifier.name === referenceIdentifier.name + ); + } + ); - context.report({ - node: callExpressionIdentifier, - messageId: 'noDebug', - }); + if (isDebugUtil || isDeclaredDebugVariable || isChainedReferenceDebug) { + context.report({ + node: callExpressionIdentifier, + messageId: 'noDebug', + }); + } }, }; }, diff --git a/tests/lib/rules/no-debug.test.ts b/tests/lib/rules/no-debug.test.ts index f4c51859..2de323df 100644 --- a/tests/lib/rules/no-debug.test.ts +++ b/tests/lib/rules/no-debug.test.ts @@ -105,6 +105,40 @@ ruleTester.run(RULE_NAME, rule, { } `, }, + { + settings: { 'testing-library/utils-module': 'test-utils' }, + code: ` + import { debug as testingDebug } from 'test-utils' + import { debug } from 'somewhere-else' + + debug() + `, + }, + { + settings: { 'testing-library/utils-module': 'test-utils' }, + code: ` + import { render as testingRender } from '@testing-library/react' + import { render } from 'somewhere-else' + + const { debug } = render(element) + + somethingElse() + debug() + `, + }, + { + settings: { 'testing-library/utils-module': 'test-utils' }, + code: ` + import { render as testingRender } from '@testing-library/react' + import { render } from 'somewhere-else' + + const { debug } = render(element) + const { debug: testingDebug } = testingRender(element) + + somethingElse() + debug() + `, + }, ], invalid: [ @@ -127,6 +161,14 @@ ruleTester.run(RULE_NAME, rule, { `, errors: [{ line: 3, column: 14, messageId: 'noDebug' }], }, + { + settings: { 'testing-library/utils-module': 'test-utils' }, + code: ` + import { debug as testingDebug } from 'test-utils' + testingDebug() + `, + errors: [{ line: 3, column: 7, messageId: 'noDebug' }], + }, { code: ` const { debug } = render() @@ -169,6 +211,21 @@ ruleTester.run(RULE_NAME, rule, { }, ], }, + { + settings: { 'testing-library/utils-module': 'test-utils' }, + code: `// aggressive reporting disabled + import { render } from 'test-utils' + const utils = render() + utils.debug() + `, + errors: [ + { + line: 4, + column: 15, + messageId: 'noDebug', + }, + ], + }, { code: ` const utils = render() @@ -189,6 +246,28 @@ ruleTester.run(RULE_NAME, rule, { }, ], }, + { + settings: { 'testing-library/utils-module': 'test-utils' }, + code: `// aggressive reporting disabled + import { render } from 'test-utils' + const utils = render() + utils.debug() + utils.foo() + utils.debug() + `, + errors: [ + { + line: 4, + column: 15, + messageId: 'noDebug', + }, + { + line: 6, + column: 15, + messageId: 'noDebug', + }, + ], + }, { code: ` describe(() => { @@ -205,6 +284,24 @@ ruleTester.run(RULE_NAME, rule, { }, ], }, + { + settings: { 'testing-library/utils-module': 'test-utils' }, + code: `// aggressive reporting disabled + import { render } from 'test-utils' + describe(() => { + test(async () => { + const { debug } = await render("foo") + debug() + }) + })`, + errors: [ + { + line: 6, + column: 11, + messageId: 'noDebug', + }, + ], + }, { code: ` describe(() => { @@ -221,6 +318,24 @@ ruleTester.run(RULE_NAME, rule, { }, ], }, + { + settings: { 'testing-library/utils-module': 'test-utils' }, + code: `// aggressive reporting disabled + import { render } from 'test-utils' + describe(() => { + test(async () => { + const utils = await render("foo") + utils.debug() + }) + })`, + errors: [ + { + line: 6, + column: 17, + messageId: 'noDebug', + }, + ], + }, { code: ` const { screen } = require('@testing-library/dom') @@ -234,6 +349,20 @@ ruleTester.run(RULE_NAME, rule, { }, ], }, + { + settings: { 'testing-library/utils-module': 'test-utils' }, + code: `// aggressive reporting disabled + const { screen } = require('@testing-library/dom') + screen.debug() + `, + errors: [ + { + line: 3, + column: 16, + messageId: 'noDebug', + }, + ], + }, { code: ` import { screen } from '@testing-library/dom' @@ -247,6 +376,20 @@ ruleTester.run(RULE_NAME, rule, { }, ], }, + { + settings: { 'testing-library/utils-module': 'test-utils' }, + code: `// aggressive reporting disabled + import { screen } from '@testing-library/dom' + screen.debug() + `, + errors: [ + { + line: 3, + column: 16, + messageId: 'noDebug', + }, + ], + }, { // https://github.com/testing-library/eslint-plugin-testing-library/issues/174 code: ` @@ -262,6 +405,21 @@ ruleTester.run(RULE_NAME, rule, { ], }, { + settings: { 'testing-library/utils-module': 'test-utils' }, + code: `// aggressive reporting disabled + import { screen, render } from '@testing-library/dom' + screen.debug() + `, + errors: [ + { + line: 3, + column: 16, + messageId: 'noDebug', + }, + ], + }, + { + settings: { 'testing-library/utils-module': 'test-utils' }, code: ` import * as dtl from '@testing-library/dom'; dtl.debug(); @@ -274,5 +432,67 @@ ruleTester.run(RULE_NAME, rule, { }, ], }, + { + code: ` + import { render } from 'aggressive-reporting' + + const { debug } = render(element) + + somethingElse() + debug() + `, + errors: [{ line: 7, column: 7, messageId: 'noDebug' }], + }, + { + settings: { 'testing-library/utils-module': 'test-utils' }, + code: ` + import { render } from '@testing-library/react' + + const { debug } = render(element) + + somethingElse() + debug() + `, + errors: [{ line: 7, column: 7, messageId: 'noDebug' }], + }, + { + settings: { 'testing-library/utils-module': 'test-utils' }, + code: ` + import { render } from 'test-utils' + + const { debug: renamed } = render(element) + + somethingElse() + renamed() + `, + errors: [{ line: 7, column: 7, messageId: 'noDebug' }], + }, + { + settings: { 'testing-library/utils-module': 'test-utils' }, + code: ` + import { render } from '@testing-library/react' + + const utils = render(element) + + somethingElse() + utils.debug() + `, + errors: [{ line: 7, column: 13, messageId: 'noDebug' }], + }, + { + settings: { + 'testing-library/utils-module': 'test-utils', + 'testing-library/custom-renders': ['testingRender'], + }, + code: `// aggressive reporting disabled, custom render set + import { testingRender } from 'test-utils' + + const { debug: renamedDebug } = testingRender(element) + + somethingElse() + renamedDebug() + `, + errors: [{ line: 7, column: 7, messageId: 'noDebug' }], + }, ], }); From 06e5986c913a8929affd032ae75d00344683ecf8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20Beltr=C3=A1n=20Alarc=C3=B3n?= Date: Sat, 20 Mar 2021 14:51:51 +0100 Subject: [PATCH 6/6] refactor(no-debug): remove unnecessary checks --- lib/rules/no-debug.ts | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/lib/rules/no-debug.ts b/lib/rules/no-debug.ts index 98a506ba..f03f0a33 100644 --- a/lib/rules/no-debug.ts +++ b/lib/rules/no-debug.ts @@ -46,10 +46,6 @@ export default createTestingLibraryRule({ VariableDeclarator(node) { const initIdentifierNode = getDeepestIdentifierNode(node.init); - if (!initIdentifierNode) { - return; - } - if (!helpers.isRenderUtil(initIdentifierNode)) { return; } @@ -68,12 +64,12 @@ export default createTestingLibraryRule({ ); } } - } else { - // find utils kept from render and save their node, like: - // const utils = render(); - if (ASTUtils.isIdentifier(node.id)) { - suspiciousReferenceNodes.push(node.id); - } + } + + // find utils kept from render and save their node, like: + // const utils = render(); + if (ASTUtils.isIdentifier(node.id)) { + suspiciousReferenceNodes.push(node.id); } }, CallExpression(node) {