From 1bb6d668c5959df5a137c6e870c02255e79fa9de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20Beltr=C3=A1n=20Alarc=C3=B3n?= Date: Sun, 21 Mar 2021 12:00:08 +0100 Subject: [PATCH 1/6] refactor: rename setting for matching files by pattern --- lib/detect-testing-library-utils.ts | 6 +++--- tests/create-testing-library-rule.test.ts | 20 ++++++++++---------- tests/lib/rules/no-await-sync-query.test.ts | 2 +- tests/lib/rules/no-dom-import.test.ts | 8 ++++---- tests/lib/rules/no-manual-cleanup.test.ts | 2 +- tests/lib/rules/no-node-access.test.ts | 2 +- 6 files changed, 20 insertions(+), 20 deletions(-) diff --git a/lib/detect-testing-library-utils.ts b/lib/detect-testing-library-utils.ts index 503729c1..a0d41ca2 100644 --- a/lib/detect-testing-library-utils.ts +++ b/lib/detect-testing-library-utils.ts @@ -27,7 +27,7 @@ import { export type TestingLibrarySettings = { 'testing-library/utils-module'?: string; - 'testing-library/filename-pattern'?: string; + 'testing-library/file-patterns'?: string; 'testing-library/custom-renders'?: string[]; }; @@ -133,7 +133,7 @@ export function detectTestingLibraryUtils< // Init options based on shared ESLint settings const customModule = context.settings['testing-library/utils-module']; const filenamePattern = - context.settings['testing-library/filename-pattern'] ?? + context.settings['testing-library/file-patterns'] ?? DEFAULT_FILENAME_PATTERN; const customRenders = context.settings['testing-library/custom-renders']; @@ -245,7 +245,7 @@ export function detectTestingLibraryUtils< /** * Determines whether filename is valid or not for current file - * being analyzed based on "testing-library/filename-pattern" setting. + * being analyzed based on "testing-library/file-patterns" setting. */ const isValidFilename: IsValidFilenameFn = () => { const fileName = context.getFilename(); diff --git a/tests/create-testing-library-rule.test.ts b/tests/create-testing-library-rule.test.ts index 4907e995..5d0d5fc4 100644 --- a/tests/create-testing-library-rule.test.ts +++ b/tests/create-testing-library-rule.test.ts @@ -70,7 +70,7 @@ ruleTester.run(RULE_NAME, rule, { import { foo } from 'report-me' `, settings: { - 'testing-library/filename-pattern': 'testing-library\\.js', + 'testing-library/file-patterns': 'testing-library\\.js', }, }, { @@ -80,7 +80,7 @@ ruleTester.run(RULE_NAME, rule, { const { foo } = require('report-me') `, settings: { - 'testing-library/filename-pattern': 'testing-library\\.js', + 'testing-library/file-patterns': 'testing-library\\.js', }, }, { @@ -252,7 +252,7 @@ ruleTester.run(RULE_NAME, rule, { }, { settings: { - 'testing-library/filename-pattern': 'testing-library\\.js', + 'testing-library/file-patterns': 'testing-library\\.js', }, code: ` // case: built-in "getBy*" query not reported because custom filename doesn't match @@ -261,7 +261,7 @@ ruleTester.run(RULE_NAME, rule, { }, { settings: { - 'testing-library/filename-pattern': 'testing-library\\.js', + 'testing-library/file-patterns': 'testing-library\\.js', }, code: ` // case: built-in "queryBy*" query not reported because custom filename doesn't match @@ -270,7 +270,7 @@ ruleTester.run(RULE_NAME, rule, { }, { settings: { - 'testing-library/filename-pattern': 'testing-library\\.js', + 'testing-library/file-patterns': 'testing-library\\.js', }, code: ` // case: built-in "findBy*" query not reported because custom filename doesn't match @@ -320,7 +320,7 @@ ruleTester.run(RULE_NAME, rule, { { settings: { 'testing-library/utils-module': 'test-utils', - 'testing-library/filename-pattern': 'testing-library\\.js', + 'testing-library/file-patterns': 'testing-library\\.js', }, code: ` // case: matching custom settings partially - module but not filename @@ -334,7 +334,7 @@ ruleTester.run(RULE_NAME, rule, { { settings: { 'testing-library/utils-module': 'test-utils', - 'testing-library/filename-pattern': 'testing-library\\.js', + 'testing-library/file-patterns': 'testing-library\\.js', }, filename: 'MyComponent.testing-library.js', code: ` @@ -382,7 +382,7 @@ ruleTester.run(RULE_NAME, rule, { import { foo } from 'report-me' `, settings: { - 'testing-library/filename-pattern': 'testing-library\\.js', + 'testing-library/file-patterns': 'testing-library\\.js', }, errors: [{ line: 3, column: 7, messageId: 'fakeError' }], }, @@ -924,7 +924,7 @@ ruleTester.run(RULE_NAME, rule, { settings: { 'testing-library/custom-renders': ['customRender', 'renderWithRedux'], 'testing-library/utils-module': 'test-utils', - 'testing-library/filename-pattern': 'custom-suffix\\.js', + 'testing-library/file-patterns': 'custom-suffix\\.js', }, code: ` // case: all aggressive reporting disabled and filename setup - matching all custom settings @@ -948,7 +948,7 @@ ruleTester.run(RULE_NAME, rule, { { settings: { 'testing-library/utils-module': 'test-utils', - 'testing-library/filename-pattern': 'testing-library\\.js', + 'testing-library/file-patterns': 'testing-library\\.js', }, filename: 'MyComponent.testing-library.js', code: ` diff --git a/tests/lib/rules/no-await-sync-query.test.ts b/tests/lib/rules/no-await-sync-query.test.ts index 2bef1ab9..e261aafe 100644 --- a/tests/lib/rules/no-await-sync-query.test.ts +++ b/tests/lib/rules/no-await-sync-query.test.ts @@ -69,7 +69,7 @@ ruleTester.run(RULE_NAME, rule, { }, // sync query awaited but not matching filename pattern is invalid but not reported { - settings: { 'testing-library/filename-pattern': 'nope\\.js' }, + settings: { 'testing-library/file-patterns': 'nope\\.js' }, code: ` () => { const element = await getByRole('button') diff --git a/tests/lib/rules/no-dom-import.test.ts b/tests/lib/rules/no-dom-import.test.ts index d459f9e7..53727858 100644 --- a/tests/lib/rules/no-dom-import.test.ts +++ b/tests/lib/rules/no-dom-import.test.ts @@ -31,7 +31,7 @@ ruleTester.run(RULE_NAME, rule, { }, { code: 'import { fireEvent } from "dom-testing-library"', - settings: { 'testing-library/filename-pattern': 'nope\\.js' }, + settings: { 'testing-library/file-patterns': 'nope\\.js' }, }, { code: 'const { fireEvent } = require("dom-testing-library")', @@ -39,7 +39,7 @@ ruleTester.run(RULE_NAME, rule, { }, { code: 'const { fireEvent } = require("dom-testing-library")', - settings: { 'testing-library/filename-pattern': 'nope\\.js' }, + settings: { 'testing-library/file-patterns': 'nope\\.js' }, }, { code: 'import { fireEvent } from "@testing-library/dom"', @@ -47,7 +47,7 @@ ruleTester.run(RULE_NAME, rule, { }, { code: 'import { fireEvent } from "@testing-library/dom"', - settings: { 'testing-library/filename-pattern': 'nope\\.js' }, + settings: { 'testing-library/file-patterns': 'nope\\.js' }, }, { code: 'const { fireEvent } = require("@testing-library/dom")', @@ -55,7 +55,7 @@ ruleTester.run(RULE_NAME, rule, { }, { code: 'const { fireEvent } = require("@testing-library/dom")', - settings: { 'testing-library/filename-pattern': 'nope\\.js' }, + settings: { 'testing-library/file-patterns': 'nope\\.js' }, }, ], invalid: [ diff --git a/tests/lib/rules/no-manual-cleanup.test.ts b/tests/lib/rules/no-manual-cleanup.test.ts index 3c681b27..4aef5c0d 100644 --- a/tests/lib/rules/no-manual-cleanup.test.ts +++ b/tests/lib/rules/no-manual-cleanup.test.ts @@ -56,7 +56,7 @@ ruleTester.run(RULE_NAME, rule, { }, { settings: { - 'testing-library/filename-pattern': 'testing-library\\.js', + 'testing-library/file-patterns': 'testing-library\\.js', }, code: ` import { render, cleanup } from "${ALL_TESTING_LIBRARIES_WITH_CLEANUP[0]}" diff --git a/tests/lib/rules/no-node-access.test.ts b/tests/lib/rules/no-node-access.test.ts index c8a9e3f7..4cd3242a 100644 --- a/tests/lib/rules/no-node-access.test.ts +++ b/tests/lib/rules/no-node-access.test.ts @@ -54,7 +54,7 @@ ruleTester.run(RULE_NAME, rule, { } `, settings: { - 'testing-library/filename-pattern': 'testing-library\\.js', + 'testing-library/file-patterns': 'testing-library\\.js', }, }, { From 3e0ba90f6af5300454c713cdc8b2255813d9242b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20Beltr=C3=A1n=20Alarc=C3=B3n?= Date: Sun, 21 Mar 2021 12:07:11 +0100 Subject: [PATCH 2/6] refactor: move file pattern setting to array of strings --- lib/detect-testing-library-utils.ts | 8 ++++---- tests/create-testing-library-rule.test.ts | 20 ++++++++++---------- tests/lib/rules/no-await-sync-query.test.ts | 2 +- tests/lib/rules/no-dom-import.test.ts | 8 ++++---- tests/lib/rules/no-manual-cleanup.test.ts | 2 +- tests/lib/rules/no-node-access.test.ts | 2 +- 6 files changed, 21 insertions(+), 21 deletions(-) diff --git a/lib/detect-testing-library-utils.ts b/lib/detect-testing-library-utils.ts index a0d41ca2..f84b8ecd 100644 --- a/lib/detect-testing-library-utils.ts +++ b/lib/detect-testing-library-utils.ts @@ -27,7 +27,7 @@ import { export type TestingLibrarySettings = { 'testing-library/utils-module'?: string; - 'testing-library/file-patterns'?: string; + 'testing-library/file-patterns'?: string[]; 'testing-library/custom-renders'?: string[]; }; @@ -110,7 +110,7 @@ export interface DetectionHelpers { isNodeComingFromTestingLibrary: IsNodeComingFromTestingLibraryFn; } -const DEFAULT_FILENAME_PATTERN = '^.*\\.(test|spec)\\.[jt]sx?$'; +const DEFAULT_FILENAME_PATTERN = ['^.*\\.(test|spec)\\.[jt]sx?$']; const FIRE_EVENT_NAME = 'fireEvent'; const RENDER_NAME = 'render'; @@ -132,7 +132,7 @@ export function detectTestingLibraryUtils< // Init options based on shared ESLint settings const customModule = context.settings['testing-library/utils-module']; - const filenamePattern = + const filePatterns = context.settings['testing-library/file-patterns'] ?? DEFAULT_FILENAME_PATTERN; const customRenders = context.settings['testing-library/custom-renders']; @@ -249,7 +249,7 @@ export function detectTestingLibraryUtils< */ const isValidFilename: IsValidFilenameFn = () => { const fileName = context.getFilename(); - return !!fileName.match(filenamePattern); + return filePatterns.some((pattern) => fileName.match(pattern)); }; /** diff --git a/tests/create-testing-library-rule.test.ts b/tests/create-testing-library-rule.test.ts index 5d0d5fc4..563fc02a 100644 --- a/tests/create-testing-library-rule.test.ts +++ b/tests/create-testing-library-rule.test.ts @@ -70,7 +70,7 @@ ruleTester.run(RULE_NAME, rule, { import { foo } from 'report-me' `, settings: { - 'testing-library/file-patterns': 'testing-library\\.js', + 'testing-library/file-patterns': ['testing-library\\.js'], }, }, { @@ -80,7 +80,7 @@ ruleTester.run(RULE_NAME, rule, { const { foo } = require('report-me') `, settings: { - 'testing-library/file-patterns': 'testing-library\\.js', + 'testing-library/file-patterns': ['testing-library\\.js'], }, }, { @@ -252,7 +252,7 @@ ruleTester.run(RULE_NAME, rule, { }, { settings: { - 'testing-library/file-patterns': 'testing-library\\.js', + 'testing-library/file-patterns': ['testing-library\\.js'], }, code: ` // case: built-in "getBy*" query not reported because custom filename doesn't match @@ -261,7 +261,7 @@ ruleTester.run(RULE_NAME, rule, { }, { settings: { - 'testing-library/file-patterns': 'testing-library\\.js', + 'testing-library/file-patterns': ['testing-library\\.js'], }, code: ` // case: built-in "queryBy*" query not reported because custom filename doesn't match @@ -270,7 +270,7 @@ ruleTester.run(RULE_NAME, rule, { }, { settings: { - 'testing-library/file-patterns': 'testing-library\\.js', + 'testing-library/file-patterns': ['testing-library\\.js'], }, code: ` // case: built-in "findBy*" query not reported because custom filename doesn't match @@ -320,7 +320,7 @@ ruleTester.run(RULE_NAME, rule, { { settings: { 'testing-library/utils-module': 'test-utils', - 'testing-library/file-patterns': 'testing-library\\.js', + 'testing-library/file-patterns': ['testing-library\\.js'], }, code: ` // case: matching custom settings partially - module but not filename @@ -334,7 +334,7 @@ ruleTester.run(RULE_NAME, rule, { { settings: { 'testing-library/utils-module': 'test-utils', - 'testing-library/file-patterns': 'testing-library\\.js', + 'testing-library/file-patterns': ['testing-library\\.js'], }, filename: 'MyComponent.testing-library.js', code: ` @@ -382,7 +382,7 @@ ruleTester.run(RULE_NAME, rule, { import { foo } from 'report-me' `, settings: { - 'testing-library/file-patterns': 'testing-library\\.js', + 'testing-library/file-patterns': ['testing-library\\.js'], }, errors: [{ line: 3, column: 7, messageId: 'fakeError' }], }, @@ -924,7 +924,7 @@ ruleTester.run(RULE_NAME, rule, { settings: { 'testing-library/custom-renders': ['customRender', 'renderWithRedux'], 'testing-library/utils-module': 'test-utils', - 'testing-library/file-patterns': 'custom-suffix\\.js', + 'testing-library/file-patterns': ['custom-suffix\\.js'], }, code: ` // case: all aggressive reporting disabled and filename setup - matching all custom settings @@ -948,7 +948,7 @@ ruleTester.run(RULE_NAME, rule, { { settings: { 'testing-library/utils-module': 'test-utils', - 'testing-library/file-patterns': 'testing-library\\.js', + 'testing-library/file-patterns': ['testing-library\\.js'], }, filename: 'MyComponent.testing-library.js', code: ` diff --git a/tests/lib/rules/no-await-sync-query.test.ts b/tests/lib/rules/no-await-sync-query.test.ts index e261aafe..db50fd71 100644 --- a/tests/lib/rules/no-await-sync-query.test.ts +++ b/tests/lib/rules/no-await-sync-query.test.ts @@ -69,7 +69,7 @@ ruleTester.run(RULE_NAME, rule, { }, // sync query awaited but not matching filename pattern is invalid but not reported { - settings: { 'testing-library/file-patterns': 'nope\\.js' }, + settings: { 'testing-library/file-patterns': ['nope\\.js'] }, code: ` () => { const element = await getByRole('button') diff --git a/tests/lib/rules/no-dom-import.test.ts b/tests/lib/rules/no-dom-import.test.ts index 53727858..67e3fa20 100644 --- a/tests/lib/rules/no-dom-import.test.ts +++ b/tests/lib/rules/no-dom-import.test.ts @@ -31,7 +31,7 @@ ruleTester.run(RULE_NAME, rule, { }, { code: 'import { fireEvent } from "dom-testing-library"', - settings: { 'testing-library/file-patterns': 'nope\\.js' }, + settings: { 'testing-library/file-patterns': ['nope\\.js'] }, }, { code: 'const { fireEvent } = require("dom-testing-library")', @@ -39,7 +39,7 @@ ruleTester.run(RULE_NAME, rule, { }, { code: 'const { fireEvent } = require("dom-testing-library")', - settings: { 'testing-library/file-patterns': 'nope\\.js' }, + settings: { 'testing-library/file-patterns': ['nope\\.js'] }, }, { code: 'import { fireEvent } from "@testing-library/dom"', @@ -47,7 +47,7 @@ ruleTester.run(RULE_NAME, rule, { }, { code: 'import { fireEvent } from "@testing-library/dom"', - settings: { 'testing-library/file-patterns': 'nope\\.js' }, + settings: { 'testing-library/file-patterns': ['nope\\.js'] }, }, { code: 'const { fireEvent } = require("@testing-library/dom")', @@ -55,7 +55,7 @@ ruleTester.run(RULE_NAME, rule, { }, { code: 'const { fireEvent } = require("@testing-library/dom")', - settings: { 'testing-library/file-patterns': 'nope\\.js' }, + settings: { 'testing-library/file-patterns': ['nope\\.js'] }, }, ], invalid: [ diff --git a/tests/lib/rules/no-manual-cleanup.test.ts b/tests/lib/rules/no-manual-cleanup.test.ts index 4aef5c0d..7a4582b6 100644 --- a/tests/lib/rules/no-manual-cleanup.test.ts +++ b/tests/lib/rules/no-manual-cleanup.test.ts @@ -56,7 +56,7 @@ ruleTester.run(RULE_NAME, rule, { }, { settings: { - 'testing-library/file-patterns': 'testing-library\\.js', + 'testing-library/file-patterns': ['testing-library\\.js'], }, code: ` import { render, cleanup } from "${ALL_TESTING_LIBRARIES_WITH_CLEANUP[0]}" diff --git a/tests/lib/rules/no-node-access.test.ts b/tests/lib/rules/no-node-access.test.ts index 4cd3242a..e143005f 100644 --- a/tests/lib/rules/no-node-access.test.ts +++ b/tests/lib/rules/no-node-access.test.ts @@ -54,7 +54,7 @@ ruleTester.run(RULE_NAME, rule, { } `, settings: { - 'testing-library/file-patterns': 'testing-library\\.js', + 'testing-library/file-patterns': ['testing-library\\.js'], }, }, { From 10eac1c16fa9a2797ebfeb385b944501171147ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20Beltr=C3=A1n=20Alarc=C3=B3n?= Date: Sun, 21 Mar 2021 12:14:19 +0100 Subject: [PATCH 3/6] refactor: rename helper for knowing if file matches --- lib/detect-testing-library-utils.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/detect-testing-library-utils.ts b/lib/detect-testing-library-utils.ts index f84b8ecd..31e0ea91 100644 --- a/lib/detect-testing-library-utils.ts +++ b/lib/detect-testing-library-utils.ts @@ -56,7 +56,7 @@ type GetCustomModuleImportNodeFn = () => ImportModuleNode | null; type GetTestingLibraryImportNameFn = () => string | undefined; type GetCustomModuleImportNameFn = () => string | undefined; type IsTestingLibraryImportedFn = () => boolean; -type IsValidFilenameFn = () => boolean; +type IsMatchingFilenameFn = () => boolean; type IsGetQueryVariantFn = (node: TSESTree.Identifier) => boolean; type IsQueryQueryVariantFn = (node: TSESTree.Identifier) => boolean; type IsFindQueryVariantFn = (node: TSESTree.Identifier) => boolean; @@ -90,7 +90,7 @@ export interface DetectionHelpers { getTestingLibraryImportName: GetTestingLibraryImportNameFn; getCustomModuleImportName: GetCustomModuleImportNameFn; isTestingLibraryImported: IsTestingLibraryImportedFn; - isValidFilename: IsValidFilenameFn; + isMatchingFilename: IsMatchingFilenameFn; isGetQueryVariant: IsGetQueryVariantFn; isQueryQueryVariant: IsQueryQueryVariantFn; isFindQueryVariant: IsFindQueryVariantFn; @@ -247,7 +247,7 @@ export function detectTestingLibraryUtils< * Determines whether filename is valid or not for current file * being analyzed based on "testing-library/file-patterns" setting. */ - const isValidFilename: IsValidFilenameFn = () => { + const isMatchingFilename: IsMatchingFilenameFn = () => { const fileName = context.getFilename(); return filePatterns.some((pattern) => fileName.match(pattern)); }; @@ -536,7 +536,7 @@ export function detectTestingLibraryUtils< * Determines if file inspected meets all conditions to be reported by rules or not. */ const canReportErrors: CanReportErrorsFn = () => { - return isTestingLibraryImported() && isValidFilename(); + return isTestingLibraryImported() && isMatchingFilename(); }; /** @@ -566,7 +566,7 @@ export function detectTestingLibraryUtils< getTestingLibraryImportName, getCustomModuleImportName, isTestingLibraryImported, - isValidFilename, + isMatchingFilename, isGetQueryVariant, isQueryQueryVariant, isFindQueryVariant, From d0f7e75ccbcf450680b0b2c7e3c9e8c0fe7d14b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20Beltr=C3=A1n=20Alarc=C3=B3n?= Date: Sun, 21 Mar 2021 12:20:38 +0100 Subject: [PATCH 4/6] refactor: use more realistic filenames for testing --- tests/create-testing-library-rule.test.ts | 30 +++++++++++------------ tests/lib/rules/no-dom-import.test.ts | 8 +++--- tests/lib/test-utils.ts | 3 ++- 3 files changed, 21 insertions(+), 20 deletions(-) diff --git a/tests/create-testing-library-rule.test.ts b/tests/create-testing-library-rule.test.ts index 563fc02a..797a83ee 100644 --- a/tests/create-testing-library-rule.test.ts +++ b/tests/create-testing-library-rule.test.ts @@ -336,7 +336,7 @@ ruleTester.run(RULE_NAME, rule, { 'testing-library/utils-module': 'test-utils', 'testing-library/file-patterns': ['testing-library\\.js'], }, - filename: 'MyComponent.testing-library.js', + filename: 'project/src/MyComponent.testing-library.js', code: ` // case: matching custom settings partially - filename but not module import { render } from 'other-utils' @@ -368,7 +368,7 @@ ruleTester.run(RULE_NAME, rule, { errors: [{ line: 3, column: 7, messageId: 'fakeError' }], }, { - filename: 'MyComponent.spec.js', + filename: 'project/src/MyComponent.spec.js', code: ` // case: import module forced to be reported but from .spec.js named file import { foo } from 'report-me' @@ -376,7 +376,7 @@ ruleTester.run(RULE_NAME, rule, { errors: [{ line: 3, column: 7, messageId: 'fakeError' }], }, { - filename: 'MyComponent.testing-library.js', + filename: 'project/src/MyComponent.testing-library.js', code: ` // case: import module forced to be reported with custom file name import { foo } from 'report-me' @@ -733,7 +733,7 @@ ruleTester.run(RULE_NAME, rule, { errors: [{ line: 3, column: 25, messageId: 'findByError' }], }, { - filename: 'MyComponent.spec.js', + filename: 'project/src/MyComponent.spec.js', code: ` // case: custom "getBy*" query reported without import (aggressive reporting) getByIcon('search') @@ -741,7 +741,7 @@ ruleTester.run(RULE_NAME, rule, { errors: [{ line: 3, column: 7, messageId: 'customQueryError' }], }, { - filename: 'MyComponent.spec.js', + filename: 'project/src/MyComponent.spec.js', code: ` // case: custom "getBy*" query reported without import using within (aggressive reporting) within(container).getByIcon('search') @@ -788,7 +788,7 @@ ruleTester.run(RULE_NAME, rule, { errors: [{ line: 4, column: 7, messageId: 'getByError' }], }, { - filename: 'MyComponent.spec.js', + filename: 'project/src/MyComponent.spec.js', settings: { 'testing-library/utils-module': 'test-utils', }, @@ -800,7 +800,7 @@ ruleTester.run(RULE_NAME, rule, { errors: [{ line: 4, column: 7, messageId: 'queryByError' }], }, { - filename: 'MyComponent.spec.js', + filename: 'project/src/MyComponent.spec.js', settings: { 'testing-library/utils-module': 'test-utils', }, @@ -823,7 +823,7 @@ ruleTester.run(RULE_NAME, rule, { errors: [{ line: 4, column: 7, messageId: 'getByError' }], }, { - filename: 'MyComponent.spec.js', + filename: 'project/src/MyComponent.spec.js', settings: { 'testing-library/utils-module': 'test-utils', }, @@ -835,7 +835,7 @@ ruleTester.run(RULE_NAME, rule, { errors: [{ line: 4, column: 7, messageId: 'queryByError' }], }, { - filename: 'MyComponent.spec.js', + filename: 'project/src/MyComponent.spec.js', settings: { 'testing-library/utils-module': 'test-utils', }, @@ -859,7 +859,7 @@ ruleTester.run(RULE_NAME, rule, { errors: [{ line: 4, column: 7, messageId: 'customQueryError' }], }, { - filename: 'MyComponent.spec.js', + filename: 'project/src/MyComponent.spec.js', settings: { 'testing-library/utils-module': 'test-utils', }, @@ -871,7 +871,7 @@ ruleTester.run(RULE_NAME, rule, { errors: [{ line: 4, column: 7, messageId: 'customQueryError' }], }, { - filename: 'MyComponent.spec.js', + filename: 'project/src/MyComponent.spec.js', settings: { 'testing-library/utils-module': 'test-utils', }, @@ -894,7 +894,7 @@ ruleTester.run(RULE_NAME, rule, { errors: [{ line: 4, column: 7, messageId: 'customQueryError' }], }, { - filename: 'MyComponent.spec.js', + filename: 'project/src/MyComponent.spec.js', settings: { 'testing-library/utils-module': 'test-utils', }, @@ -906,7 +906,7 @@ ruleTester.run(RULE_NAME, rule, { errors: [{ line: 4, column: 7, messageId: 'customQueryError' }], }, { - filename: 'MyComponent.spec.js', + filename: 'project/src/MyComponent.spec.js', settings: { 'testing-library/utils-module': 'test-utils', }, @@ -920,7 +920,7 @@ ruleTester.run(RULE_NAME, rule, { // Test Cases for all settings mixed { - filename: 'MyComponent.custom-suffix.js', + filename: 'project/src/MyComponent.custom-suffix.js', settings: { 'testing-library/custom-renders': ['customRender', 'renderWithRedux'], 'testing-library/utils-module': 'test-utils', @@ -950,7 +950,7 @@ ruleTester.run(RULE_NAME, rule, { 'testing-library/utils-module': 'test-utils', 'testing-library/file-patterns': ['testing-library\\.js'], }, - filename: 'MyComponent.testing-library.js', + filename: 'project/src/MyComponent.testing-library.js', code: ` // case: matching all custom settings import { render } from 'test-utils' diff --git a/tests/lib/rules/no-dom-import.test.ts b/tests/lib/rules/no-dom-import.test.ts index 67e3fa20..74b37056 100644 --- a/tests/lib/rules/no-dom-import.test.ts +++ b/tests/lib/rules/no-dom-import.test.ts @@ -27,7 +27,7 @@ ruleTester.run(RULE_NAME, rule, { }, { code: 'import { fireEvent } from "dom-testing-library"', - filename: 'filename.not-matching.js', + filename: 'project/src/filename.not-matching.js', }, { code: 'import { fireEvent } from "dom-testing-library"', @@ -35,7 +35,7 @@ ruleTester.run(RULE_NAME, rule, { }, { code: 'const { fireEvent } = require("dom-testing-library")', - filename: 'filename.not-matching.js', + filename: 'project/src/filename.not-matching.js', }, { code: 'const { fireEvent } = require("dom-testing-library")', @@ -43,7 +43,7 @@ ruleTester.run(RULE_NAME, rule, { }, { code: 'import { fireEvent } from "@testing-library/dom"', - filename: 'filename.not-matching.js', + filename: 'project/src/filename.not-matching.js', }, { code: 'import { fireEvent } from "@testing-library/dom"', @@ -51,7 +51,7 @@ ruleTester.run(RULE_NAME, rule, { }, { code: 'const { fireEvent } = require("@testing-library/dom")', - filename: 'filename.not-matching.js', + filename: 'project/src/filename.not-matching.js', }, { code: 'const { fireEvent } = require("@testing-library/dom")', diff --git a/tests/lib/test-utils.ts b/tests/lib/test-utils.ts index 88c1b778..b02a3a87 100644 --- a/tests/lib/test-utils.ts +++ b/tests/lib/test-utils.ts @@ -2,7 +2,8 @@ import { resolve } from 'path'; import { TSESLint } from '@typescript-eslint/experimental-utils'; const DEFAULT_TEST_CASE_CONFIG = { - filename: 'MyComponent.test.js', + filename: + '/Users/whoever/project/src/components/MyComponent/MyComponent.test.js', }; class TestingLibraryRuleTester extends TSESLint.RuleTester { From 1d66792c18c0952c395dc2b19001c03befbb2938 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20Beltr=C3=A1n=20Alarc=C3=B3n?= Date: Sun, 21 Mar 2021 12:49:16 +0100 Subject: [PATCH 5/6] refactor: check if file matches with micromatch instead of regexp --- lib/detect-testing-library-utils.ts | 15 ++++++++----- package.json | 4 +++- tests/create-testing-library-rule.test.ts | 24 ++++++++++++--------- tests/lib/rules/no-await-sync-query.test.ts | 4 +++- tests/lib/rules/no-dom-import.test.ts | 16 ++++++++++---- tests/lib/rules/no-manual-cleanup.test.ts | 4 +++- tests/lib/rules/no-node-access.test.ts | 4 +++- 7 files changed, 48 insertions(+), 23 deletions(-) diff --git a/lib/detect-testing-library-utils.ts b/lib/detect-testing-library-utils.ts index 31e0ea91..61e9383e 100644 --- a/lib/detect-testing-library-utils.ts +++ b/lib/detect-testing-library-utils.ts @@ -3,6 +3,8 @@ import { TSESLint, TSESTree, } from '@typescript-eslint/experimental-utils'; +import micromatch from 'micromatch'; + import { getAssertNodeInfo, getDeepestIdentifierNode, @@ -110,7 +112,10 @@ export interface DetectionHelpers { isNodeComingFromTestingLibrary: IsNodeComingFromTestingLibraryFn; } -const DEFAULT_FILENAME_PATTERN = ['^.*\\.(test|spec)\\.[jt]sx?$']; +const DEFAULT_FILE_PATTERNS = [ + '**/__tests__/**/*.[jt]s?(x)', + '**/?(*.)+(spec|test).[jt]s?(x)', +]; const FIRE_EVENT_NAME = 'fireEvent'; const RENDER_NAME = 'render'; @@ -134,7 +139,7 @@ export function detectTestingLibraryUtils< const customModule = context.settings['testing-library/utils-module']; const filePatterns = context.settings['testing-library/file-patterns'] ?? - DEFAULT_FILENAME_PATTERN; + DEFAULT_FILE_PATTERNS; const customRenders = context.settings['testing-library/custom-renders']; /** @@ -244,12 +249,12 @@ export function detectTestingLibraryUtils< }; /** - * Determines whether filename is valid or not for current file - * being analyzed based on "testing-library/file-patterns" setting. + * Determines whether file matches given patterns for being analyzed or not + * based on "testing-library/file-patterns" setting. */ const isMatchingFilename: IsMatchingFilenameFn = () => { const fileName = context.getFilename(); - return filePatterns.some((pattern) => fileName.match(pattern)); + return micromatch.isMatch(fileName, filePatterns); }; /** diff --git a/package.json b/package.json index e98fd824..ffeab315 100644 --- a/package.json +++ b/package.json @@ -53,12 +53,14 @@ "semantic-release": "semantic-release" }, "dependencies": { - "@typescript-eslint/experimental-utils": "^4.18.0" + "@typescript-eslint/experimental-utils": "^4.18.0", + "micromatch": "^4.0.2" }, "devDependencies": { "@commitlint/cli": "^12.0.1", "@commitlint/config-conventional": "^12.0.1", "@types/jest": "^26.0.20", + "@types/micromatch": "^4.0.1", "@typescript-eslint/eslint-plugin": "^4.18.0", "@typescript-eslint/parser": "^4.18.0", "cpy-cli": "^3.1.1", diff --git a/tests/create-testing-library-rule.test.ts b/tests/create-testing-library-rule.test.ts index 797a83ee..64bcf7f4 100644 --- a/tests/create-testing-library-rule.test.ts +++ b/tests/create-testing-library-rule.test.ts @@ -70,7 +70,7 @@ ruleTester.run(RULE_NAME, rule, { import { foo } from 'report-me' `, settings: { - 'testing-library/file-patterns': ['testing-library\\.js'], + 'testing-library/file-patterns': ['**/?(*.)+(not-matching).[jt]s?(x)'], }, }, { @@ -80,7 +80,7 @@ ruleTester.run(RULE_NAME, rule, { const { foo } = require('report-me') `, settings: { - 'testing-library/file-patterns': ['testing-library\\.js'], + 'testing-library/file-patterns': ['**/?(*.)+(not-matching).[jt]s?(x)'], }, }, { @@ -252,7 +252,7 @@ ruleTester.run(RULE_NAME, rule, { }, { settings: { - 'testing-library/file-patterns': ['testing-library\\.js'], + 'testing-library/file-patterns': ['**/?(*.)+(not-matching).[jt]s?(x)'], }, code: ` // case: built-in "getBy*" query not reported because custom filename doesn't match @@ -261,7 +261,7 @@ ruleTester.run(RULE_NAME, rule, { }, { settings: { - 'testing-library/file-patterns': ['testing-library\\.js'], + 'testing-library/file-patterns': ['**/?(*.)+(not-matching).[jt]s?(x)'], }, code: ` // case: built-in "queryBy*" query not reported because custom filename doesn't match @@ -270,7 +270,7 @@ ruleTester.run(RULE_NAME, rule, { }, { settings: { - 'testing-library/file-patterns': ['testing-library\\.js'], + 'testing-library/file-patterns': ['**/?(*.)+(not-matching).[jt]s?(x)'], }, code: ` // case: built-in "findBy*" query not reported because custom filename doesn't match @@ -320,7 +320,7 @@ ruleTester.run(RULE_NAME, rule, { { settings: { 'testing-library/utils-module': 'test-utils', - 'testing-library/file-patterns': ['testing-library\\.js'], + 'testing-library/file-patterns': ['**/?(*.)+(not-matching).[jt]s?(x)'], }, code: ` // case: matching custom settings partially - module but not filename @@ -334,7 +334,7 @@ ruleTester.run(RULE_NAME, rule, { { settings: { 'testing-library/utils-module': 'test-utils', - 'testing-library/file-patterns': ['testing-library\\.js'], + 'testing-library/file-patterns': ['**/?(*.)+(not-matching).[jt]s?(x)'], }, filename: 'project/src/MyComponent.testing-library.js', code: ` @@ -382,7 +382,9 @@ ruleTester.run(RULE_NAME, rule, { import { foo } from 'report-me' `, settings: { - 'testing-library/file-patterns': ['testing-library\\.js'], + 'testing-library/file-patterns': [ + '**/?(*.)+(testing-library).[jt]s?(x)', + ], }, errors: [{ line: 3, column: 7, messageId: 'fakeError' }], }, @@ -924,7 +926,7 @@ ruleTester.run(RULE_NAME, rule, { settings: { 'testing-library/custom-renders': ['customRender', 'renderWithRedux'], 'testing-library/utils-module': 'test-utils', - 'testing-library/file-patterns': ['custom-suffix\\.js'], + 'testing-library/file-patterns': ['**/?(*.)+(custom-suffix).[jt]s?(x)'], }, code: ` // case: all aggressive reporting disabled and filename setup - matching all custom settings @@ -948,7 +950,9 @@ ruleTester.run(RULE_NAME, rule, { { settings: { 'testing-library/utils-module': 'test-utils', - 'testing-library/file-patterns': ['testing-library\\.js'], + 'testing-library/file-patterns': [ + '**/?(*.)+(testing-library|custom-suffix).[jt]s?(x)', + ], }, filename: 'project/src/MyComponent.testing-library.js', code: ` diff --git a/tests/lib/rules/no-await-sync-query.test.ts b/tests/lib/rules/no-await-sync-query.test.ts index db50fd71..b014430d 100644 --- a/tests/lib/rules/no-await-sync-query.test.ts +++ b/tests/lib/rules/no-await-sync-query.test.ts @@ -69,7 +69,9 @@ ruleTester.run(RULE_NAME, rule, { }, // sync query awaited but not matching filename pattern is invalid but not reported { - settings: { 'testing-library/file-patterns': ['nope\\.js'] }, + settings: { + 'testing-library/file-patterns': ['**/?(*.)+(nope).[jt]s?(x)'], + }, code: ` () => { const element = await getByRole('button') diff --git a/tests/lib/rules/no-dom-import.test.ts b/tests/lib/rules/no-dom-import.test.ts index 74b37056..8d8e8ffe 100644 --- a/tests/lib/rules/no-dom-import.test.ts +++ b/tests/lib/rules/no-dom-import.test.ts @@ -31,7 +31,9 @@ ruleTester.run(RULE_NAME, rule, { }, { code: 'import { fireEvent } from "dom-testing-library"', - settings: { 'testing-library/file-patterns': ['nope\\.js'] }, + settings: { + 'testing-library/file-patterns': ['**/?(*.)+(nope).[jt]s?(x)'], + }, }, { code: 'const { fireEvent } = require("dom-testing-library")', @@ -39,7 +41,9 @@ ruleTester.run(RULE_NAME, rule, { }, { code: 'const { fireEvent } = require("dom-testing-library")', - settings: { 'testing-library/file-patterns': ['nope\\.js'] }, + settings: { + 'testing-library/file-patterns': ['**/?(*.)+(nope).[jt]s?(x)'], + }, }, { code: 'import { fireEvent } from "@testing-library/dom"', @@ -47,7 +51,9 @@ ruleTester.run(RULE_NAME, rule, { }, { code: 'import { fireEvent } from "@testing-library/dom"', - settings: { 'testing-library/file-patterns': ['nope\\.js'] }, + settings: { + 'testing-library/file-patterns': ['**/?(*.)+(nope).[jt]s?(x)'], + }, }, { code: 'const { fireEvent } = require("@testing-library/dom")', @@ -55,7 +61,9 @@ ruleTester.run(RULE_NAME, rule, { }, { code: 'const { fireEvent } = require("@testing-library/dom")', - settings: { 'testing-library/file-patterns': ['nope\\.js'] }, + settings: { + 'testing-library/file-patterns': ['**/?(*.)+(nope).[jt]s?(x)'], + }, }, ], invalid: [ diff --git a/tests/lib/rules/no-manual-cleanup.test.ts b/tests/lib/rules/no-manual-cleanup.test.ts index 7a4582b6..6b56683e 100644 --- a/tests/lib/rules/no-manual-cleanup.test.ts +++ b/tests/lib/rules/no-manual-cleanup.test.ts @@ -56,7 +56,9 @@ ruleTester.run(RULE_NAME, rule, { }, { settings: { - 'testing-library/file-patterns': ['testing-library\\.js'], + 'testing-library/file-patterns': [ + '**/?(*.)+(testing-library).[jt]s?(x)', + ], }, code: ` import { render, cleanup } from "${ALL_TESTING_LIBRARIES_WITH_CLEANUP[0]}" diff --git a/tests/lib/rules/no-node-access.test.ts b/tests/lib/rules/no-node-access.test.ts index e143005f..4df15a40 100644 --- a/tests/lib/rules/no-node-access.test.ts +++ b/tests/lib/rules/no-node-access.test.ts @@ -54,7 +54,9 @@ ruleTester.run(RULE_NAME, rule, { } `, settings: { - 'testing-library/file-patterns': ['testing-library\\.js'], + 'testing-library/file-patterns': [ + '**/?(*.)+(testing-library).[jt]s?(x)', + ], }, }, { From 10cf6d73d8bb51db33f0f44c3d4b22a3852b3acd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20Beltr=C3=A1n=20Alarc=C3=B3n?= Date: Sun, 21 Mar 2021 12:53:12 +0100 Subject: [PATCH 6/6] test: add extra test for __tests__ folder --- tests/create-testing-library-rule.test.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/create-testing-library-rule.test.ts b/tests/create-testing-library-rule.test.ts index 64bcf7f4..3be02512 100644 --- a/tests/create-testing-library-rule.test.ts +++ b/tests/create-testing-library-rule.test.ts @@ -375,6 +375,14 @@ ruleTester.run(RULE_NAME, rule, { `, errors: [{ line: 3, column: 7, messageId: 'fakeError' }], }, + { + filename: 'project/src/__tests__/MyComponent.tsx', + code: ` + // case: import module forced to be reported from __tests__ folder without .spec or .test suffix + import { foo } from 'report-me' + `, + errors: [{ line: 3, column: 7, messageId: 'fakeError' }], + }, { filename: 'project/src/MyComponent.testing-library.js', code: `