Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: use micromatch for matching files to be reported #296

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 18 additions & 13 deletions lib/detect-testing-library-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import {
TSESLint,
TSESTree,
} from '@typescript-eslint/experimental-utils';
import micromatch from 'micromatch';

import {
getAssertNodeInfo,
getDeepestIdentifierNode,
Expand All @@ -27,7 +29,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[];
};

Expand Down Expand Up @@ -56,7 +58,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;
Expand Down Expand Up @@ -90,7 +92,7 @@ export interface DetectionHelpers {
getTestingLibraryImportName: GetTestingLibraryImportNameFn;
getCustomModuleImportName: GetCustomModuleImportNameFn;
isTestingLibraryImported: IsTestingLibraryImportedFn;
isValidFilename: IsValidFilenameFn;
isMatchingFilename: IsMatchingFilenameFn;
isGetQueryVariant: IsGetQueryVariantFn;
isQueryQueryVariant: IsQueryQueryVariantFn;
isFindQueryVariant: IsFindQueryVariantFn;
Expand All @@ -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';
Expand All @@ -132,9 +137,9 @@ 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'] ??
DEFAULT_FILENAME_PATTERN;
const filePatterns =
context.settings['testing-library/file-patterns'] ??
DEFAULT_FILE_PATTERNS;
const customRenders = context.settings['testing-library/custom-renders'];

/**
Expand Down Expand Up @@ -244,12 +249,12 @@ export function detectTestingLibraryUtils<
};

/**
* Determines whether filename is valid or not for current file
* being analyzed based on "testing-library/filename-pattern" setting.
* Determines whether file matches given patterns for being analyzed or not
* based on "testing-library/file-patterns" setting.
*/
const isValidFilename: IsValidFilenameFn = () => {
const isMatchingFilename: IsMatchingFilenameFn = () => {
const fileName = context.getFilename();
return !!fileName.match(filenamePattern);
return micromatch.isMatch(fileName, filePatterns);
};

/**
Expand Down Expand Up @@ -536,7 +541,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();
};

/**
Expand Down Expand Up @@ -566,7 +571,7 @@ export function detectTestingLibraryUtils<
getTestingLibraryImportName,
getCustomModuleImportName,
isTestingLibraryImported,
isValidFilename,
isMatchingFilename,
isGetQueryVariant,
isQueryQueryVariant,
isFindQueryVariant,
Expand Down
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
62 changes: 37 additions & 25 deletions tests/create-testing-library-rule.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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': ['**/?(*.)+(not-matching).[jt]s?(x)'],
},
},
{
Expand All @@ -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': ['**/?(*.)+(not-matching).[jt]s?(x)'],
},
},
{
Expand Down Expand Up @@ -252,7 +252,7 @@ ruleTester.run(RULE_NAME, rule, {
},
{
settings: {
'testing-library/filename-pattern': '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
Expand All @@ -261,7 +261,7 @@ ruleTester.run(RULE_NAME, rule, {
},
{
settings: {
'testing-library/filename-pattern': '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
Expand All @@ -270,7 +270,7 @@ ruleTester.run(RULE_NAME, rule, {
},
{
settings: {
'testing-library/filename-pattern': '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
Expand Down Expand Up @@ -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': ['**/?(*.)+(not-matching).[jt]s?(x)'],
},
code: `
// case: matching custom settings partially - module but not filename
Expand All @@ -334,9 +334,9 @@ ruleTester.run(RULE_NAME, rule, {
{
settings: {
'testing-library/utils-module': 'test-utils',
'testing-library/filename-pattern': 'testing-library\\.js',
'testing-library/file-patterns': ['**/?(*.)+(not-matching).[jt]s?(x)'],
},
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'
Expand Down Expand Up @@ -368,21 +368,31 @@ 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'
`,
errors: [{ line: 3, column: 7, messageId: 'fakeError' }],
},
{
filename: 'MyComponent.testing-library.js',
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: `
// case: import module forced to be reported with custom file name
import { foo } from 'report-me'
`,
settings: {
'testing-library/filename-pattern': 'testing-library\\.js',
'testing-library/file-patterns': [
'**/?(*.)+(testing-library).[jt]s?(x)',
],
},
errors: [{ line: 3, column: 7, messageId: 'fakeError' }],
},
Expand Down Expand Up @@ -733,15 +743,15 @@ 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')
`,
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')
Expand Down Expand Up @@ -788,7 +798,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',
},
Expand All @@ -800,7 +810,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',
},
Expand All @@ -823,7 +833,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',
},
Expand All @@ -835,7 +845,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',
},
Expand All @@ -859,7 +869,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',
},
Expand All @@ -871,7 +881,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',
},
Expand All @@ -894,7 +904,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',
},
Expand All @@ -906,7 +916,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',
},
Expand All @@ -920,11 +930,11 @@ 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',
'testing-library/filename-pattern': '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
Expand All @@ -948,9 +958,11 @@ 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|custom-suffix).[jt]s?(x)',
],
},
filename: 'MyComponent.testing-library.js',
filename: 'project/src/MyComponent.testing-library.js',
code: `
// case: matching all custom settings
import { render } from 'test-utils'
Expand Down
4 changes: 3 additions & 1 deletion tests/lib/rules/no-await-sync-query.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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/filename-pattern': 'nope\\.js' },
settings: {
'testing-library/file-patterns': ['**/?(*.)+(nope).[jt]s?(x)'],
},
code: `
() => {
const element = await getByRole('button')
Expand Down
24 changes: 16 additions & 8 deletions tests/lib/rules/no-dom-import.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,35 +27,43 @@ 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"',
settings: { 'testing-library/filename-pattern': 'nope\\.js' },
settings: {
'testing-library/file-patterns': ['**/?(*.)+(nope).[jt]s?(x)'],
},
},
{
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")',
settings: { 'testing-library/filename-pattern': 'nope\\.js' },
settings: {
'testing-library/file-patterns': ['**/?(*.)+(nope).[jt]s?(x)'],
},
},
{
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"',
settings: { 'testing-library/filename-pattern': 'nope\\.js' },
settings: {
'testing-library/file-patterns': ['**/?(*.)+(nope).[jt]s?(x)'],
},
},
{
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")',
settings: { 'testing-library/filename-pattern': 'nope\\.js' },
settings: {
'testing-library/file-patterns': ['**/?(*.)+(nope).[jt]s?(x)'],
},
},
],
invalid: [
Expand Down
Loading