From 2c473abed70b7a4f128c96b3fa6f96d2fb1b6e45 Mon Sep 17 00:00:00 2001 From: Gareth Jones Date: Mon, 26 Apr 2021 12:45:01 +1200 Subject: [PATCH 01/10] feat(no-debug): support `utilNames` option --- docs/rules/no-debug.md | 6 ++++ .../detect-testing-library-utils.ts | 26 +++++++++++++++++ lib/rules/no-debug.ts | 28 ++++++++++++++----- tests/lib/rules/no-debug.test.ts | 27 ++++++++++++++++++ 4 files changed, 80 insertions(+), 7 deletions(-) diff --git a/docs/rules/no-debug.md b/docs/rules/no-debug.md index 1b3167fd..274ffdb8 100644 --- a/docs/rules/no-debug.md +++ b/docs/rules/no-debug.md @@ -28,6 +28,12 @@ const { screen } = require('@testing-library/react'); screen.debug(); ``` +If you want to disallow the use of other debugging functions, you can configure what names this rule checks for with the `utilNames` option: + +``` + "testing-library/no-debug": ["error", {"utilNames": ["debug", "logTestingPlaygroundURL"]}], +``` + ## Further Reading - [debug API in React Testing Library](https://testing-library.com/docs/react-testing-library/api#debug) diff --git a/lib/create-testing-library-rule/detect-testing-library-utils.ts b/lib/create-testing-library-rule/detect-testing-library-utils.ts index 3d6662be..dd8e71ba 100644 --- a/lib/create-testing-library-rule/detect-testing-library-utils.ts +++ b/lib/create-testing-library-rule/detect-testing-library-utils.ts @@ -80,6 +80,10 @@ type IsRenderVariableDeclaratorFn = ( node: TSESTree.VariableDeclarator ) => boolean; type IsDebugUtilFn = (identifierNode: TSESTree.Identifier) => boolean; +type IsOneOfDebugUtils = ( + identifierNode: TSESTree.Identifier, + names: string[] +) => boolean; type IsPresenceAssertFn = (node: TSESTree.MemberExpression) => boolean; type IsAbsenceAssertFn = (node: TSESTree.MemberExpression) => boolean; type CanReportErrorsFn = () => boolean; @@ -112,6 +116,7 @@ export interface DetectionHelpers { isRenderUtil: IsRenderUtilFn; isRenderVariableDeclarator: IsRenderVariableDeclaratorFn; isDebugUtil: IsDebugUtilFn; + isOneOfDebugUtils: IsOneOfDebugUtils; isPresenceAssert: IsPresenceAssertFn; isAbsenceAssert: IsAbsenceAssertFn; canReportErrors: CanReportErrorsFn; @@ -595,6 +600,26 @@ export function detectTestingLibraryUtils< return isRenderUtil(initIdentifierNode); }; + const isOneOfDebugUtils: IsOneOfDebugUtils = ( + identifierNode, + names: string[] + ) => { + const isBuiltInConsole = + isMemberExpression(identifierNode.parent) && + ASTUtils.isIdentifier(identifierNode.parent.object) && + identifierNode.parent.object.name === 'console'; + + return ( + !isBuiltInConsole && + isTestingLibraryUtil( + identifierNode, + (identifierNodeName, originalNodeName) => { + return names.includes(originalNodeName || identifierNodeName); + } + ) + ); + }; + const isDebugUtil: IsDebugUtilFn = (identifierNode) => { const isBuiltInConsole = isMemberExpression(identifierNode.parent) && @@ -807,6 +832,7 @@ export function detectTestingLibraryUtils< isRenderUtil, isRenderVariableDeclarator, isDebugUtil, + isOneOfDebugUtils, isPresenceAssert, isAbsenceAssert, canReportErrors, diff --git a/lib/rules/no-debug.ts b/lib/rules/no-debug.ts index d1a492cf..fe3d2b77 100644 --- a/lib/rules/no-debug.ts +++ b/lib/rules/no-debug.ts @@ -13,7 +13,7 @@ import { ASTUtils, TSESTree } from '@typescript-eslint/experimental-utils'; export const RULE_NAME = 'no-debug'; export type MessageIds = 'noDebug'; -type Options = []; +type Options = [{ utilNames: string[] }]; export default createTestingLibraryRule({ name: RULE_NAME, @@ -32,11 +32,22 @@ export default createTestingLibraryRule({ messages: { noDebug: 'Unexpected debug statement', }, - schema: [], + schema: [ + { + type: 'object', + properties: { + utilNames: { + type: 'array', + items: { type: 'string' }, + }, + }, + additionalProperties: false, + }, + ], }, - defaultOptions: [], + defaultOptions: [{ utilNames: ['debug'] }], - create(context, [], helpers) { + create(context, [{ utilNames }], helpers) { const suspiciousDebugVariableNames: string[] = []; const suspiciousReferenceNodes: TSESTree.Identifier[] = []; const renderWrapperNames: string[] = []; @@ -84,7 +95,7 @@ export default createTestingLibraryRule({ if ( isProperty(property) && ASTUtils.isIdentifier(property.key) && - property.key.name === 'debug' + utilNames.includes(property.key.name) ) { const identifierNode = getDeepestIdentifierNode(property.value); @@ -119,14 +130,17 @@ export default createTestingLibraryRule({ return; } - const isDebugUtil = helpers.isDebugUtil(callExpressionIdentifier); + const isDebugUtil = helpers.isOneOfDebugUtils( + callExpressionIdentifier, + utilNames + ); const isDeclaredDebugVariable = suspiciousDebugVariableNames.includes( callExpressionIdentifier.name ); const isChainedReferenceDebug = suspiciousReferenceNodes.some( (suspiciousReferenceIdentifier) => { return ( - callExpressionIdentifier.name === 'debug' && + utilNames.includes(callExpressionIdentifier.name) && suspiciousReferenceIdentifier.name === referenceIdentifier.name ); } diff --git a/tests/lib/rules/no-debug.test.ts b/tests/lib/rules/no-debug.test.ts index 7606b915..6a104fc3 100644 --- a/tests/lib/rules/no-debug.test.ts +++ b/tests/lib/rules/no-debug.test.ts @@ -87,6 +87,19 @@ ruleTester.run(RULE_NAME, rule, { screen.debug `, }, + { + code: ` + import { screen } from '@testing-library/dom' + screen.logTestingPlaygroundURL() + `, + }, + { + code: ` + import { screen } from '@testing-library/dom' + screen.debug() + `, + options: [{ utilNames: ['anotherUtil'] }], + }, { code: `const { queries } = require('@testing-library/dom')`, }, @@ -419,6 +432,20 @@ ruleTester.run(RULE_NAME, rule, { }, ], }, + { + code: ` + import { screen } from '@testing-library/dom' + screen.logTestingPlaygroundURL() + `, + options: [{ utilNames: ['logTestingPlaygroundURL'] }], + errors: [ + { + line: 3, + column: 16, + messageId: 'noDebug', + }, + ], + }, { settings: { 'testing-library/utils-module': 'test-utils' }, code: `// aggressive reporting disabled From 03564b5de3d54c39032e3f604fc5d86197aa918f Mon Sep 17 00:00:00 2001 From: Gareth Jones Date: Fri, 30 Apr 2021 15:21:29 +1200 Subject: [PATCH 02/10] fix(no-debug): only accept known debug utils --- lib/rules/no-debug.ts | 13 ++++++++----- tests/lib/rules/no-debug.test.ts | 8 +------- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/lib/rules/no-debug.ts b/lib/rules/no-debug.ts index fe3d2b77..74d0ca4f 100644 --- a/lib/rules/no-debug.ts +++ b/lib/rules/no-debug.ts @@ -13,7 +13,7 @@ import { ASTUtils, TSESTree } from '@typescript-eslint/experimental-utils'; export const RULE_NAME = 'no-debug'; export type MessageIds = 'noDebug'; -type Options = [{ utilNames: string[] }]; +type Options = [{ utilNames: Array<'debug' | 'logTestingPlaygroundURL'> }]; export default createTestingLibraryRule({ name: RULE_NAME, @@ -38,14 +38,17 @@ export default createTestingLibraryRule({ properties: { utilNames: { type: 'array', - items: { type: 'string' }, + items: { + type: 'string', + enum: ['debug', 'logTestingPlaygroundURL'], + }, }, }, additionalProperties: false, }, ], }, - defaultOptions: [{ utilNames: ['debug'] }], + defaultOptions: [{ utilNames: ['debug', 'logTestingPlaygroundURL'] }], create(context, [{ utilNames }], helpers) { const suspiciousDebugVariableNames: string[] = []; @@ -95,7 +98,7 @@ export default createTestingLibraryRule({ if ( isProperty(property) && ASTUtils.isIdentifier(property.key) && - utilNames.includes(property.key.name) + (utilNames as string[]).includes(property.key.name) ) { const identifierNode = getDeepestIdentifierNode(property.value); @@ -140,7 +143,7 @@ export default createTestingLibraryRule({ const isChainedReferenceDebug = suspiciousReferenceNodes.some( (suspiciousReferenceIdentifier) => { return ( - utilNames.includes(callExpressionIdentifier.name) && + (utilNames as string[]).includes(callExpressionIdentifier.name) && suspiciousReferenceIdentifier.name === referenceIdentifier.name ); } diff --git a/tests/lib/rules/no-debug.test.ts b/tests/lib/rules/no-debug.test.ts index 6a104fc3..6d43ec76 100644 --- a/tests/lib/rules/no-debug.test.ts +++ b/tests/lib/rules/no-debug.test.ts @@ -92,13 +92,7 @@ ruleTester.run(RULE_NAME, rule, { import { screen } from '@testing-library/dom' screen.logTestingPlaygroundURL() `, - }, - { - code: ` - import { screen } from '@testing-library/dom' - screen.debug() - `, - options: [{ utilNames: ['anotherUtil'] }], + options: [{ utilNames: ['debug'] }], }, { code: `const { queries } = require('@testing-library/dom')`, From dcf5e15948ce39143d632ce6157e796a378c973e Mon Sep 17 00:00:00 2001 From: Gareth Jones Date: Fri, 30 Apr 2021 15:49:21 +1200 Subject: [PATCH 03/10] refactor: merge `isDebugUtil` & `isOneOfDebugUtils` utils --- .../detect-testing-library-utils.ts | 37 +++++-------------- lib/rules/no-debug.ts | 7 ++-- lib/utils/index.ts | 6 +++ 3 files changed, 20 insertions(+), 30 deletions(-) diff --git a/lib/create-testing-library-rule/detect-testing-library-utils.ts b/lib/create-testing-library-rule/detect-testing-library-utils.ts index dd8e71ba..ec729111 100644 --- a/lib/create-testing-library-rule/detect-testing-library-utils.ts +++ b/lib/create-testing-library-rule/detect-testing-library-utils.ts @@ -25,6 +25,7 @@ import { ABSENCE_MATCHERS, ALL_QUERIES_COMBINATIONS, ASYNC_UTILS, + DEBUG_UTILS, PRESENCE_MATCHERS, } from '../utils'; @@ -79,10 +80,9 @@ type IsRenderUtilFn = (node: TSESTree.Identifier) => boolean; type IsRenderVariableDeclaratorFn = ( node: TSESTree.VariableDeclarator ) => boolean; -type IsDebugUtilFn = (identifierNode: TSESTree.Identifier) => boolean; -type IsOneOfDebugUtils = ( +type IsDebugUtilFn = ( identifierNode: TSESTree.Identifier, - names: string[] + validNames?: ReadonlyArray ) => boolean; type IsPresenceAssertFn = (node: TSESTree.MemberExpression) => boolean; type IsAbsenceAssertFn = (node: TSESTree.MemberExpression) => boolean; @@ -116,7 +116,6 @@ export interface DetectionHelpers { isRenderUtil: IsRenderUtilFn; isRenderVariableDeclarator: IsRenderVariableDeclaratorFn; isDebugUtil: IsDebugUtilFn; - isOneOfDebugUtils: IsOneOfDebugUtils; isPresenceAssert: IsPresenceAssertFn; isAbsenceAssert: IsAbsenceAssertFn; canReportErrors: CanReportErrorsFn; @@ -600,9 +599,9 @@ export function detectTestingLibraryUtils< return isRenderUtil(initIdentifierNode); }; - const isOneOfDebugUtils: IsOneOfDebugUtils = ( + const isDebugUtil: IsDebugUtilFn = ( identifierNode, - names: string[] + validNames = DEBUG_UTILS ) => { const isBuiltInConsole = isMemberExpression(identifierNode.parent) && @@ -614,26 +613,11 @@ export function detectTestingLibraryUtils< isTestingLibraryUtil( identifierNode, (identifierNodeName, originalNodeName) => { - return names.includes(originalNodeName || identifierNodeName); - } - ) - ); - }; - - const isDebugUtil: IsDebugUtilFn = (identifierNode) => { - const isBuiltInConsole = - isMemberExpression(identifierNode.parent) && - ASTUtils.isIdentifier(identifierNode.parent.object) && - identifierNode.parent.object.name === 'console'; - - return ( - !isBuiltInConsole && - isTestingLibraryUtil( - identifierNode, - (identifierNodeName, originalNodeName) => { - return [identifierNodeName, originalNodeName] - .filter(Boolean) - .includes('debug'); + return ( + (validNames as string[]).includes(identifierNodeName) || + (!!originalNodeName && + (validNames as string[]).includes(originalNodeName)) + ); } ) ); @@ -832,7 +816,6 @@ export function detectTestingLibraryUtils< isRenderUtil, isRenderVariableDeclarator, isDebugUtil, - isOneOfDebugUtils, isPresenceAssert, isAbsenceAssert, canReportErrors, diff --git a/lib/rules/no-debug.ts b/lib/rules/no-debug.ts index 74d0ca4f..c0bf0c60 100644 --- a/lib/rules/no-debug.ts +++ b/lib/rules/no-debug.ts @@ -8,12 +8,13 @@ import { isObjectPattern, isProperty, } from '../node-utils'; +import { DEBUG_UTILS } from '../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'; -type Options = [{ utilNames: Array<'debug' | 'logTestingPlaygroundURL'> }]; +type Options = [{ utilNames: Array }]; export default createTestingLibraryRule({ name: RULE_NAME, @@ -40,7 +41,7 @@ export default createTestingLibraryRule({ type: 'array', items: { type: 'string', - enum: ['debug', 'logTestingPlaygroundURL'], + enum: DEBUG_UTILS, }, }, }, @@ -133,7 +134,7 @@ export default createTestingLibraryRule({ return; } - const isDebugUtil = helpers.isOneOfDebugUtils( + const isDebugUtil = helpers.isDebugUtil( callExpressionIdentifier, utilNames ); diff --git a/lib/utils/index.ts b/lib/utils/index.ts index 106d5f36..b9d899e5 100644 --- a/lib/utils/index.ts +++ b/lib/utils/index.ts @@ -66,6 +66,11 @@ const ASYNC_UTILS = [ 'waitForDomChange', ] as const; +const DEBUG_UTILS = [ + 'debug', // + 'logTestingPlaygroundURL', +] as const; + const EVENTS_SIMULATORS = ['fireEvent', 'userEvent'] as const; const TESTING_FRAMEWORK_SETUP_HOOKS = ['beforeEach', 'beforeAll']; @@ -119,6 +124,7 @@ export { ASYNC_QUERIES_COMBINATIONS, ALL_QUERIES_COMBINATIONS, ASYNC_UTILS, + DEBUG_UTILS, EVENTS_SIMULATORS, TESTING_FRAMEWORK_SETUP_HOOKS, LIBRARY_MODULES, From 995f3db4508b1ad3af42e249927f636b6bdebab1 Mon Sep 17 00:00:00 2001 From: Gareth Jones Date: Fri, 30 Apr 2021 16:04:01 +1200 Subject: [PATCH 04/10] docs(no-debug): mention which utils are checked for by default --- docs/rules/no-debug.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/rules/no-debug.md b/docs/rules/no-debug.md index 274ffdb8..5cf36459 100644 --- a/docs/rules/no-debug.md +++ b/docs/rules/no-debug.md @@ -2,6 +2,8 @@ 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. +By default, this rule disallows the `debug` and `logTestingPlaygroundURL` utils. + ## Rule Details This rule aims to disallow the use of `debug` in your tests. @@ -28,10 +30,10 @@ const { screen } = require('@testing-library/react'); screen.debug(); ``` -If you want to disallow the use of other debugging functions, you can configure what names this rule checks for with the `utilNames` option: +If you want to allow the use of some debugging functions, you can configure what names this rule checks for with the `utilNames` option: ``` - "testing-library/no-debug": ["error", {"utilNames": ["debug", "logTestingPlaygroundURL"]}], + "testing-library/no-debug": ["error", {"utilNames": ["debug"}], ``` ## Further Reading From 31cefa05a2dbfe4a9acb2ba03ef0b7c7f5b9457c Mon Sep 17 00:00:00 2001 From: Gareth Jones Date: Sat, 1 May 2021 11:55:00 +1200 Subject: [PATCH 05/10] fix(no-debug): mark `utilNames` as optional --- lib/rules/no-debug.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/rules/no-debug.ts b/lib/rules/no-debug.ts index c0bf0c60..98095f54 100644 --- a/lib/rules/no-debug.ts +++ b/lib/rules/no-debug.ts @@ -14,7 +14,7 @@ import { ASTUtils, TSESTree } from '@typescript-eslint/experimental-utils'; export const RULE_NAME = 'no-debug'; export type MessageIds = 'noDebug'; -type Options = [{ utilNames: Array }]; +type Options = [{ utilNames?: Array }]; export default createTestingLibraryRule({ name: RULE_NAME, From 69470d002c83e080429896426faff04bcb3987c3 Mon Sep 17 00:00:00 2001 From: Gareth Jones Date: Sat, 1 May 2021 11:56:44 +1200 Subject: [PATCH 06/10] test(no-debug): add new case --- tests/lib/rules/no-debug.test.ts | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tests/lib/rules/no-debug.test.ts b/tests/lib/rules/no-debug.test.ts index 6d43ec76..8c3e0ef2 100644 --- a/tests/lib/rules/no-debug.test.ts +++ b/tests/lib/rules/no-debug.test.ts @@ -440,6 +440,19 @@ ruleTester.run(RULE_NAME, rule, { }, ], }, + { + code: ` + import { screen } from '@testing-library/dom' + screen.logTestingPlaygroundURL() + `, + errors: [ + { + line: 3, + column: 16, + messageId: 'noDebug', + }, + ], + }, { settings: { 'testing-library/utils-module': 'test-utils' }, code: `// aggressive reporting disabled From 1e5702441ef7414fc111d5a0c1c0ae08e8752a6c Mon Sep 17 00:00:00 2001 From: Gareth Jones Date: Fri, 7 May 2021 11:18:56 +1200 Subject: [PATCH 07/10] feat(no-debug): accept `utilsToCheckFor` property option --- lib/rules/no-debug.ts | 46 +++++++++++++++++++++++--------- tests/lib/rules/no-debug.test.ts | 39 +++++++++++++++++++++++++-- 2 files changed, 70 insertions(+), 15 deletions(-) diff --git a/lib/rules/no-debug.ts b/lib/rules/no-debug.ts index 98095f54..639d62a5 100644 --- a/lib/rules/no-debug.ts +++ b/lib/rules/no-debug.ts @@ -10,11 +10,19 @@ import { } from '../node-utils'; import { DEBUG_UTILS } from '../utils'; import { createTestingLibraryRule } from '../create-testing-library-rule'; -import { ASTUtils, TSESTree } from '@typescript-eslint/experimental-utils'; +import { + ASTUtils, + TSESTree, + JSONSchema, +} from '@typescript-eslint/experimental-utils'; + +type DebugUtilsToCheckFor = Partial< + Record +>; export const RULE_NAME = 'no-debug'; export type MessageIds = 'noDebug'; -type Options = [{ utilNames?: Array }]; +type Options = [{ utilsToCheckFor?: DebugUtilsToCheckFor }]; export default createTestingLibraryRule({ name: RULE_NAME, @@ -37,26 +45,38 @@ export default createTestingLibraryRule({ { type: 'object', properties: { - utilNames: { - type: 'array', - items: { - type: 'string', - enum: DEBUG_UTILS, - }, + utilsToCheckFor: { + type: 'object', + properties: DEBUG_UTILS.reduce< + Record + >( + (obj, name) => ({ + [name]: { type: 'boolean' }, + ...obj, + }), + {} + ), + additionalProperties: false, }, }, additionalProperties: false, }, ], }, - defaultOptions: [{ utilNames: ['debug', 'logTestingPlaygroundURL'] }], + defaultOptions: [ + { utilsToCheckFor: { debug: true, logTestingPlaygroundURL: true } }, + ], - create(context, [{ utilNames }], helpers) { + create(context, [{ utilsToCheckFor = {} }], helpers) { const suspiciousDebugVariableNames: string[] = []; const suspiciousReferenceNodes: TSESTree.Identifier[] = []; const renderWrapperNames: string[] = []; const builtInConsoleNodes: TSESTree.VariableDeclarator[] = []; + const utilsToReport = Object.entries(utilsToCheckFor) + .filter(([, shouldCheckFor]) => shouldCheckFor) + .map(([name]) => name); + function detectRenderWrapper(node: TSESTree.Identifier): void { const innerFunction = getInnermostReturningFunction(context, node); @@ -99,7 +119,7 @@ export default createTestingLibraryRule({ if ( isProperty(property) && ASTUtils.isIdentifier(property.key) && - (utilNames as string[]).includes(property.key.name) + utilsToReport.includes(property.key.name) ) { const identifierNode = getDeepestIdentifierNode(property.value); @@ -136,7 +156,7 @@ export default createTestingLibraryRule({ const isDebugUtil = helpers.isDebugUtil( callExpressionIdentifier, - utilNames + utilsToReport as Array ); const isDeclaredDebugVariable = suspiciousDebugVariableNames.includes( callExpressionIdentifier.name @@ -144,7 +164,7 @@ export default createTestingLibraryRule({ const isChainedReferenceDebug = suspiciousReferenceNodes.some( (suspiciousReferenceIdentifier) => { return ( - (utilNames as string[]).includes(callExpressionIdentifier.name) && + utilsToReport.includes(callExpressionIdentifier.name) && suspiciousReferenceIdentifier.name === referenceIdentifier.name ); } diff --git a/tests/lib/rules/no-debug.test.ts b/tests/lib/rules/no-debug.test.ts index 8c3e0ef2..376ddac4 100644 --- a/tests/lib/rules/no-debug.test.ts +++ b/tests/lib/rules/no-debug.test.ts @@ -92,7 +92,14 @@ ruleTester.run(RULE_NAME, rule, { import { screen } from '@testing-library/dom' screen.logTestingPlaygroundURL() `, - options: [{ utilNames: ['debug'] }], + options: [{ utilsToCheckFor: { logTestingPlaygroundURL: false } }], + }, + { + code: ` + import { screen } from '@testing-library/dom' + screen.logTestingPlaygroundURL() + `, + options: [{ utilsToCheckFor: undefined }], }, { code: `const { queries } = require('@testing-library/dom')`, @@ -431,7 +438,35 @@ ruleTester.run(RULE_NAME, rule, { import { screen } from '@testing-library/dom' screen.logTestingPlaygroundURL() `, - options: [{ utilNames: ['logTestingPlaygroundURL'] }], + options: [{ utilsToCheckFor: { logTestingPlaygroundURL: true } }], + errors: [ + { + line: 3, + column: 16, + messageId: 'noDebug', + }, + ], + }, + { + code: ` + import { screen } from '@testing-library/dom' + screen.logTestingPlaygroundURL() + `, + options: [{ utilsToCheckFor: { debug: false } }], + errors: [ + { + line: 3, + column: 16, + messageId: 'noDebug', + }, + ], + }, + { + code: ` + import { screen } from '@testing-library/dom' + screen.logTestingPlaygroundURL() + `, + options: [{ utilsToCheckFor: {} }], errors: [ { line: 3, From 5b320a40899a4e0bfae1d12b0542bc75bb6e197d Mon Sep 17 00:00:00 2001 From: Gareth Jones Date: Fri, 7 May 2021 11:20:50 +1200 Subject: [PATCH 08/10] feat: support more `DEBUG_UTILS` --- lib/utils/index.ts | 6 +++++- tests/lib/rules/no-debug.test.ts | 28 ++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/lib/utils/index.ts b/lib/utils/index.ts index b9d899e5..55997e11 100644 --- a/lib/utils/index.ts +++ b/lib/utils/index.ts @@ -67,8 +67,12 @@ const ASYNC_UTILS = [ ] as const; const DEBUG_UTILS = [ - 'debug', // + 'debug', 'logTestingPlaygroundURL', + 'prettyDOM', + 'logRoles', + 'logDOM', + 'prettyFormat', ] as const; const EVENTS_SIMULATORS = ['fireEvent', 'userEvent'] as const; diff --git a/tests/lib/rules/no-debug.test.ts b/tests/lib/rules/no-debug.test.ts index 376ddac4..81507a38 100644 --- a/tests/lib/rules/no-debug.test.ts +++ b/tests/lib/rules/no-debug.test.ts @@ -447,6 +447,34 @@ ruleTester.run(RULE_NAME, rule, { }, ], }, + { + code: ` + import { logRoles } from '@testing-library/dom' + logRoles(document.createElement('nav')) + `, + options: [{ utilsToCheckFor: { logRoles: true } }], + errors: [ + { + line: 3, + column: 9, + messageId: 'noDebug', + }, + ], + }, + { + code: ` + import { screen } from '@testing-library/dom' + screen.logTestingPlaygroundURL() + `, + options: [{ utilsToCheckFor: { logRoles: true } }], + errors: [ + { + line: 3, + column: 16, + messageId: 'noDebug', + }, + ], + }, { code: ` import { screen } from '@testing-library/dom' From 5d6c0941b551c523064d47c73a5fbd810572c60d Mon Sep 17 00:00:00 2001 From: Gareth Jones Date: Fri, 14 May 2021 09:05:52 +1200 Subject: [PATCH 09/10] docs(no-debug): update with details of new functionality --- README.md | 2 +- docs/rules/no-debug.md | 8 ++++---- lib/rules/no-debug.ts | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index f438182c..6ea2bcf9 100644 --- a/README.md +++ b/README.md @@ -187,7 +187,7 @@ To enable this configuration use the `extends` property in your | [testing-library/no-await-sync-events](docs/rules/no-await-sync-events.md) | Disallow unnecessary `await` for sync events | | | | [testing-library/no-await-sync-query](docs/rules/no-await-sync-query.md) | Disallow unnecessary `await` for sync queries | ![dom-badge][] ![angular-badge][] ![react-badge][] ![vue-badge][] | | | [testing-library/no-container](docs/rules/no-container.md) | Disallow the use of `container` methods | ![angular-badge][] ![react-badge][] ![vue-badge][] | | -| [testing-library/no-debug](docs/rules/no-debug.md) | Disallow the use of `debug` | ![angular-badge][] ![react-badge][] ![vue-badge][] | | +| [testing-library/no-debug](docs/rules/no-debug.md) | Disallow the use of debugging utilities like `debug` | ![angular-badge][] ![react-badge][] ![vue-badge][] | | | [testing-library/no-dom-import](docs/rules/no-dom-import.md) | Disallow importing from DOM Testing Library | ![angular-badge][] ![react-badge][] ![vue-badge][] | ![fixable-badge][] | | [testing-library/no-manual-cleanup](docs/rules/no-manual-cleanup.md) | Disallow the use of `cleanup` | | | | [testing-library/no-node-access](docs/rules/no-node-access.md) | Disallow direct Node access | ![angular-badge][] ![react-badge][] ![vue-badge][] | | diff --git a/docs/rules/no-debug.md b/docs/rules/no-debug.md index 5cf36459..a076be78 100644 --- a/docs/rules/no-debug.md +++ b/docs/rules/no-debug.md @@ -1,4 +1,4 @@ -# Disallow the use of `debug` (`testing-library/no-debug`) +# Disallow the use of debugging utilities like `debug` (`testing-library/no-debug`) 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. @@ -6,7 +6,7 @@ By default, this rule disallows the `debug` and `logTestingPlaygroundURL` utils. ## Rule Details -This rule aims to disallow the use of `debug` in your tests. +This rule aims to disallow the use of debugging utilities like `debug` in your tests. Examples of **incorrect** code for this rule: @@ -30,10 +30,10 @@ const { screen } = require('@testing-library/react'); screen.debug(); ``` -If you want to allow the use of some debugging functions, you can configure what names this rule checks for with the `utilNames` option: +If you want to allow the use of some debugging functions, you can configure what names this rule checks for with the `utilsToCheckFor` option: ``` - "testing-library/no-debug": ["error", {"utilNames": ["debug"}], + "testing-library/no-debug": ["error", { "utilsToCheckFor": { "debug": false } }, ``` ## Further Reading diff --git a/lib/rules/no-debug.ts b/lib/rules/no-debug.ts index 639d62a5..39d2829a 100644 --- a/lib/rules/no-debug.ts +++ b/lib/rules/no-debug.ts @@ -29,7 +29,7 @@ export default createTestingLibraryRule({ meta: { type: 'problem', docs: { - description: 'Disallow unnecessary debug usages in the tests', + description: 'Disallow the use of debugging utilities like `debug`', category: 'Best Practices', recommendedConfig: { dom: false, From d363cd024d093170bd0b74e4fc0bd2146521f670 Mon Sep 17 00:00:00 2001 From: Gareth Jones Date: Fri, 14 May 2021 11:30:39 +1200 Subject: [PATCH 10/10] docs(no-debug): include list of debug utils and more complete example --- docs/rules/no-debug.md | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/docs/rules/no-debug.md b/docs/rules/no-debug.md index a076be78..9ae030dd 100644 --- a/docs/rules/no-debug.md +++ b/docs/rules/no-debug.md @@ -2,11 +2,18 @@ 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. -By default, this rule disallows the `debug` and `logTestingPlaygroundURL` utils. - ## Rule Details -This rule aims to disallow the use of debugging utilities like `debug` in your tests. +This rule supports disallowing the following debugging utilities: + +- `debug` +- `logTestingPlaygroundURL` +- `prettyDOM` +- `logRoles` +- `logDOM` +- `prettyFormat` + +By default, only `debug` and `logTestingPlaygroundURL` are disallowed. Examples of **incorrect** code for this rule: @@ -30,10 +37,21 @@ const { screen } = require('@testing-library/react'); screen.debug(); ``` -If you want to allow the use of some debugging functions, you can configure what names this rule checks for with the `utilsToCheckFor` option: - -``` - "testing-library/no-debug": ["error", { "utilsToCheckFor": { "debug": false } }, +You can control which debugging utils are checked for with the `utilsToCheckFor` option: + +```json +{ + "testing-library/no-debug": [ + "error", + { + "utilsToCheckFor": { + "debug": false, + "logRoles": true, + "logDOM": true + } + } + ] +} ``` ## Further Reading