diff --git a/lib/detect-testing-library-utils.ts b/lib/detect-testing-library-utils.ts index cf5ca51f..31b4c809 100644 --- a/lib/detect-testing-library-utils.ts +++ b/lib/detect-testing-library-utils.ts @@ -2,6 +2,7 @@ import { TSESLint, TSESTree } from '@typescript-eslint/experimental-utils'; export type TestingLibrarySettings = { 'testing-library/module'?: string; + 'testing-library/file-name'?: string; }; export type TestingLibraryContext< @@ -25,9 +26,12 @@ export type EnhancedRuleCreate< export type DetectionHelpers = { getIsTestingLibraryImported: () => boolean; + getIsValidFileName: () => boolean; canReportErrors: () => boolean; }; +const DEFAULT_FILE_NAME_PATTERN = '^.*\\.(test|spec)\\.[jt]sx?$'; + /** * Enhances a given rule `create` with helpers to detect Testing Library utils. */ @@ -45,6 +49,9 @@ export function detectTestingLibraryUtils< // Init options based on shared ESLint settings const customModule = context.settings['testing-library/module']; + const fileNamePattern = + context.settings['testing-library/file-name'] ?? + DEFAULT_FILE_NAME_PATTERN; // Helpers for Testing Library detection. const helpers: DetectionHelpers = { @@ -68,11 +75,21 @@ export function detectTestingLibraryUtils< return isImportingTestingLibraryModule || isImportingCustomModule; }, + /** + * Gets if name of the file being analyzed is valid or not. + * + * This is based on "testing-library/file-name" setting. + */ + getIsValidFileName() { + const fileName = context.getFilename(); + return !!fileName.match(fileNamePattern); + }, + /** * Wraps all conditions that must be met to report rules. */ canReportErrors() { - return this.getIsTestingLibraryImported(); + return this.getIsTestingLibraryImported() && this.getIsValidFileName(); }, }; diff --git a/tests/create-testing-library-rule.test.ts b/tests/create-testing-library-rule.test.ts index 14977c72..1073b370 100644 --- a/tests/create-testing-library-rule.test.ts +++ b/tests/create-testing-library-rule.test.ts @@ -1,11 +1,7 @@ import { createRuleTester } from './lib/test-utils'; import rule, { RULE_NAME } from './fake-rule'; -const ruleTester = createRuleTester({ - ecmaFeatures: { - jsx: true, - }, -}); +const ruleTester = createRuleTester(); ruleTester.run(RULE_NAME, rule, { valid: [ @@ -38,6 +34,15 @@ ruleTester.run(RULE_NAME, rule, { 'testing-library/module': 'test-utils', }, }, + { + code: ` + // case: import module forced to be reported but not matching file name + import { foo } from 'report-me' + `, + settings: { + 'testing-library/file-name': 'testing-library\\.js', + }, + }, ], invalid: [ { @@ -47,6 +52,25 @@ ruleTester.run(RULE_NAME, rule, { `, errors: [{ line: 3, column: 7, messageId: 'fakeError' }], }, + { + filename: 'MyComponent.spec.js', + code: ` + // case: import module forced to be reported but from .spec.js named file + import { foo } from 'report-me' + `, + errors: [{ line: 3, column: 7, messageId: 'fakeError' }], + }, + { + filename: 'MyComponent.testing-library.js', + code: ` + // case: import module forced to be reported with custom file name + import { foo } from 'report-me' + `, + settings: { + 'testing-library/file-name': 'testing-library\\.js', + }, + errors: [{ line: 3, column: 7, messageId: 'fakeError' }], + }, { code: ` // case: render imported from any module by default (aggressive reporting) diff --git a/tests/lib/rules/consistent-data-testid.test.ts b/tests/lib/rules/consistent-data-testid.test.ts index cb7ba92c..dd0892f2 100644 --- a/tests/lib/rules/consistent-data-testid.test.ts +++ b/tests/lib/rules/consistent-data-testid.test.ts @@ -1,11 +1,7 @@ import { createRuleTester } from '../test-utils'; import rule, { RULE_NAME } from '../../../lib/rules/consistent-data-testid'; -const ruleTester = createRuleTester({ - ecmaFeatures: { - jsx: true, - }, -}); +const ruleTester = createRuleTester(); ruleTester.run(RULE_NAME, rule, { valid: [ diff --git a/tests/lib/rules/no-container.test.ts b/tests/lib/rules/no-container.test.ts index a6a6116a..4823e9a6 100644 --- a/tests/lib/rules/no-container.test.ts +++ b/tests/lib/rules/no-container.test.ts @@ -1,11 +1,7 @@ import { createRuleTester } from '../test-utils'; import rule, { RULE_NAME } from '../../../lib/rules/no-container'; -const ruleTester = createRuleTester({ - ecmaFeatures: { - jsx: true, - }, -}); +const ruleTester = createRuleTester(); ruleTester.run(RULE_NAME, rule, { valid: [ diff --git a/tests/lib/rules/no-debug.test.ts b/tests/lib/rules/no-debug.test.ts index ad175bac..3e26b414 100644 --- a/tests/lib/rules/no-debug.test.ts +++ b/tests/lib/rules/no-debug.test.ts @@ -1,11 +1,7 @@ import { createRuleTester } from '../test-utils'; import rule, { RULE_NAME } from '../../../lib/rules/no-debug'; -const ruleTester = createRuleTester({ - ecmaFeatures: { - jsx: true, - }, -}); +const ruleTester = createRuleTester(); ruleTester.run(RULE_NAME, rule, { valid: [ diff --git a/tests/lib/rules/no-multiple-assertions-wait-for.test.ts b/tests/lib/rules/no-multiple-assertions-wait-for.test.ts index 44bef16a..4398662a 100644 --- a/tests/lib/rules/no-multiple-assertions-wait-for.test.ts +++ b/tests/lib/rules/no-multiple-assertions-wait-for.test.ts @@ -3,11 +3,7 @@ import rule, { RULE_NAME, } from '../../../lib/rules/no-multiple-assertions-wait-for'; -const ruleTester = createRuleTester({ - ecmaFeatures: { - jsx: true, - }, -}); +const ruleTester = createRuleTester(); ruleTester.run(RULE_NAME, rule, { valid: [ diff --git a/tests/lib/rules/no-node-access.test.ts b/tests/lib/rules/no-node-access.test.ts index 9c7cbcc4..83dcf04c 100644 --- a/tests/lib/rules/no-node-access.test.ts +++ b/tests/lib/rules/no-node-access.test.ts @@ -1,11 +1,7 @@ import { createRuleTester } from '../test-utils'; import rule, { RULE_NAME } from '../../../lib/rules/no-node-access'; -const ruleTester = createRuleTester({ - ecmaFeatures: { - jsx: true, - }, -}); +const ruleTester = createRuleTester(); ruleTester.run(RULE_NAME, rule, { valid: [ @@ -51,18 +47,16 @@ ruleTester.run(RULE_NAME, rule, { within(signinModal).getByPlaceholderText('Username'); `, }, - /*{ - // TODO: this one should be valid indeed. Rule implementation must be improved - // to track where the nodes are coming from. This one wasn't reported before - // just because this code is not importing TL module, but that's a really - // brittle check. Instead, this one shouldn't be reported since `children` - // it's just a property not related to a node + { code: ` const Component = props => { return