From 2f6c028ff85a39bce97248c73acd22f57585b5dc Mon Sep 17 00:00:00 2001 From: Gyumong <60845910+Gyumong@users.noreply.github.com> Date: Fri, 8 Nov 2024 19:03:58 +0900 Subject: [PATCH] fix(eslint-plugin-query): add Suspense query hooks to no-rest-destructuring rule (#8260) * fix(eslint-plugin-query): add missing hooks to no-rest-destructuring rule * test(no-rest-destructuring): add test cases for Suspense query hooks --- .../__tests__/no-rest-destructuring.test.ts | 177 ++++++++++++++++++ .../no-rest-destructuring.rule.ts | 14 +- 2 files changed, 189 insertions(+), 2 deletions(-) diff --git a/packages/eslint-plugin-query/src/__tests__/no-rest-destructuring.test.ts b/packages/eslint-plugin-query/src/__tests__/no-rest-destructuring.test.ts index b3ec633b70..50169bff2b 100644 --- a/packages/eslint-plugin-query/src/__tests__/no-rest-destructuring.test.ts +++ b/packages/eslint-plugin-query/src/__tests__/no-rest-destructuring.test.ts @@ -147,6 +147,144 @@ ruleTester.run('no-rest-destructuring', rule, { } `, }, + { + name: 'useSuspenseQuery is not captured', + code: normalizeIndent` + import { useSuspenseQuery } from '@tanstack/react-query' + + function Component() { + useSuspenseQuery() + return + } + `, + }, + { + name: 'useSuspenseQuery is not destructured', + code: normalizeIndent` + import { useSuspenseQuery } from '@tanstack/react-query' + + function Component() { + const query = useSuspenseQuery() + return + } + `, + }, + { + name: 'useSuspenseQuery is destructured without rest', + code: normalizeIndent` + import { useSuspenseQuery } from '@tanstack/react-query' + + function Component() { + const { data, isLoading, isError } = useSuspenseQuery() + return + } + `, + }, + { + name: 'useSuspenseInfiniteQuery is not captured', + code: normalizeIndent` + import { useSuspenseInfiniteQuery } from '@tanstack/react-query' + + function Component() { + useSuspenseInfiniteQuery() + return + } + `, + }, + { + name: 'useSuspenseInfiniteQuery is not destructured', + code: normalizeIndent` + import { useSuspenseInfiniteQuery } from '@tanstack/react-query' + + function Component() { + const query = useSuspenseInfiniteQuery() + return + } + `, + }, + { + name: 'useSuspenseInfiniteQuery is destructured without rest', + code: normalizeIndent` + import { useSuspenseInfiniteQuery } from '@tanstack/react-query' + + function Component() { + const { data, isLoading, isError } = useSuspenseInfiniteQuery() + return + } + `, + }, + { + name: 'useSuspenseQueries is not captured', + code: normalizeIndent` + import { useSuspenseQueries } from '@tanstack/react-query' + + function Component() { + useSuspenseQueries([]) + return + } + `, + }, + { + name: 'useSuspenseQueries is not destructured', + code: normalizeIndent` + import { useSuspenseQueries } from '@tanstack/react-query' + + function Component() { + const queries = useSuspenseQueries([]) + return + } + `, + }, + { + name: 'useSuspenseQueries array has no rest destructured element', + code: normalizeIndent` + import { useSuspenseQueries } from '@tanstack/react-query' + + function Component() { + const [query1, { data, isLoading }] = useSuspenseQueries([ + { queryKey: ['key1'], queryFn: () => {} }, + { queryKey: ['key2'], queryFn: () => {} }, + ]) + return + } + `, + }, + { + name: 'useSuspenseQuery is destructured with rest but not from tanstack query', + code: normalizeIndent` + import { useSuspenseQuery } from 'other-package' + + function Component() { + const { data, ...rest } = useSuspenseQuery() + return + } + `, + }, + { + name: 'useSuspenseInfiniteQuery is destructured with rest but not from tanstack query', + code: normalizeIndent` + import { useSuspenseInfiniteQuery } from 'other-package' + + function Component() { + const { data, ...rest } = useSuspenseInfiniteQuery() + return + } + `, + }, + { + name: 'useSuspenseQueries array has rest destructured element but not from tanstack query', + code: normalizeIndent` + import { useSuspenseQueries } from 'other-package' + + function Component() { + const [query1, { data, ...rest }] = useSuspenseQueries([ + { queryKey: ['key1'], queryFn: () => {} }, + { queryKey: ['key2'], queryFn: () => {} }, + ]) + return + } + `, + }, ], invalid: [ { @@ -188,5 +326,44 @@ ruleTester.run('no-rest-destructuring', rule, { `, errors: [{ messageId: 'objectRestDestructure' }], }, + { + name: 'useSuspenseQuery is destructured with rest', + code: normalizeIndent` + import { useSuspenseQuery } from '@tanstack/react-query' + + function Component() { + const { data, ...rest } = useSuspenseQuery() + return + } + `, + errors: [{ messageId: 'objectRestDestructure' }], + }, + { + name: 'useSuspenseInfiniteQuery is destructured with rest', + code: normalizeIndent` + import { useSuspenseInfiniteQuery } from '@tanstack/react-query' + + function Component() { + const { data, ...rest } = useSuspenseInfiniteQuery() + return + } + `, + errors: [{ messageId: 'objectRestDestructure' }], + }, + { + name: 'useSuspenseQueries is destructured with rest', + code: normalizeIndent` + import { useSuspenseQueries } from '@tanstack/react-query' + + function Component() { + const [query1, { data, ...rest }] = useSuspenseQueries([ + { queryKey: ['key1'], queryFn: () => {} }, + { queryKey: ['key2'], queryFn: () => {} }, + ]) + return + } + `, + errors: [{ messageId: 'objectRestDestructure' }], + }, ], }) diff --git a/packages/eslint-plugin-query/src/rules/no-rest-destructuring/no-rest-destructuring.rule.ts b/packages/eslint-plugin-query/src/rules/no-rest-destructuring/no-rest-destructuring.rule.ts index a8d9e79612..29b68389c9 100644 --- a/packages/eslint-plugin-query/src/rules/no-rest-destructuring/no-rest-destructuring.rule.ts +++ b/packages/eslint-plugin-query/src/rules/no-rest-destructuring/no-rest-destructuring.rule.ts @@ -7,7 +7,14 @@ import type { ExtraRuleDocs } from '../../types' export const name = 'no-rest-destructuring' -const queryHooks = ['useQuery', 'useQueries', 'useInfiniteQuery'] +const queryHooks = [ + 'useQuery', + 'useQueries', + 'useInfiniteQuery', + 'useSuspenseQuery', + 'useSuspenseQueries', + 'useSuspenseInfiniteQuery', +] const createRule = ESLintUtils.RuleCreator(getDocsUrl) @@ -38,7 +45,10 @@ export const rule = createRule({ } const returnValue = node.parent.id - if (node.callee.name !== 'useQueries') { + if ( + node.callee.name !== 'useQueries' && + node.callee.name !== 'useSuspenseQueries' + ) { if (NoRestDestructuringUtils.isObjectRestDestructuring(returnValue)) { context.report({ node: node.parent,