From 984f245ff1222231a64f57fb91e376e61e7219fd Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Fri, 30 May 2025 16:10:10 +0000 Subject: [PATCH 1/5] docs: add y-hsgw as a contributor for code, and test (#1014) --- .all-contributorsrc | 10 ++++++++++ README.md | 1 + 2 files changed, 11 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 515ea578..ccff7e6e 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -718,6 +718,16 @@ "test", "doc" ] + }, + { + "login": "y-hsgw", + "name": "Yukihiro Hasegawa", + "avatar_url": "https://avatars.githubusercontent.com/u/49516827?v=4", + "profile": "https://github.com/y-hsgw", + "contributions": [ + "code", + "test" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index 981ae6fc..06a47466 100644 --- a/README.md +++ b/README.md @@ -552,6 +552,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d nostro
nostro

๐Ÿ’ป Daniel Rentz
Daniel Rentz

๐Ÿ“– StyleShit
StyleShit

๐Ÿ’ป โš ๏ธ ๐Ÿ“– + Yukihiro Hasegawa
Yukihiro Hasegawa

๐Ÿ’ป โš ๏ธ From 5b24014a3c236ea127ed2321d4f8e6122955c577 Mon Sep 17 00:00:00 2001 From: Yukihiro Hasegawa <49516827+y-hsgw@users.noreply.github.com> Date: Wed, 4 Jun 2025 14:30:22 +0900 Subject: [PATCH 2/5] refactor: strengthen type safety (#1015) --- .../detect-testing-library-utils.ts | 10 ++-- lib/create-testing-library-rule/index.ts | 19 +++++-- lib/rules/no-node-access.ts | 12 +++-- lib/rules/no-render-in-lifecycle.ts | 2 +- lib/rules/prefer-explicit-assert.ts | 12 +++-- lib/utils/index.ts | 34 +++++++----- .../lib/rules/consistent-data-testid.test.ts | 53 ++++++++++--------- tests/lib/rules/no-unnecessary-act.test.ts | 19 ++++--- tests/lib/rules/prefer-find-by.test.ts | 9 ++-- .../lib/rules/prefer-presence-queries.test.ts | 11 ++-- tests/lib/rules/prefer-query-matchers.test.ts | 9 ++-- tests/lib/rules/prefer-user-event.test.ts | 25 ++++----- 12 files changed, 132 insertions(+), 83 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 001dc532..09688bef 100644 --- a/lib/create-testing-library-rule/detect-testing-library-utils.ts +++ b/lib/create-testing-library-rule/detect-testing-library-utils.ts @@ -802,8 +802,10 @@ export function detectTestingLibraryUtils< } return isNegated - ? ABSENCE_MATCHERS.includes(matcher) - : PRESENCE_MATCHERS.includes(matcher); + ? ABSENCE_MATCHERS.some((absenceMather) => absenceMather === matcher) + : PRESENCE_MATCHERS.some( + (presenceMather) => presenceMather === matcher + ); }; /** @@ -821,8 +823,8 @@ export function detectTestingLibraryUtils< } return isNegated - ? PRESENCE_MATCHERS.includes(matcher) - : ABSENCE_MATCHERS.includes(matcher); + ? PRESENCE_MATCHERS.some((presenceMather) => presenceMather === matcher) + : ABSENCE_MATCHERS.some((absenceMather) => absenceMather === matcher); }; const isMatchingAssert: IsMatchingAssertFn = (node, matcherName) => { diff --git a/lib/create-testing-library-rule/index.ts b/lib/create-testing-library-rule/index.ts index 82e28403..8ce3b334 100644 --- a/lib/create-testing-library-rule/index.ts +++ b/lib/create-testing-library-rule/index.ts @@ -1,6 +1,10 @@ import { ESLintUtils } from '@typescript-eslint/utils'; -import { getDocsUrl, TestingLibraryPluginDocs } from '../utils'; +import { + getDocsUrl, + TestingLibraryPluginDocs, + TestingLibraryPluginRuleModule, +} from '../utils'; import { DetectionOptions, @@ -27,11 +31,20 @@ export const createTestingLibraryRule = < create: EnhancedRuleCreate; detectionOptions?: Partial; } ->) => - ESLintUtils.RuleCreator>(getDocsUrl)({ +>): TestingLibraryPluginRuleModule => { + const rule = ESLintUtils.RuleCreator>( + getDocsUrl + )({ ...remainingConfig, create: detectTestingLibraryUtils( create, detectionOptions ), }); + const { docs } = rule.meta; + if (docs === undefined) { + throw new Error('Rule metadata must contain `docs` property'); + } + + return { ...rule, meta: { ...rule.meta, docs } }; +}; diff --git a/lib/rules/no-node-access.ts b/lib/rules/no-node-access.ts index 0fcd78ac..14b7957d 100644 --- a/lib/rules/no-node-access.ts +++ b/lib/rules/no-node-access.ts @@ -52,11 +52,17 @@ export default createTestingLibraryRule({ return; } + const propertyName = ASTUtils.isIdentifier(node.property) + ? node.property.name + : null; + if ( - ASTUtils.isIdentifier(node.property) && - ALL_RETURNING_NODES.includes(node.property.name) + propertyName && + ALL_RETURNING_NODES.some( + (allReturningNode) => allReturningNode === propertyName + ) ) { - if (allowContainerFirstChild && node.property.name === 'firstChild') { + if (allowContainerFirstChild && propertyName === 'firstChild') { return; } diff --git a/lib/rules/no-render-in-lifecycle.ts b/lib/rules/no-render-in-lifecycle.ts index c15fcd19..1e1aee24 100644 --- a/lib/rules/no-render-in-lifecycle.ts +++ b/lib/rules/no-render-in-lifecycle.ts @@ -68,7 +68,7 @@ export default createTestingLibraryRule({ type: 'object', properties: { allowTestingFrameworkSetupHook: { - enum: TESTING_FRAMEWORK_SETUP_HOOKS, + enum: [...TESTING_FRAMEWORK_SETUP_HOOKS], type: 'string', }, }, diff --git a/lib/rules/prefer-explicit-assert.ts b/lib/rules/prefer-explicit-assert.ts index 7dc78f2c..ed0ffc8c 100644 --- a/lib/rules/prefer-explicit-assert.ts +++ b/lib/rules/prefer-explicit-assert.ts @@ -92,7 +92,7 @@ export default createTestingLibraryRule({ properties: { assertion: { type: 'string', - enum: PRESENCE_MATCHERS, + enum: [...PRESENCE_MATCHERS], }, includeFindQueries: { type: 'boolean' }, }, @@ -182,8 +182,14 @@ export default createTestingLibraryRule({ } const shouldEnforceAssertion = - (!isNegatedMatcher && PRESENCE_MATCHERS.includes(matcher)) || - (isNegatedMatcher && ABSENCE_MATCHERS.includes(matcher)); + (!isNegatedMatcher && + PRESENCE_MATCHERS.some( + (presenceMather) => presenceMather === matcher + )) || + (isNegatedMatcher && + ABSENCE_MATCHERS.some( + (absenceMather) => absenceMather === matcher + )); if (shouldEnforceAssertion && matcher !== assertion) { context.report({ diff --git a/lib/utils/index.ts b/lib/utils/index.ts index cb0e8e03..e43b8102 100644 --- a/lib/utils/index.ts +++ b/lib/utils/index.ts @@ -2,7 +2,10 @@ export * from './compat'; export * from './file-import'; export * from './types'; -const combineQueries = (variants: string[], methods: string[]): string[] => { +const combineQueries = ( + variants: readonly string[], + methods: readonly string[] +): string[] => { const combinedQueries: string[] = []; variants.forEach((variant) => { const variantPrefix = variant.replace('By', ''); @@ -25,14 +28,19 @@ const LIBRARY_MODULES = [ '@testing-library/vue', '@testing-library/svelte', '@marko/testing-library', -]; +] as const; -const SYNC_QUERIES_VARIANTS = ['getBy', 'getAllBy', 'queryBy', 'queryAllBy']; -const ASYNC_QUERIES_VARIANTS = ['findBy', 'findAllBy']; +const SYNC_QUERIES_VARIANTS = [ + 'getBy', + 'getAllBy', + 'queryBy', + 'queryAllBy', +] as const; +const ASYNC_QUERIES_VARIANTS = ['findBy', 'findAllBy'] as const; const ALL_QUERIES_VARIANTS = [ ...SYNC_QUERIES_VARIANTS, ...ASYNC_QUERIES_VARIANTS, -]; +] as const; const ALL_QUERIES_METHODS = [ 'ByLabelText', @@ -43,7 +51,7 @@ const ALL_QUERIES_METHODS = [ 'ByDisplayValue', 'ByRole', 'ByTestId', -]; +] as const; const SYNC_QUERIES_COMBINATIONS = combineQueries( SYNC_QUERIES_VARIANTS, @@ -58,7 +66,7 @@ const ASYNC_QUERIES_COMBINATIONS = combineQueries( const ALL_QUERIES_COMBINATIONS = [ ...SYNC_QUERIES_COMBINATIONS, ...ASYNC_QUERIES_COMBINATIONS, -]; +] as const; const ASYNC_UTILS = ['waitFor', 'waitForElementToBeRemoved'] as const; @@ -73,7 +81,7 @@ const DEBUG_UTILS = [ const EVENTS_SIMULATORS = ['fireEvent', 'userEvent'] as const; -const TESTING_FRAMEWORK_SETUP_HOOKS = ['beforeEach', 'beforeAll']; +const TESTING_FRAMEWORK_SETUP_HOOKS = ['beforeEach', 'beforeAll'] as const; const PROPERTIES_RETURNING_NODES = [ 'activeElement', @@ -93,7 +101,7 @@ const PROPERTIES_RETURNING_NODES = [ 'previousSibling', 'rootNode', 'scripts', -]; +] as const; const METHODS_RETURNING_NODES = [ 'closest', @@ -104,20 +112,20 @@ const METHODS_RETURNING_NODES = [ 'getElementsByTagNameNS', 'querySelector', 'querySelectorAll', -]; +] as const; const ALL_RETURNING_NODES = [ ...PROPERTIES_RETURNING_NODES, ...METHODS_RETURNING_NODES, -]; +] as const; const PRESENCE_MATCHERS = [ 'toBeOnTheScreen', 'toBeInTheDocument', 'toBeTruthy', 'toBeDefined', -]; -const ABSENCE_MATCHERS = ['toBeNull', 'toBeFalsy']; +] as const; +const ABSENCE_MATCHERS = ['toBeNull', 'toBeFalsy'] as const; export { combineQueries, diff --git a/tests/lib/rules/consistent-data-testid.test.ts b/tests/lib/rules/consistent-data-testid.test.ts index b0f5874a..a2cdc46c 100644 --- a/tests/lib/rules/consistent-data-testid.test.ts +++ b/tests/lib/rules/consistent-data-testid.test.ts @@ -1,4 +1,7 @@ -import { type TSESLint } from '@typescript-eslint/utils'; +import { + type InvalidTestCase, + type ValidTestCase, +} from '@typescript-eslint/rule-tester'; import rule, { MessageIds, @@ -9,9 +12,9 @@ import { createRuleTester } from '../test-utils'; const ruleTester = createRuleTester(); -type ValidTestCase = TSESLint.ValidTestCase; -type InvalidTestCase = TSESLint.InvalidTestCase; -type TestCase = InvalidTestCase | ValidTestCase; +type RuleValidTestCase = ValidTestCase; +type RuleInvalidTestCase = InvalidTestCase; +type TestCase = RuleValidTestCase | RuleInvalidTestCase; const disableAggressiveReporting = (array: T[]): T[] => array.map((testCase) => ({ ...testCase, @@ -22,11 +25,11 @@ const disableAggressiveReporting = (array: T[]): T[] => }, })); -const validTestCases: ValidTestCase[] = [ +const validTestCases: RuleValidTestCase[] = [ { code: ` import React from 'react'; - + const TestComponent = props => { return (
@@ -40,7 +43,7 @@ const validTestCases: ValidTestCase[] = [ { code: ` import React from 'react'; - + const TestComponent = props => { return (
@@ -54,7 +57,7 @@ const validTestCases: ValidTestCase[] = [ { code: ` import React from 'react'; - + const TestComponent = props => { return (
@@ -73,7 +76,7 @@ const validTestCases: ValidTestCase[] = [ { code: ` import React from 'react'; - + const TestComponent = props => { return (
@@ -92,7 +95,7 @@ const validTestCases: ValidTestCase[] = [ { code: ` import React from 'react'; - + const TestComponent = props => { return (
@@ -111,7 +114,7 @@ const validTestCases: ValidTestCase[] = [ { code: ` import React from 'react'; - + const TestComponent = props => { return (
@@ -130,7 +133,7 @@ const validTestCases: ValidTestCase[] = [ { code: ` import React from 'react'; - + const TestComponent = props => { return (
@@ -149,7 +152,7 @@ const validTestCases: ValidTestCase[] = [ { code: ` import React from 'react'; - + const TestComponent = props => { return (
@@ -168,7 +171,7 @@ const validTestCases: ValidTestCase[] = [ { code: ` import React from 'react'; - + const TestComponent = props => { return (
@@ -188,7 +191,7 @@ const validTestCases: ValidTestCase[] = [ { code: ` import React from 'react'; - + const TestComponent = props => { const dynamicTestId = 'somethingDynamic'; return ( @@ -205,7 +208,7 @@ const validTestCases: ValidTestCase[] = [ { code: ` import React from 'react'; - + const TestComponent = props => { return (
@@ -224,7 +227,7 @@ const validTestCases: ValidTestCase[] = [ { code: ` import React from 'react'; - + const TestComponent = props => { return (
@@ -244,7 +247,7 @@ const validTestCases: ValidTestCase[] = [ { code: ` import React from 'react'; - + const TestComponent = props => { return (
@@ -262,11 +265,11 @@ const validTestCases: ValidTestCase[] = [ filename: '/my/cool/file/path/[...wildcard].js', }, ]; -const invalidTestCases: InvalidTestCase[] = [ +const invalidTestCases: RuleInvalidTestCase[] = [ { code: ` import React from 'react'; - + const TestComponent = props => { return (
@@ -291,7 +294,7 @@ const invalidTestCases: InvalidTestCase[] = [ { code: ` import React from 'react'; - + const TestComponent = props => { return (
@@ -321,7 +324,7 @@ const invalidTestCases: InvalidTestCase[] = [ { code: ` import React from 'react'; - + const TestComponent = props => { return (
@@ -352,7 +355,7 @@ const invalidTestCases: InvalidTestCase[] = [ { code: ` import React from 'react'; - + const TestComponent = props => { return (
@@ -391,7 +394,7 @@ const invalidTestCases: InvalidTestCase[] = [ { code: ` import React from 'react'; - + const TestComponent = props => { return (
@@ -421,7 +424,7 @@ const invalidTestCases: InvalidTestCase[] = [ { code: ` // test for custom message import React from 'react'; - + const TestComponent = props => { return (
diff --git a/tests/lib/rules/no-unnecessary-act.test.ts b/tests/lib/rules/no-unnecessary-act.test.ts index 3dcac3d8..26305961 100644 --- a/tests/lib/rules/no-unnecessary-act.test.ts +++ b/tests/lib/rules/no-unnecessary-act.test.ts @@ -1,4 +1,7 @@ -import { type TSESLint } from '@typescript-eslint/utils'; +import { + type InvalidTestCase, + type ValidTestCase, +} from '@typescript-eslint/rule-tester'; import rule, { MessageIds, @@ -9,9 +12,9 @@ import { createRuleTester } from '../test-utils'; const ruleTester = createRuleTester(); -type ValidTestCase = TSESLint.ValidTestCase; -type InvalidTestCase = TSESLint.InvalidTestCase; -type TestCase = InvalidTestCase | ValidTestCase; +type RuleValidTestCase = ValidTestCase; +type RuleInvalidTestCase = InvalidTestCase; +type TestCase = RuleInvalidTestCase | RuleValidTestCase; const addOptions = ( array: T[], @@ -37,7 +40,7 @@ const SUPPORTED_TESTING_FRAMEWORKS = [ ['@marko/testing-library', 'Marko TL'], ]; -const validNonStrictTestCases: ValidTestCase[] = [ +const validNonStrictTestCases: RuleValidTestCase[] = [ { code: `// case: RTL act wrapping both RTL and non-RTL calls import { act, render, waitFor } from '@testing-library/react' @@ -62,7 +65,7 @@ const validNonStrictTestCases: ValidTestCase[] = [ }, ]; -const validTestCases: ValidTestCase[] = [ +const validTestCases: RuleValidTestCase[] = [ ...SUPPORTED_TESTING_FRAMEWORKS.map(([testingFramework, shortName]) => ({ code: `// case: ${shortName} act wrapping non-${shortName} calls import { act } from '${testingFramework}' @@ -214,7 +217,7 @@ const validTestCases: ValidTestCase[] = [ })), ]; -const invalidStrictTestCases: InvalidTestCase[] = +const invalidStrictTestCases: RuleInvalidTestCase[] = SUPPORTED_TESTING_FRAMEWORKS.flatMap(([testingFramework, shortName]) => [ { code: `// case: ${shortName} act wrapping both ${shortName} and non-${shortName} calls with strict option @@ -244,7 +247,7 @@ const invalidStrictTestCases: InvalidTestCase[] = }, ]); -const invalidTestCases: InvalidTestCase[] = [ +const invalidTestCases: RuleInvalidTestCase[] = [ ...SUPPORTED_TESTING_FRAMEWORKS.map( ([testingFramework, shortName]) => ({ diff --git a/tests/lib/rules/prefer-find-by.test.ts b/tests/lib/rules/prefer-find-by.test.ts index 3521db71..c9d2c64b 100644 --- a/tests/lib/rules/prefer-find-by.test.ts +++ b/tests/lib/rules/prefer-find-by.test.ts @@ -1,4 +1,7 @@ -import { TSESLint } from '@typescript-eslint/utils'; +import { + type InvalidTestCase, + type ValidTestCase, +} from '@typescript-eslint/rule-tester'; import rule, { RULE_NAME, @@ -26,9 +29,7 @@ function buildFindByMethod(queryMethod: string) { } function createScenario< - T extends - | TSESLint.InvalidTestCase - | TSESLint.ValidTestCase<[]>, + T extends InvalidTestCase | ValidTestCase<[]>, >(callback: (waitMethod: string, queryMethod: string) => T) { return SYNC_QUERIES_COMBINATIONS.map((queryMethod) => callback('waitFor', queryMethod) diff --git a/tests/lib/rules/prefer-presence-queries.test.ts b/tests/lib/rules/prefer-presence-queries.test.ts index 488534c7..f185b00c 100644 --- a/tests/lib/rules/prefer-presence-queries.test.ts +++ b/tests/lib/rules/prefer-presence-queries.test.ts @@ -1,4 +1,7 @@ -import { TSESLint } from '@typescript-eslint/utils'; +import { + type InvalidTestCase, + type ValidTestCase, +} from '@typescript-eslint/rule-tester'; import rule, { RULE_NAME, @@ -17,8 +20,8 @@ const queryAllByQueries = ALL_QUERIES_METHODS.map( (method) => `queryAll${method}` ); -type RuleValidTestCase = TSESLint.ValidTestCase; -type RuleInvalidTestCase = TSESLint.InvalidTestCase; +type RuleValidTestCase = ValidTestCase; +type RuleInvalidTestCase = InvalidTestCase; type AssertionFnParams = { query: string; @@ -921,7 +924,7 @@ ruleTester.run(RULE_NAME, rule, { // submit button exists const submitButton = screen.getByRole('button') fireEvent.click(submitButton) - + // right after clicking submit button it disappears expect(submitButton).not.toBeInTheDocument() `, diff --git a/tests/lib/rules/prefer-query-matchers.test.ts b/tests/lib/rules/prefer-query-matchers.test.ts index 908f1b27..66f03644 100644 --- a/tests/lib/rules/prefer-query-matchers.test.ts +++ b/tests/lib/rules/prefer-query-matchers.test.ts @@ -1,4 +1,7 @@ -import { TSESLint } from '@typescript-eslint/utils'; +import { + type InvalidTestCase, + type ValidTestCase, +} from '@typescript-eslint/rule-tester'; import rule, { RULE_NAME, @@ -17,8 +20,8 @@ const queryAllByQueries = ALL_QUERIES_METHODS.map( (method) => `queryAll${method}` ); -type RuleValidTestCase = TSESLint.ValidTestCase; -type RuleInvalidTestCase = TSESLint.InvalidTestCase; +type RuleValidTestCase = ValidTestCase; +type RuleInvalidTestCase = InvalidTestCase; type AssertionFnParams = { query: string; diff --git a/tests/lib/rules/prefer-user-event.test.ts b/tests/lib/rules/prefer-user-event.test.ts index aae52d9b..299a65dc 100644 --- a/tests/lib/rules/prefer-user-event.test.ts +++ b/tests/lib/rules/prefer-user-event.test.ts @@ -1,4 +1,7 @@ -import { TSESLint } from '@typescript-eslint/utils'; +import { + type InvalidTestCase, + type ValidTestCase, +} from '@typescript-eslint/rule-tester'; import rule, { MAPPING_TO_USER_EVENT, @@ -11,9 +14,7 @@ import { LIBRARY_MODULES } from '../../../lib/utils'; import { createRuleTester } from '../test-utils'; function createScenarioWithImport< - T extends - | TSESLint.InvalidTestCase - | TSESLint.ValidTestCase, + T extends InvalidTestCase | ValidTestCase, >(callback: (libraryModule: string, fireEventMethod: string) => T) { return LIBRARY_MODULES.reduce( (acc: Array, libraryModule) => @@ -69,7 +70,7 @@ ruleTester.run(RULE_NAME, rule, { userEvent.${userEventMethod}(foo) `, })), - ...createScenarioWithImport>( + ...createScenarioWithImport>( (libraryModule: string, fireEventMethod: string) => ({ code: ` import { fireEvent } from '${libraryModule}' @@ -79,7 +80,7 @@ ruleTester.run(RULE_NAME, rule, { options: [{ allowedMethods: [fireEventMethod] }], }) ), - ...createScenarioWithImport>( + ...createScenarioWithImport>( (libraryModule: string, fireEventMethod: string) => ({ code: ` import { fireEvent as fireEventAliased } from '${libraryModule}' @@ -89,7 +90,7 @@ ruleTester.run(RULE_NAME, rule, { options: [{ allowedMethods: [fireEventMethod] }], }) ), - ...createScenarioWithImport>( + ...createScenarioWithImport>( (libraryModule: string, fireEventMethod: string) => ({ code: ` import * as dom from '${libraryModule}' @@ -273,7 +274,7 @@ ruleTester.run(RULE_NAME, rule, { }, ], invalid: [ - ...createScenarioWithImport>( + ...createScenarioWithImport>( (libraryModule: string, fireEventMethod: string) => ({ code: ` import { fireEvent } from '${libraryModule}' @@ -293,7 +294,7 @@ ruleTester.run(RULE_NAME, rule, { ], }) ), - ...createScenarioWithImport>( + ...createScenarioWithImport>( (libraryModule: string, fireEventMethod: string) => ({ code: ` import * as dom from '${libraryModule}' @@ -312,7 +313,7 @@ ruleTester.run(RULE_NAME, rule, { ], }) ), - ...createScenarioWithImport>( + ...createScenarioWithImport>( (libraryModule: string, fireEventMethod: string) => ({ code: ` const { fireEvent } = require('${libraryModule}') @@ -331,7 +332,7 @@ ruleTester.run(RULE_NAME, rule, { ], }) ), - ...createScenarioWithImport>( + ...createScenarioWithImport>( (libraryModule: string, fireEventMethod: string) => ({ code: ` const rtl = require('${libraryModule}') @@ -484,7 +485,7 @@ ruleTester.run(RULE_NAME, rule, { }, code: ` import { fireEvent, createEvent } from 'test-utils' - + fireEvent(node, createEvent('${fireEventMethod}', node)) `, errors: [ From 342f640c9d239ee50251887b8a6522c56cf4d295 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 4 Jun 2025 10:51:04 +0200 Subject: [PATCH 3/5] build(deps-dev): bump eslint-plugin-jest from 28.9.0 to 28.12.0 (#1019) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Mario Beltrรกn --- pnpm-lock.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 72f8abd0..03818277 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -62,7 +62,7 @@ importers: version: 2.31.0(@typescript-eslint/parser@8.15.0(eslint@8.57.1)(typescript@5.7.2))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1) eslint-plugin-jest: specifier: ^28.9.0 - version: 28.9.0(@typescript-eslint/eslint-plugin@8.15.0(@typescript-eslint/parser@8.15.0(eslint@8.57.1)(typescript@5.7.2))(eslint@8.57.1)(typescript@5.7.2))(eslint@8.57.1)(jest@29.7.0(@types/node@22.10.1)(ts-node@10.9.2(@swc/core@1.9.3)(@types/node@22.10.1)(typescript@5.7.2)))(typescript@5.7.2) + version: 28.12.0(@typescript-eslint/eslint-plugin@8.15.0(@typescript-eslint/parser@8.15.0(eslint@8.57.1)(typescript@5.7.2))(eslint@8.57.1)(typescript@5.7.2))(eslint@8.57.1)(jest@29.7.0(@types/node@22.10.1)(ts-node@10.9.2(@swc/core@1.9.3)(@types/node@22.10.1)(typescript@5.7.2)))(typescript@5.7.2) eslint-plugin-jest-formatting: specifier: ^3.1.0 version: 3.1.0(eslint@8.57.1) @@ -1564,8 +1564,8 @@ packages: peerDependencies: eslint: '>=0.8.0' - eslint-plugin-jest@28.9.0: - resolution: {integrity: sha512-rLu1s1Wf96TgUUxSw6loVIkNtUjq1Re7A9QdCCHSohnvXEBAjuL420h0T/fMmkQlNsQP2GhQzEUpYHPfxBkvYQ==} + eslint-plugin-jest@28.12.0: + resolution: {integrity: sha512-J6zmDp8WiQ9tyvYXE+3RFy7/+l4hraWLzmsabYXyehkmmDd36qV4VQFc7XzcsD8C1PTNt646MSx25bO1mdd9Yw==} engines: {node: ^16.10.0 || ^18.12.0 || >=20.0.0} peerDependencies: '@typescript-eslint/eslint-plugin': ^6.0.0 || ^7.0.0 || ^8.0.0 @@ -5427,7 +5427,7 @@ snapshots: dependencies: eslint: 8.57.1 - eslint-plugin-jest@28.9.0(@typescript-eslint/eslint-plugin@8.15.0(@typescript-eslint/parser@8.15.0(eslint@8.57.1)(typescript@5.7.2))(eslint@8.57.1)(typescript@5.7.2))(eslint@8.57.1)(jest@29.7.0(@types/node@22.10.1)(ts-node@10.9.2(@swc/core@1.9.3)(@types/node@22.10.1)(typescript@5.7.2)))(typescript@5.7.2): + eslint-plugin-jest@28.12.0(@typescript-eslint/eslint-plugin@8.15.0(@typescript-eslint/parser@8.15.0(eslint@8.57.1)(typescript@5.7.2))(eslint@8.57.1)(typescript@5.7.2))(eslint@8.57.1)(jest@29.7.0(@types/node@22.10.1)(ts-node@10.9.2(@swc/core@1.9.3)(@types/node@22.10.1)(typescript@5.7.2)))(typescript@5.7.2): dependencies: '@typescript-eslint/utils': 8.15.0(eslint@8.57.1)(typescript@5.7.2) eslint: 8.57.1 From 5eed1ddcc16fc10160bae3d5851d7aebf9167c77 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 4 Jun 2025 11:34:02 +0200 Subject: [PATCH 4/5] build(deps-dev): bump @types/node from 22.10.1 to 22.15.29 (#1016) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pnpm-lock.yaml | 112 ++++++++++++++++++++++++------------------------- 1 file changed, 56 insertions(+), 56 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 03818277..6ef3acc5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -17,7 +17,7 @@ importers: devDependencies: '@commitlint/cli': specifier: ^19.6.0 - version: 19.8.0(@types/node@22.10.1)(typescript@5.7.2) + version: 19.8.0(@types/node@22.15.29)(typescript@5.7.2) '@commitlint/config-conventional': specifier: ^19.6.0 version: 19.8.0 @@ -32,7 +32,7 @@ importers: version: 29.5.14 '@types/node': specifier: ^22.9.3 - version: 22.10.1 + version: 22.15.29 '@typescript-eslint/eslint-plugin': specifier: ^8.15.0 version: 8.15.0(@typescript-eslint/parser@8.15.0(eslint@8.57.1)(typescript@5.7.2))(eslint@8.57.1)(typescript@5.7.2) @@ -62,7 +62,7 @@ importers: version: 2.31.0(@typescript-eslint/parser@8.15.0(eslint@8.57.1)(typescript@5.7.2))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1) eslint-plugin-jest: specifier: ^28.9.0 - version: 28.12.0(@typescript-eslint/eslint-plugin@8.15.0(@typescript-eslint/parser@8.15.0(eslint@8.57.1)(typescript@5.7.2))(eslint@8.57.1)(typescript@5.7.2))(eslint@8.57.1)(jest@29.7.0(@types/node@22.10.1)(ts-node@10.9.2(@swc/core@1.9.3)(@types/node@22.10.1)(typescript@5.7.2)))(typescript@5.7.2) + version: 28.12.0(@typescript-eslint/eslint-plugin@8.15.0(@typescript-eslint/parser@8.15.0(eslint@8.57.1)(typescript@5.7.2))(eslint@8.57.1)(typescript@5.7.2))(eslint@8.57.1)(jest@29.7.0(@types/node@22.15.29)(ts-node@10.9.2(@swc/core@1.9.3)(@types/node@22.15.29)(typescript@5.7.2)))(typescript@5.7.2) eslint-plugin-jest-formatting: specifier: ^3.1.0 version: 3.1.0(eslint@8.57.1) @@ -74,7 +74,7 @@ importers: version: 7.2.1(eslint@8.57.1) eslint-remote-tester: specifier: ^3.0.1 - version: 3.0.1(eslint@8.57.1)(ts-node@10.9.2(@swc/core@1.9.3)(@types/node@22.10.1)(typescript@5.7.2)) + version: 3.0.1(eslint@8.57.1)(ts-node@10.9.2(@swc/core@1.9.3)(@types/node@22.15.29)(typescript@5.7.2)) eslint-remote-tester-repositories: specifier: ^1.0.1 version: 1.0.1 @@ -86,7 +86,7 @@ importers: version: 3.0.1 jest: specifier: ^29.7.0 - version: 29.7.0(@types/node@22.10.1)(ts-node@10.9.2(@swc/core@1.9.3)(@types/node@22.10.1)(typescript@5.7.2)) + version: 29.7.0(@types/node@22.15.29)(ts-node@10.9.2(@swc/core@1.9.3)(@types/node@22.15.29)(typescript@5.7.2)) lint-staged: specifier: ^15.2.10 version: 15.4.3 @@ -101,7 +101,7 @@ importers: version: 7.7.1 ts-node: specifier: ^10.9.2 - version: 10.9.2(@swc/core@1.9.3)(@types/node@22.10.1)(typescript@5.7.2) + version: 10.9.2(@swc/core@1.9.3)(@types/node@22.15.29)(typescript@5.7.2) typescript: specifier: ^5.7.2 version: 5.7.2 @@ -777,8 +777,8 @@ packages: '@types/json5@0.0.29': resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} - '@types/node@22.10.1': - resolution: {integrity: sha512-qKgsUwfHZV2WCWLAnVP1JqnpE6Im6h3Y0+fYgMTasNQ7V++CBX5OT1as0g0f+OyubbFqhf6XVNIsmN4IIhEgGQ==} + '@types/node@22.15.29': + resolution: {integrity: sha512-LNdjOkUDlU1RZb8e1kOIUpN1qQUlzGkEtbVNo53vbrwDg5om6oduhm4SiUaPW5ASTXhAiP0jInWG8Qx9fVlOeQ==} '@types/normalize-package-data@2.4.4': resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} @@ -3470,8 +3470,8 @@ packages: unbox-primitive@1.0.2: resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} - undici-types@6.20.0: - resolution: {integrity: sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==} + undici-types@6.21.0: + resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} unicode-emoji-modifier-base@1.0.0: resolution: {integrity: sha512-yLSH4py7oFH3oG/9K+XWrz1pSi3dfUrWEnInbxMfArOfc1+33BlGPQtLsOYwvdMy11AwUBetYuaRxSPqgkq+8g==} @@ -3861,11 +3861,11 @@ snapshots: '@colors/colors@1.5.0': optional: true - '@commitlint/cli@19.8.0(@types/node@22.10.1)(typescript@5.7.2)': + '@commitlint/cli@19.8.0(@types/node@22.15.29)(typescript@5.7.2)': dependencies: '@commitlint/format': 19.8.0 '@commitlint/lint': 19.8.0 - '@commitlint/load': 19.8.0(@types/node@22.10.1)(typescript@5.7.2) + '@commitlint/load': 19.8.0(@types/node@22.15.29)(typescript@5.7.2) '@commitlint/read': 19.8.0 '@commitlint/types': 19.8.0 tinyexec: 0.3.2 @@ -3912,7 +3912,7 @@ snapshots: '@commitlint/rules': 19.8.0 '@commitlint/types': 19.8.0 - '@commitlint/load@19.8.0(@types/node@22.10.1)(typescript@5.7.2)': + '@commitlint/load@19.8.0(@types/node@22.15.29)(typescript@5.7.2)': dependencies: '@commitlint/config-validator': 19.8.0 '@commitlint/execute-rule': 19.8.0 @@ -3920,7 +3920,7 @@ snapshots: '@commitlint/types': 19.8.0 chalk: 5.4.1 cosmiconfig: 9.0.0(typescript@5.7.2) - cosmiconfig-typescript-loader: 6.1.0(@types/node@22.10.1)(cosmiconfig@9.0.0(typescript@5.7.2))(typescript@5.7.2) + cosmiconfig-typescript-loader: 6.1.0(@types/node@22.15.29)(cosmiconfig@9.0.0(typescript@5.7.2))(typescript@5.7.2) lodash.isplainobject: 4.0.6 lodash.merge: 4.6.2 lodash.uniq: 4.5.0 @@ -4023,27 +4023,27 @@ snapshots: '@jest/console@29.7.0': dependencies: '@jest/types': 29.6.3 - '@types/node': 22.10.1 + '@types/node': 22.15.29 chalk: 4.1.2 jest-message-util: 29.7.0 jest-util: 29.7.0 slash: 3.0.0 - '@jest/core@29.7.0(ts-node@10.9.2(@swc/core@1.9.3)(@types/node@22.10.1)(typescript@5.7.2))': + '@jest/core@29.7.0(ts-node@10.9.2(@swc/core@1.9.3)(@types/node@22.15.29)(typescript@5.7.2))': dependencies: '@jest/console': 29.7.0 '@jest/reporters': 29.7.0 '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 22.10.1 + '@types/node': 22.15.29 ansi-escapes: 4.3.2 chalk: 4.1.2 ci-info: 3.9.0 exit: 0.1.2 graceful-fs: 4.2.11 jest-changed-files: 29.7.0 - jest-config: 29.7.0(@types/node@22.10.1)(ts-node@10.9.2(@swc/core@1.9.3)(@types/node@22.10.1)(typescript@5.7.2)) + jest-config: 29.7.0(@types/node@22.15.29)(ts-node@10.9.2(@swc/core@1.9.3)(@types/node@22.15.29)(typescript@5.7.2)) jest-haste-map: 29.7.0 jest-message-util: 29.7.0 jest-regex-util: 29.6.3 @@ -4072,7 +4072,7 @@ snapshots: dependencies: '@jest/fake-timers': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 22.10.1 + '@types/node': 22.15.29 jest-mock: 29.7.0 '@jest/expect-utils@29.7.0': @@ -4090,7 +4090,7 @@ snapshots: dependencies: '@jest/types': 29.6.3 '@sinonjs/fake-timers': 10.3.0 - '@types/node': 22.10.1 + '@types/node': 22.15.29 jest-message-util: 29.7.0 jest-mock: 29.7.0 jest-util: 29.7.0 @@ -4112,7 +4112,7 @@ snapshots: '@jest/transform': 29.7.0 '@jest/types': 29.6.3 '@jridgewell/trace-mapping': 0.3.25 - '@types/node': 22.10.1 + '@types/node': 22.15.29 chalk: 4.1.2 collect-v8-coverage: 1.0.2 exit: 0.1.2 @@ -4182,7 +4182,7 @@ snapshots: '@jest/schemas': 29.6.3 '@types/istanbul-lib-coverage': 2.0.6 '@types/istanbul-reports': 3.0.4 - '@types/node': 22.10.1 + '@types/node': 22.15.29 '@types/yargs': 17.0.33 chalk: 4.1.2 @@ -4488,11 +4488,11 @@ snapshots: '@types/conventional-commits-parser@5.0.1': dependencies: - '@types/node': 22.10.1 + '@types/node': 22.15.29 '@types/graceful-fs@4.1.9': dependencies: - '@types/node': 22.10.1 + '@types/node': 22.15.29 '@types/istanbul-lib-coverage@2.0.6': {} @@ -4513,9 +4513,9 @@ snapshots: '@types/json5@0.0.29': {} - '@types/node@22.10.1': + '@types/node@22.15.29': dependencies: - undici-types: 6.20.0 + undici-types: 6.21.0 '@types/normalize-package-data@2.4.4': {} @@ -5066,9 +5066,9 @@ snapshots: core-util-is@1.0.3: {} - cosmiconfig-typescript-loader@6.1.0(@types/node@22.10.1)(cosmiconfig@9.0.0(typescript@5.7.2))(typescript@5.7.2): + cosmiconfig-typescript-loader@6.1.0(@types/node@22.15.29)(cosmiconfig@9.0.0(typescript@5.7.2))(typescript@5.7.2): dependencies: - '@types/node': 22.10.1 + '@types/node': 22.15.29 cosmiconfig: 9.0.0(typescript@5.7.2) jiti: 2.4.2 typescript: 5.7.2 @@ -5091,13 +5091,13 @@ snapshots: optionalDependencies: typescript: 5.7.2 - create-jest@29.7.0(@types/node@22.10.1)(ts-node@10.9.2(@swc/core@1.9.3)(@types/node@22.10.1)(typescript@5.7.2)): + create-jest@29.7.0(@types/node@22.15.29)(ts-node@10.9.2(@swc/core@1.9.3)(@types/node@22.15.29)(typescript@5.7.2)): dependencies: '@jest/types': 29.6.3 chalk: 4.1.2 exit: 0.1.2 graceful-fs: 4.2.11 - jest-config: 29.7.0(@types/node@22.10.1)(ts-node@10.9.2(@swc/core@1.9.3)(@types/node@22.10.1)(typescript@5.7.2)) + jest-config: 29.7.0(@types/node@22.15.29)(ts-node@10.9.2(@swc/core@1.9.3)(@types/node@22.15.29)(typescript@5.7.2)) jest-util: 29.7.0 prompts: 2.4.2 transitivePeerDependencies: @@ -5427,13 +5427,13 @@ snapshots: dependencies: eslint: 8.57.1 - eslint-plugin-jest@28.12.0(@typescript-eslint/eslint-plugin@8.15.0(@typescript-eslint/parser@8.15.0(eslint@8.57.1)(typescript@5.7.2))(eslint@8.57.1)(typescript@5.7.2))(eslint@8.57.1)(jest@29.7.0(@types/node@22.10.1)(ts-node@10.9.2(@swc/core@1.9.3)(@types/node@22.10.1)(typescript@5.7.2)))(typescript@5.7.2): + eslint-plugin-jest@28.12.0(@typescript-eslint/eslint-plugin@8.15.0(@typescript-eslint/parser@8.15.0(eslint@8.57.1)(typescript@5.7.2))(eslint@8.57.1)(typescript@5.7.2))(eslint@8.57.1)(jest@29.7.0(@types/node@22.15.29)(ts-node@10.9.2(@swc/core@1.9.3)(@types/node@22.15.29)(typescript@5.7.2)))(typescript@5.7.2): dependencies: '@typescript-eslint/utils': 8.15.0(eslint@8.57.1)(typescript@5.7.2) eslint: 8.57.1 optionalDependencies: '@typescript-eslint/eslint-plugin': 8.15.0(@typescript-eslint/parser@8.15.0(eslint@8.57.1)(typescript@5.7.2))(eslint@8.57.1)(typescript@5.7.2) - jest: 29.7.0(@types/node@22.10.1)(ts-node@10.9.2(@swc/core@1.9.3)(@types/node@22.10.1)(typescript@5.7.2)) + jest: 29.7.0(@types/node@22.15.29)(ts-node@10.9.2(@swc/core@1.9.3)(@types/node@22.15.29)(typescript@5.7.2)) transitivePeerDependencies: - supports-color - typescript @@ -5455,7 +5455,7 @@ snapshots: eslint-remote-tester-repositories@1.0.1: {} - eslint-remote-tester@3.0.1(eslint@8.57.1)(ts-node@10.9.2(@swc/core@1.9.3)(@types/node@22.10.1)(typescript@5.7.2)): + eslint-remote-tester@3.0.1(eslint@8.57.1)(ts-node@10.9.2(@swc/core@1.9.3)(@types/node@22.15.29)(typescript@5.7.2)): dependencies: '@babel/code-frame': 7.26.2 JSONStream: 1.3.5 @@ -5466,7 +5466,7 @@ snapshots: react: 17.0.2 simple-git: 3.27.0 optionalDependencies: - ts-node: 10.9.2(@swc/core@1.9.3)(@types/node@22.10.1)(typescript@5.7.2) + ts-node: 10.9.2(@swc/core@1.9.3)(@types/node@22.15.29)(typescript@5.7.2) transitivePeerDependencies: - '@types/react' - bufferutil @@ -6184,7 +6184,7 @@ snapshots: '@jest/expect': 29.7.0 '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 22.10.1 + '@types/node': 22.15.29 chalk: 4.1.2 co: 4.6.0 dedent: 1.5.3 @@ -6204,16 +6204,16 @@ snapshots: - babel-plugin-macros - supports-color - jest-cli@29.7.0(@types/node@22.10.1)(ts-node@10.9.2(@swc/core@1.9.3)(@types/node@22.10.1)(typescript@5.7.2)): + jest-cli@29.7.0(@types/node@22.15.29)(ts-node@10.9.2(@swc/core@1.9.3)(@types/node@22.15.29)(typescript@5.7.2)): dependencies: - '@jest/core': 29.7.0(ts-node@10.9.2(@swc/core@1.9.3)(@types/node@22.10.1)(typescript@5.7.2)) + '@jest/core': 29.7.0(ts-node@10.9.2(@swc/core@1.9.3)(@types/node@22.15.29)(typescript@5.7.2)) '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 chalk: 4.1.2 - create-jest: 29.7.0(@types/node@22.10.1)(ts-node@10.9.2(@swc/core@1.9.3)(@types/node@22.10.1)(typescript@5.7.2)) + create-jest: 29.7.0(@types/node@22.15.29)(ts-node@10.9.2(@swc/core@1.9.3)(@types/node@22.15.29)(typescript@5.7.2)) exit: 0.1.2 import-local: 3.2.0 - jest-config: 29.7.0(@types/node@22.10.1)(ts-node@10.9.2(@swc/core@1.9.3)(@types/node@22.10.1)(typescript@5.7.2)) + jest-config: 29.7.0(@types/node@22.15.29)(ts-node@10.9.2(@swc/core@1.9.3)(@types/node@22.15.29)(typescript@5.7.2)) jest-util: 29.7.0 jest-validate: 29.7.0 yargs: 17.7.2 @@ -6223,7 +6223,7 @@ snapshots: - supports-color - ts-node - jest-config@29.7.0(@types/node@22.10.1)(ts-node@10.9.2(@swc/core@1.9.3)(@types/node@22.10.1)(typescript@5.7.2)): + jest-config@29.7.0(@types/node@22.15.29)(ts-node@10.9.2(@swc/core@1.9.3)(@types/node@22.15.29)(typescript@5.7.2)): dependencies: '@babel/core': 7.26.0 '@jest/test-sequencer': 29.7.0 @@ -6248,8 +6248,8 @@ snapshots: slash: 3.0.0 strip-json-comments: 3.1.1 optionalDependencies: - '@types/node': 22.10.1 - ts-node: 10.9.2(@swc/core@1.9.3)(@types/node@22.10.1)(typescript@5.7.2) + '@types/node': 22.15.29 + ts-node: 10.9.2(@swc/core@1.9.3)(@types/node@22.15.29)(typescript@5.7.2) transitivePeerDependencies: - babel-plugin-macros - supports-color @@ -6278,7 +6278,7 @@ snapshots: '@jest/environment': 29.7.0 '@jest/fake-timers': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 22.10.1 + '@types/node': 22.15.29 jest-mock: 29.7.0 jest-util: 29.7.0 @@ -6288,7 +6288,7 @@ snapshots: dependencies: '@jest/types': 29.6.3 '@types/graceful-fs': 4.1.9 - '@types/node': 22.10.1 + '@types/node': 22.15.29 anymatch: 3.1.3 fb-watchman: 2.0.2 graceful-fs: 4.2.11 @@ -6327,7 +6327,7 @@ snapshots: jest-mock@29.7.0: dependencies: '@jest/types': 29.6.3 - '@types/node': 22.10.1 + '@types/node': 22.15.29 jest-util: 29.7.0 jest-pnp-resolver@1.2.3(jest-resolve@29.7.0): @@ -6362,7 +6362,7 @@ snapshots: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 22.10.1 + '@types/node': 22.15.29 chalk: 4.1.2 emittery: 0.13.1 graceful-fs: 4.2.11 @@ -6390,7 +6390,7 @@ snapshots: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 22.10.1 + '@types/node': 22.15.29 chalk: 4.1.2 cjs-module-lexer: 1.4.1 collect-v8-coverage: 1.0.2 @@ -6436,7 +6436,7 @@ snapshots: jest-util@29.7.0: dependencies: '@jest/types': 29.6.3 - '@types/node': 22.10.1 + '@types/node': 22.15.29 chalk: 4.1.2 ci-info: 3.9.0 graceful-fs: 4.2.11 @@ -6455,7 +6455,7 @@ snapshots: dependencies: '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 22.10.1 + '@types/node': 22.15.29 ansi-escapes: 4.3.2 chalk: 4.1.2 emittery: 0.13.1 @@ -6464,17 +6464,17 @@ snapshots: jest-worker@29.7.0: dependencies: - '@types/node': 22.10.1 + '@types/node': 22.15.29 jest-util: 29.7.0 merge-stream: 2.0.0 supports-color: 8.1.1 - jest@29.7.0(@types/node@22.10.1)(ts-node@10.9.2(@swc/core@1.9.3)(@types/node@22.10.1)(typescript@5.7.2)): + jest@29.7.0(@types/node@22.15.29)(ts-node@10.9.2(@swc/core@1.9.3)(@types/node@22.15.29)(typescript@5.7.2)): dependencies: - '@jest/core': 29.7.0(ts-node@10.9.2(@swc/core@1.9.3)(@types/node@22.10.1)(typescript@5.7.2)) + '@jest/core': 29.7.0(ts-node@10.9.2(@swc/core@1.9.3)(@types/node@22.15.29)(typescript@5.7.2)) '@jest/types': 29.6.3 import-local: 3.2.0 - jest-cli: 29.7.0(@types/node@22.10.1)(ts-node@10.9.2(@swc/core@1.9.3)(@types/node@22.10.1)(typescript@5.7.2)) + jest-cli: 29.7.0(@types/node@22.15.29)(ts-node@10.9.2(@swc/core@1.9.3)(@types/node@22.15.29)(typescript@5.7.2)) transitivePeerDependencies: - '@types/node' - babel-plugin-macros @@ -7403,14 +7403,14 @@ snapshots: dependencies: typescript: 5.7.2 - ts-node@10.9.2(@swc/core@1.9.3)(@types/node@22.10.1)(typescript@5.7.2): + ts-node@10.9.2(@swc/core@1.9.3)(@types/node@22.15.29)(typescript@5.7.2): dependencies: '@cspotcode/source-map-support': 0.8.1 '@tsconfig/node10': 1.0.11 '@tsconfig/node12': 1.0.11 '@tsconfig/node14': 1.0.3 '@tsconfig/node16': 1.0.4 - '@types/node': 22.10.1 + '@types/node': 22.15.29 acorn: 8.14.0 acorn-walk: 8.3.4 arg: 4.1.3 @@ -7504,7 +7504,7 @@ snapshots: has-symbols: 1.0.3 which-boxed-primitive: 1.0.2 - undici-types@6.20.0: {} + undici-types@6.21.0: {} unicode-emoji-modifier-base@1.0.0: {} From 4ab50a05941eb597dc64b41f323299b53f6487fc Mon Sep 17 00:00:00 2001 From: Yukihiro Hasegawa <49516827+y-hsgw@users.noreply.github.com> Date: Thu, 5 Jun 2025 14:34:55 +0900 Subject: [PATCH 5/5] feat(prefer-presence-queries): add autofix support (#1020) Closes #916 --- README.md | 2 +- docs/rules/prefer-presence-queries.md | 2 + lib/rules/prefer-presence-queries.ts | 18 +++- .../lib/rules/prefer-presence-queries.test.ts | 96 ++++++++++++++++++- 4 files changed, 113 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 06a47466..18e61661 100644 --- a/README.md +++ b/README.md @@ -346,7 +346,7 @@ module.exports = [ | [prefer-explicit-assert](docs/rules/prefer-explicit-assert.md) | Suggest using explicit assertions rather than standalone queries | | | | | [prefer-find-by](docs/rules/prefer-find-by.md) | Suggest using `find(All)By*` query instead of `waitFor` + `get(All)By*` to wait for elements | ![badge-angular][] ![badge-dom][] ![badge-marko][] ![badge-react][] ![badge-svelte][] ![badge-vue][] | | ๐Ÿ”ง | | [prefer-implicit-assert](docs/rules/prefer-implicit-assert.md) | Suggest using implicit assertions for getBy* & findBy* queries | | | | -| [prefer-presence-queries](docs/rules/prefer-presence-queries.md) | Ensure appropriate `get*`/`query*` queries are used with their respective matchers | ![badge-angular][] ![badge-dom][] ![badge-marko][] ![badge-react][] ![badge-svelte][] ![badge-vue][] | | | +| [prefer-presence-queries](docs/rules/prefer-presence-queries.md) | Ensure appropriate `get*`/`query*` queries are used with their respective matchers | ![badge-angular][] ![badge-dom][] ![badge-marko][] ![badge-react][] ![badge-svelte][] ![badge-vue][] | | ๐Ÿ”ง | | [prefer-query-by-disappearance](docs/rules/prefer-query-by-disappearance.md) | Suggest using `queryBy*` queries when waiting for disappearance | ![badge-angular][] ![badge-dom][] ![badge-marko][] ![badge-react][] ![badge-svelte][] ![badge-vue][] | | | | [prefer-query-matchers](docs/rules/prefer-query-matchers.md) | Ensure the configured `get*`/`query*` query is used with the corresponding matchers | | | | | [prefer-screen-queries](docs/rules/prefer-screen-queries.md) | Suggest using `screen` while querying | ![badge-angular][] ![badge-dom][] ![badge-marko][] ![badge-react][] ![badge-svelte][] ![badge-vue][] | | | diff --git a/docs/rules/prefer-presence-queries.md b/docs/rules/prefer-presence-queries.md index 2bb3174a..b7e40121 100644 --- a/docs/rules/prefer-presence-queries.md +++ b/docs/rules/prefer-presence-queries.md @@ -2,6 +2,8 @@ ๐Ÿ’ผ This rule is enabled in the following configs: `angular`, `dom`, `marko`, `react`, `svelte`, `vue`. +๐Ÿ”ง This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix). + The (DOM) Testing Library allows to query DOM elements using different types of queries such as `get*` and `query*`. Using `get*` throws an error in case the element is not found, while `query*` returns null instead of throwing (or empty array for `queryAllBy*` ones). These differences are useful in some situations: diff --git a/lib/rules/prefer-presence-queries.ts b/lib/rules/prefer-presence-queries.ts index a810f869..504633c3 100644 --- a/lib/rules/prefer-presence-queries.ts +++ b/lib/rules/prefer-presence-queries.ts @@ -33,6 +33,7 @@ export default createTestingLibraryRule({ wrongAbsenceQuery: 'Use `queryBy*` queries rather than `getBy*` for checking element is NOT present', }, + fixable: 'code', schema: [ { type: 'object', @@ -62,7 +63,7 @@ export default createTestingLibraryRule({ const expectCallNode = findClosestCallNode(node, 'expect'); const withinCallNode = findClosestCallNode(node, 'within'); - if (!expectCallNode || !isMemberExpression(expectCallNode.parent)) { + if (!isMemberExpression(expectCallNode?.parent)) { return; } @@ -86,14 +87,25 @@ export default createTestingLibraryRule({ (withinCallNode || isPresenceAssert) && !isPresenceQuery ) { - context.report({ node, messageId: 'wrongPresenceQuery' }); + const newQueryName = node.name.replace(/^query/, 'get'); + + context.report({ + node, + messageId: 'wrongPresenceQuery', + fix: (fixer) => fixer.replaceText(node, newQueryName), + }); } else if ( !withinCallNode && absence && isAbsenceAssert && isPresenceQuery ) { - context.report({ node, messageId: 'wrongAbsenceQuery' }); + const newQueryName = node.name.replace(/^get/, 'query'); + context.report({ + node, + messageId: 'wrongAbsenceQuery', + fix: (fixer) => fixer.replaceText(node, newQueryName), + }); } }, }; diff --git a/tests/lib/rules/prefer-presence-queries.test.ts b/tests/lib/rules/prefer-presence-queries.test.ts index f185b00c..72cbe4d5 100644 --- a/tests/lib/rules/prefer-presence-queries.test.ts +++ b/tests/lib/rules/prefer-presence-queries.test.ts @@ -82,6 +82,15 @@ const getDisabledValidAssertion = ({ }; }; +const toggleQueryPrefix = (query: string): string => { + if (query.startsWith('get')) return query.replace(/^get/, 'query'); + if (query.startsWith('query')) return query.replace(/^query/, 'get'); + return query; +}; + +const applyScreenPrefix = (query: string, shouldUseScreen: boolean): string => + shouldUseScreen ? `screen.${query}` : query; + const getInvalidAssertions = ({ query, matcher, @@ -89,12 +98,18 @@ const getInvalidAssertions = ({ shouldUseScreen = false, assertionType, }: AssertionFnParams): RuleInvalidTestCase[] => { - const finalQuery = shouldUseScreen ? `screen.${query}` : query; + const finalQuery = applyScreenPrefix(query, shouldUseScreen); const code = `expect(${finalQuery}('Hello'))${matcher}`; + + const outputQuery = toggleQueryPrefix(query); + const finalOutputQuery = applyScreenPrefix(outputQuery, shouldUseScreen); + const output = `expect(${finalOutputQuery}('Hello'))${matcher}`; + return [ { code, errors: [{ messageId, line: 1, column: shouldUseScreen ? 15 : 8 }], + output, }, { code, @@ -105,6 +120,7 @@ const getInvalidAssertions = ({ }, ], errors: [{ messageId, line: 1, column: shouldUseScreen ? 15 : 8 }], + output, }, ]; }; @@ -1307,18 +1323,24 @@ ruleTester.run(RULE_NAME, rule, { { code: 'expect(screen.getAllByText("button")[1]).not.toBeInTheDocument()', errors: [{ messageId: 'wrongAbsenceQuery', line: 1, column: 15 }], + output: + 'expect(screen.queryAllByText("button")[1]).not.toBeInTheDocument()', }, { code: 'expect(screen.getAllByText("button")[1]).not.toBeOnTheScreen()', errors: [{ messageId: 'wrongAbsenceQuery', line: 1, column: 15 }], + output: + 'expect(screen.queryAllByText("button")[1]).not.toBeOnTheScreen()', }, { code: 'expect(screen.queryAllByText("button")[1]).toBeInTheDocument()', errors: [{ messageId: 'wrongPresenceQuery', line: 1, column: 15 }], + output: 'expect(screen.getAllByText("button")[1]).toBeInTheDocument()', }, { code: 'expect(screen.queryAllByText("button")[1]).toBeOnTheScreen()', errors: [{ messageId: 'wrongPresenceQuery', line: 1, column: 15 }], + output: 'expect(screen.getAllByText("button")[1]).toBeOnTheScreen()', }, { code: ` @@ -1326,6 +1348,10 @@ ruleTester.run(RULE_NAME, rule, { expect(queryByCustomQuery("button")).toBeInTheDocument() `, errors: [{ messageId: 'wrongPresenceQuery', line: 3, column: 16 }], + output: ` + // case: asserting presence incorrectly with custom queryBy* query + expect(getByCustomQuery("button")).toBeInTheDocument() + `, }, { code: ` @@ -1333,6 +1359,10 @@ ruleTester.run(RULE_NAME, rule, { expect(queryByCustomQuery("button")).toBeOnTheScreen() `, errors: [{ messageId: 'wrongPresenceQuery', line: 3, column: 16 }], + output: ` + // case: asserting presence incorrectly with custom queryBy* query + expect(getByCustomQuery("button")).toBeOnTheScreen() + `, }, { code: ` @@ -1340,6 +1370,10 @@ ruleTester.run(RULE_NAME, rule, { expect(getByCustomQuery("button")).not.toBeInTheDocument() `, errors: [{ messageId: 'wrongAbsenceQuery', line: 3, column: 16 }], + output: ` + // case: asserting absence incorrectly with custom getBy* query + expect(queryByCustomQuery("button")).not.toBeInTheDocument() + `, }, { code: ` @@ -1347,6 +1381,10 @@ ruleTester.run(RULE_NAME, rule, { expect(getByCustomQuery("button")).not.toBeOnTheScreen() `, errors: [{ messageId: 'wrongAbsenceQuery', line: 3, column: 16 }], + output: ` + // case: asserting absence incorrectly with custom getBy* query + expect(queryByCustomQuery("button")).not.toBeOnTheScreen() + `, }, { settings: { @@ -1358,6 +1396,11 @@ ruleTester.run(RULE_NAME, rule, { expect(queryByRole("button")).toBeInTheDocument() `, errors: [{ line: 4, column: 14, messageId: 'wrongPresenceQuery' }], + output: ` + // case: asserting presence incorrectly importing custom module + import 'test-utils' + expect(getByRole("button")).toBeInTheDocument() + `, }, { settings: { @@ -1369,6 +1412,11 @@ ruleTester.run(RULE_NAME, rule, { expect(queryByRole("button")).toBeOnTheScreen() `, errors: [{ line: 4, column: 14, messageId: 'wrongPresenceQuery' }], + output: ` + // case: asserting presence incorrectly importing custom module + import 'test-utils' + expect(getByRole("button")).toBeOnTheScreen() + `, }, { settings: { @@ -1380,6 +1428,11 @@ ruleTester.run(RULE_NAME, rule, { expect(getByRole("button")).not.toBeInTheDocument() `, errors: [{ line: 4, column: 14, messageId: 'wrongAbsenceQuery' }], + output: ` + // case: asserting absence incorrectly importing custom module + import 'test-utils' + expect(queryByRole("button")).not.toBeInTheDocument() + `, }, { settings: { @@ -1391,18 +1444,29 @@ ruleTester.run(RULE_NAME, rule, { expect(getByRole("button")).not.toBeOnTheScreen() `, errors: [{ line: 4, column: 14, messageId: 'wrongAbsenceQuery' }], + output: ` + // case: asserting absence incorrectly importing custom module + import 'test-utils' + expect(queryByRole("button")).not.toBeOnTheScreen() + `, }, { code: ` // case: asserting within check does still work with improper outer clause expect(within(screen.getByRole("button")).getByText("Hello")).not.toBeInTheDocument()`, errors: [{ line: 3, column: 46, messageId: 'wrongAbsenceQuery' }], + output: ` + // case: asserting within check does still work with improper outer clause + expect(within(screen.getByRole("button")).queryByText("Hello")).not.toBeInTheDocument()`, }, { code: ` // case: asserting within check does still work with improper outer clause expect(within(screen.getByRole("button")).queryByText("Hello")).toBeInTheDocument()`, errors: [{ line: 3, column: 46, messageId: 'wrongPresenceQuery' }], + output: ` + // case: asserting within check does still work with improper outer clause + expect(within(screen.getByRole("button")).getByText("Hello")).toBeInTheDocument()`, }, { code: ` @@ -1412,18 +1476,27 @@ ruleTester.run(RULE_NAME, rule, { { line: 3, column: 25, messageId: 'wrongPresenceQuery' }, { line: 3, column: 48, messageId: 'wrongAbsenceQuery' }, ], + output: ` + // case: asserting within check does still work with improper outer clause and improper inner clause + expect(within(screen.getByRole("button")).queryByText("Hello")).not.toBeInTheDocument()`, }, { code: ` // case: asserting within check does still work with proper outer clause and improper inner clause expect(within(screen.queryByRole("button")).queryByText("Hello")).not.toBeInTheDocument()`, errors: [{ line: 3, column: 25, messageId: 'wrongPresenceQuery' }], + output: ` + // case: asserting within check does still work with proper outer clause and improper inner clause + expect(within(screen.getByRole("button")).queryByText("Hello")).not.toBeInTheDocument()`, }, { code: ` // case: asserting within check does still work with proper outer clause and improper inner clause expect(within(screen.queryByRole("button")).getByText("Hello")).toBeInTheDocument()`, errors: [{ line: 3, column: 25, messageId: 'wrongPresenceQuery' }], + output: ` + // case: asserting within check does still work with proper outer clause and improper inner clause + expect(within(screen.getByRole("button")).getByText("Hello")).toBeInTheDocument()`, }, { code: ` @@ -1433,18 +1506,27 @@ ruleTester.run(RULE_NAME, rule, { { line: 3, column: 25, messageId: 'wrongPresenceQuery' }, { line: 3, column: 48, messageId: 'wrongPresenceQuery' }, ], + output: ` + // case: asserting within check does still work with improper outer clause and improper inner clause + expect(within(screen.getByRole("button")).getByText("Hello")).toBeInTheDocument()`, }, { code: ` // case: asserting within check does still work with improper outer clause expect(within(screen.getByRole("button")).getByText("Hello")).not.toBeOnTheScreen()`, errors: [{ line: 3, column: 46, messageId: 'wrongAbsenceQuery' }], + output: ` + // case: asserting within check does still work with improper outer clause + expect(within(screen.getByRole("button")).queryByText("Hello")).not.toBeOnTheScreen()`, }, { code: ` // case: asserting within check does still work with improper outer clause expect(within(screen.getByRole("button")).queryByText("Hello")).toBeOnTheScreen()`, errors: [{ line: 3, column: 46, messageId: 'wrongPresenceQuery' }], + output: ` + // case: asserting within check does still work with improper outer clause + expect(within(screen.getByRole("button")).getByText("Hello")).toBeOnTheScreen()`, }, { code: ` @@ -1454,18 +1536,27 @@ ruleTester.run(RULE_NAME, rule, { { line: 3, column: 25, messageId: 'wrongPresenceQuery' }, { line: 3, column: 48, messageId: 'wrongAbsenceQuery' }, ], + output: ` + // case: asserting within check does still work with improper outer clause and improper inner clause + expect(within(screen.getByRole("button")).queryByText("Hello")).not.toBeOnTheScreen()`, }, { code: ` // case: asserting within check does still work with proper outer clause and improper inner clause expect(within(screen.queryByRole("button")).queryByText("Hello")).not.toBeOnTheScreen()`, errors: [{ line: 3, column: 25, messageId: 'wrongPresenceQuery' }], + output: ` + // case: asserting within check does still work with proper outer clause and improper inner clause + expect(within(screen.getByRole("button")).queryByText("Hello")).not.toBeOnTheScreen()`, }, { code: ` // case: asserting within check does still work with proper outer clause and improper inner clause expect(within(screen.queryByRole("button")).getByText("Hello")).toBeOnTheScreen()`, errors: [{ line: 3, column: 25, messageId: 'wrongPresenceQuery' }], + output: ` + // case: asserting within check does still work with proper outer clause and improper inner clause + expect(within(screen.getByRole("button")).getByText("Hello")).toBeOnTheScreen()`, }, { code: ` @@ -1475,6 +1566,9 @@ ruleTester.run(RULE_NAME, rule, { { line: 3, column: 25, messageId: 'wrongPresenceQuery' }, { line: 3, column: 48, messageId: 'wrongPresenceQuery' }, ], + output: ` + // case: asserting within check does still work with improper outer clause and improper inner clause + expect(within(screen.getByRole("button")).getByText("Hello")).toBeOnTheScreen()`, }, ], });