diff --git a/packages/vue-query/src/__tests__/infiniteQueryOptions.test-d.ts b/packages/vue-query/src/__tests__/infiniteQueryOptions.test-d.ts index cd4743d9d5..2b15cb7bfe 100644 --- a/packages/vue-query/src/__tests__/infiniteQueryOptions.test-d.ts +++ b/packages/vue-query/src/__tests__/infiniteQueryOptions.test-d.ts @@ -1,6 +1,7 @@ import { assertType, describe, expectTypeOf, it } from 'vitest' import { dataTagSymbol } from '@tanstack/query-core' import { reactive } from 'vue-demi' +import { queryKey } from '@tanstack/query-test-utils' import { infiniteQueryOptions } from '../infiniteQueryOptions' import { QueryClient } from '../queryClient' import { useInfiniteQuery } from '../useInfiniteQuery' @@ -8,9 +9,10 @@ import type { InfiniteData } from '@tanstack/query-core' describe('infiniteQueryOptions', () => { it('should not allow excess properties', () => { + const key = queryKey() assertType( infiniteQueryOptions({ - queryKey: ['key'], + queryKey: key, queryFn: () => Promise.resolve('data'), getNextPageParam: () => 1, initialPageParam: 1, @@ -20,8 +22,9 @@ describe('infiniteQueryOptions', () => { ) }) it('should infer types for callbacks', () => { + const key = queryKey() infiniteQueryOptions({ - queryKey: ['key'], + queryKey: key, queryFn: () => Promise.resolve('data'), staleTime: 1000, getNextPageParam: () => 1, @@ -32,8 +35,9 @@ describe('infiniteQueryOptions', () => { }) }) it('should work when passed to useInfiniteQuery', () => { + const key = queryKey() const options = infiniteQueryOptions({ - queryKey: ['key'], + queryKey: key, queryFn: () => Promise.resolve('string'), getNextPageParam: () => 1, initialPageParam: 1, @@ -46,61 +50,66 @@ describe('infiniteQueryOptions', () => { >() }) it('should tag the queryKey with the result type of the QueryFn', () => { - const { queryKey } = infiniteQueryOptions({ - queryKey: ['key'], + const key = queryKey() + const { queryKey: tagged } = infiniteQueryOptions({ + queryKey: key, queryFn: () => Promise.resolve('string'), getNextPageParam: () => 1, initialPageParam: 1, }) - expectTypeOf(queryKey[dataTagSymbol]).toEqualTypeOf>() + expectTypeOf(tagged[dataTagSymbol]).toEqualTypeOf>() }) it('should tag the queryKey even if no promise is returned', () => { - const { queryKey } = infiniteQueryOptions({ - queryKey: ['key'], + const key = queryKey() + const { queryKey: tagged } = infiniteQueryOptions({ + queryKey: key, queryFn: () => 'string', getNextPageParam: () => 1, initialPageParam: 1, }) - expectTypeOf(queryKey[dataTagSymbol]).toEqualTypeOf>() + expectTypeOf(tagged[dataTagSymbol]).toEqualTypeOf>() }) it('should tag the queryKey with the result type of the QueryFn if select is used', () => { - const { queryKey } = infiniteQueryOptions({ - queryKey: ['key'], + const key = queryKey() + const { queryKey: tagged } = infiniteQueryOptions({ + queryKey: key, queryFn: () => Promise.resolve('string'), select: (data) => data.pages, getNextPageParam: () => 1, initialPageParam: 1, }) - expectTypeOf(queryKey[dataTagSymbol]).toEqualTypeOf>() + expectTypeOf(tagged[dataTagSymbol]).toEqualTypeOf>() }) it('should return the proper type when passed to getQueryData', () => { - const { queryKey } = infiniteQueryOptions({ - queryKey: ['key'], + const key = queryKey() + const { queryKey: tagged } = infiniteQueryOptions({ + queryKey: key, queryFn: () => Promise.resolve('string'), getNextPageParam: () => 1, initialPageParam: 1, }) const queryClient = new QueryClient() - const data = queryClient.getQueryData(queryKey) + const data = queryClient.getQueryData(tagged) expectTypeOf(data).toEqualTypeOf< InfiniteData | undefined >() }) it('should properly type when passed to setQueryData', () => { - const { queryKey } = infiniteQueryOptions({ - queryKey: ['key'], + const key = queryKey() + const { queryKey: tagged } = infiniteQueryOptions({ + queryKey: key, queryFn: () => Promise.resolve('string'), getNextPageParam: () => 1, initialPageParam: 1, }) const queryClient = new QueryClient() - const data = queryClient.setQueryData(queryKey, (prev) => { + const data = queryClient.setQueryData(tagged, (prev) => { expectTypeOf(prev).toEqualTypeOf< InfiniteData | undefined >() diff --git a/packages/vue-query/src/__tests__/queryClient.test-d.ts b/packages/vue-query/src/__tests__/queryClient.test-d.ts index ed4855a134..9af6d20307 100644 --- a/packages/vue-query/src/__tests__/queryClient.test-d.ts +++ b/packages/vue-query/src/__tests__/queryClient.test-d.ts @@ -1,4 +1,5 @@ import { assertType, describe, expectTypeOf, it } from 'vitest' +import { queryKey } from '@tanstack/query-test-utils' import { QueryClient } from '../queryClient' import type { DataTag, InfiniteData } from '@tanstack/query-core' @@ -113,8 +114,9 @@ describe('setQueryData', () => { describe('fetchInfiniteQuery', () => { it('should allow passing pages', async () => { + const key = queryKey() const data = await new QueryClient().fetchInfiniteQuery({ - queryKey: ['key'], + queryKey: key, queryFn: () => Promise.resolve('string'), getNextPageParam: () => 1, initialPageParam: 1, @@ -125,9 +127,10 @@ describe('fetchInfiniteQuery', () => { }) it('should not allow passing getNextPageParam without pages', () => { + const key = queryKey() assertType>([ { - queryKey: ['key'], + queryKey: key, queryFn: () => Promise.resolve('string'), initialPageParam: 1, getNextPageParam: () => 1, @@ -136,10 +139,11 @@ describe('fetchInfiniteQuery', () => { }) it('should not allow passing pages without getNextPageParam', () => { + const key = queryKey() assertType>([ // @ts-expect-error Property 'getNextPageParam' is missing { - queryKey: ['key'], + queryKey: key, queryFn: () => Promise.resolve('string'), initialPageParam: 1, pages: 5, diff --git a/packages/vue-query/src/__tests__/queryOptions.test-d.ts b/packages/vue-query/src/__tests__/queryOptions.test-d.ts index 65d49d945f..3c98c30296 100644 --- a/packages/vue-query/src/__tests__/queryOptions.test-d.ts +++ b/packages/vue-query/src/__tests__/queryOptions.test-d.ts @@ -1,15 +1,17 @@ import { assertType, describe, expectTypeOf, it } from 'vitest' import { reactive, ref } from 'vue-demi' import { dataTagSymbol } from '@tanstack/query-core' +import { queryKey } from '@tanstack/query-test-utils' import { QueryClient } from '../queryClient' import { queryOptions } from '../queryOptions' import { useQuery } from '../useQuery' describe('queryOptions', () => { it('should not allow excess properties', () => { + const key = queryKey() assertType( queryOptions({ - queryKey: ['key'], + queryKey: key, queryFn: () => Promise.resolve(5), // @ts-expect-error this is a good error, because stallTime does not exist! stallTime: 1000, @@ -17,8 +19,9 @@ describe('queryOptions', () => { ) }) it('should infer types for callbacks', () => { + const key = queryKey() queryOptions({ - queryKey: ['key'], + queryKey: key, queryFn: () => Promise.resolve(5), staleTime: 1000, select: (data) => { @@ -27,8 +30,9 @@ describe('queryOptions', () => { }) }) it('should work when passed to useQuery', () => { + const key = queryKey() const options = queryOptions({ - queryKey: ['key'], + queryKey: key, queryFn: () => Promise.resolve(5), }) @@ -36,75 +40,82 @@ describe('queryOptions', () => { expectTypeOf(data).toEqualTypeOf() }) it('should tag the queryKey with the result type of the QueryFn', () => { - const { queryKey } = queryOptions({ - queryKey: ['key'], + const key = queryKey() + const { queryKey: tagged } = queryOptions({ + queryKey: key, queryFn: () => Promise.resolve(5), }) - expectTypeOf(queryKey[dataTagSymbol]).toEqualTypeOf() + expectTypeOf(tagged[dataTagSymbol]).toEqualTypeOf() }) it('should tag the queryKey even if no promise is returned', () => { - const { queryKey } = queryOptions({ - queryKey: ['key'], + const key = queryKey() + const { queryKey: tagged } = queryOptions({ + queryKey: key, queryFn: () => 5, }) - expectTypeOf(queryKey[dataTagSymbol]).toEqualTypeOf() + expectTypeOf(tagged[dataTagSymbol]).toEqualTypeOf() }) it('should tag the queryKey with unknown if there is no queryFn', () => { - const { queryKey } = queryOptions({ - queryKey: ['key'], + const key = queryKey() + const { queryKey: tagged } = queryOptions({ + queryKey: key, }) - expectTypeOf(queryKey[dataTagSymbol]).toEqualTypeOf() + expectTypeOf(tagged[dataTagSymbol]).toEqualTypeOf() }) it('should tag the queryKey with the result type of the QueryFn if select is used', () => { - const { queryKey } = queryOptions({ - queryKey: ['key'], + const key = queryKey() + const { queryKey: tagged } = queryOptions({ + queryKey: key, queryFn: () => Promise.resolve(5), select: (data) => data.toString(), }) - expectTypeOf(queryKey[dataTagSymbol]).toEqualTypeOf() + expectTypeOf(tagged[dataTagSymbol]).toEqualTypeOf() }) it('should return the proper type when passed to getQueryData', () => { - const { queryKey } = queryOptions({ - queryKey: ['key'], + const key = queryKey() + const { queryKey: tagged } = queryOptions({ + queryKey: key, queryFn: () => Promise.resolve(5), }) const queryClient = new QueryClient() - const data = queryClient.getQueryData(queryKey) + const data = queryClient.getQueryData(tagged) expectTypeOf(data).toEqualTypeOf() }) it('should properly type updaterFn when passed to setQueryData', () => { - const { queryKey } = queryOptions({ - queryKey: ['key'], + const key = queryKey() + const { queryKey: tagged } = queryOptions({ + queryKey: key, queryFn: () => Promise.resolve(5), }) const queryClient = new QueryClient() - const data = queryClient.setQueryData(queryKey, (prev) => { + const data = queryClient.setQueryData(tagged, (prev) => { expectTypeOf(prev).toEqualTypeOf() return prev }) expectTypeOf(data).toEqualTypeOf() }) it('should properly type value when passed to setQueryData', () => { - const { queryKey } = queryOptions({ - queryKey: ['key'], + const key = queryKey() + const { queryKey: tagged } = queryOptions({ + queryKey: key, queryFn: () => Promise.resolve(5), }) const queryClient = new QueryClient() // @ts-expect-error value should be a number - queryClient.setQueryData(queryKey, '5') + queryClient.setQueryData(tagged, '5') // @ts-expect-error value should be a number - queryClient.setQueryData(queryKey, () => '5') + queryClient.setQueryData(tagged, () => '5') - const data = queryClient.setQueryData(queryKey, 5) + const data = queryClient.setQueryData(tagged, 5) expectTypeOf(data).toEqualTypeOf() }) @@ -126,10 +137,11 @@ describe('queryOptions', () => { }) it('TData should always be defined when initialData is provided as a function which ALWAYS returns the data', () => { + const key = queryKey() const { data } = reactive( useQuery( queryOptions({ - queryKey: ['key'], + queryKey: key, queryFn: () => { return { wow: true, @@ -146,10 +158,11 @@ describe('queryOptions', () => { }) it('TData should have undefined in the union when initialData is NOT provided', () => { + const key = queryKey() const { data } = reactive( useQuery( queryOptions({ - queryKey: ['key'], + queryKey: key, queryFn: () => { return { wow: true, @@ -163,10 +176,11 @@ describe('queryOptions', () => { }) it('TData should have undefined in the union when initialData is provided as a function which can return undefined', () => { + const key = queryKey() const { data } = reactive( useQuery( queryOptions({ - queryKey: ['key'], + queryKey: key, queryFn: () => { return { wow: true, @@ -181,10 +195,11 @@ describe('queryOptions', () => { }) it('TData should be narrowed after an isSuccess check when initialData is provided as a function which can return undefined', () => { + const key = queryKey() const { data, isSuccess } = reactive( useQuery( queryOptions({ - queryKey: ['key'], + queryKey: key, queryFn: () => { return { wow: true, @@ -201,10 +216,11 @@ describe('queryOptions', () => { }) it('data should not have undefined when initialData is provided', () => { + const key = queryKey() const { data } = reactive( useQuery( queryOptions({ - queryKey: ['query-key'], + queryKey: key, initialData: 42, }), ), diff --git a/packages/vue-query/src/__tests__/useInfiniteQuery.test-d.tsx b/packages/vue-query/src/__tests__/useInfiniteQuery.test-d.tsx index 9163cd2482..fd083967d0 100644 --- a/packages/vue-query/src/__tests__/useInfiniteQuery.test-d.tsx +++ b/packages/vue-query/src/__tests__/useInfiniteQuery.test-d.tsx @@ -1,15 +1,16 @@ import { describe, expectTypeOf, it } from 'vitest' import { computed, reactive } from 'vue-demi' -import { sleep } from '@tanstack/query-test-utils' +import { queryKey, sleep } from '@tanstack/query-test-utils' import { useInfiniteQuery } from '../useInfiniteQuery' import { infiniteQueryOptions } from '../infiniteQueryOptions' import type { InfiniteData } from '@tanstack/query-core' describe('Discriminated union return type', () => { it('data should be possibly undefined by default', () => { + const key = queryKey() const query = reactive( useInfiniteQuery({ - queryKey: ['infiniteQuery'], + queryKey: key, queryFn: () => sleep(0).then(() => 'Some data'), getNextPageParam: () => undefined, initialPageParam: 0, @@ -23,9 +24,10 @@ describe('Discriminated union return type', () => { }) it('data should be defined when query is success', () => { + const key = queryKey() const query = reactive( useInfiniteQuery({ - queryKey: ['infiniteQuery'], + queryKey: key, queryFn: () => sleep(0).then(() => 'Some data'), getNextPageParam: () => undefined, initialPageParam: 0, @@ -39,9 +41,10 @@ describe('Discriminated union return type', () => { }) it('error should be null when query is success', () => { + const key = queryKey() const query = reactive( useInfiniteQuery({ - queryKey: ['infiniteQuery'], + queryKey: key, queryFn: () => sleep(0).then(() => 'Some data'), getNextPageParam: () => undefined, initialPageParam: 0, @@ -54,9 +57,10 @@ describe('Discriminated union return type', () => { }) it('data should be undefined when query is pending', () => { + const key = queryKey() const query = reactive( useInfiniteQuery({ - queryKey: ['infiniteQuery'], + queryKey: key, queryFn: () => sleep(0).then(() => 'Some data'), getNextPageParam: () => undefined, initialPageParam: 0, @@ -69,9 +73,10 @@ describe('Discriminated union return type', () => { }) it('error should be defined when query is error', () => { + const key = queryKey() const query = reactive( useInfiniteQuery({ - queryKey: ['infiniteQuery'], + queryKey: key, queryFn: () => sleep(0).then(() => 'Some data'), getNextPageParam: () => undefined, initialPageParam: 0, @@ -84,8 +89,9 @@ describe('Discriminated union return type', () => { }) it('should accept computed options', () => { + const key = queryKey() const options = computed(() => ({ - queryKey: ['infiniteQuery'], + queryKey: key, queryFn: () => sleep(0).then(() => 'Some data'), getNextPageParam: () => undefined, initialPageParam: 0, @@ -98,9 +104,10 @@ describe('Discriminated union return type', () => { }) it('should accept computed options using infiniteQueryOptions', () => { + const key = queryKey() const options = computed(() => infiniteQueryOptions({ - queryKey: ['infiniteQuery'], + queryKey: key, queryFn: () => sleep(0).then(() => 'Some data'), getNextPageParam: () => undefined, initialPageParam: 0, @@ -114,9 +121,10 @@ describe('Discriminated union return type', () => { }) it('should accept plain options using infiniteQueryOptions', () => { + const key = queryKey() const options = () => infiniteQueryOptions({ - queryKey: ['infiniteQuery'], + queryKey: key, queryFn: () => sleep(0).then(() => 'Some data'), getNextPageParam: () => undefined, initialPageParam: 0, diff --git a/packages/vue-query/src/__tests__/useInfiniteQuery.test.ts b/packages/vue-query/src/__tests__/useInfiniteQuery.test.ts index b9eee7547f..73dd45b7eb 100644 --- a/packages/vue-query/src/__tests__/useInfiniteQuery.test.ts +++ b/packages/vue-query/src/__tests__/useInfiniteQuery.test.ts @@ -1,5 +1,5 @@ import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest' -import { sleep } from '@tanstack/query-test-utils' +import { queryKey, sleep } from '@tanstack/query-test-utils' import { useInfiniteQuery } from '../useInfiniteQuery' import { infiniteQueryOptions } from '../infiniteQueryOptions' @@ -15,8 +15,9 @@ describe('useInfiniteQuery', () => { }) test('should properly execute infinite query', async () => { + const key = queryKey() const { data, fetchNextPage, status } = useInfiniteQuery({ - queryKey: ['infiniteQuery'], + queryKey: key, queryFn: ({ pageParam }) => sleep(0).then(() => 'data on page ' + pageParam), initialPageParam: 0, @@ -45,8 +46,9 @@ describe('useInfiniteQuery', () => { expect(status.value).toStrictEqual('success') }) test('should properly execute infinite query using infiniteQueryOptions', async () => { + const key = queryKey() const options = infiniteQueryOptions({ - queryKey: ['infiniteQueryOptions'], + queryKey: key, queryFn: ({ pageParam }) => sleep(0).then(() => 'data on page ' + pageParam), initialPageParam: 0, diff --git a/packages/vue-query/src/__tests__/useIsFetching.test.ts b/packages/vue-query/src/__tests__/useIsFetching.test.ts index aa4a933931..1e1a5a0ae2 100644 --- a/packages/vue-query/src/__tests__/useIsFetching.test.ts +++ b/packages/vue-query/src/__tests__/useIsFetching.test.ts @@ -1,6 +1,6 @@ import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest' import { onScopeDispose, reactive, ref } from 'vue-demi' -import { sleep } from '@tanstack/query-test-utils' +import { queryKey, sleep } from '@tanstack/query-test-utils' import { useQuery } from '../useQuery' import { useIsFetching } from '../useIsFetching' import type { MockedFunction } from 'vitest' @@ -17,12 +17,14 @@ describe('useIsFetching', () => { }) test('should properly return isFetching state', async () => { + const key1 = queryKey() + const key2 = queryKey() const { isFetching: isFetchingQuery } = useQuery({ - queryKey: ['isFetching1'], + queryKey: key1, queryFn: () => sleep(0).then(() => 'Some data'), }) useQuery({ - queryKey: ['isFetching2'], + queryKey: key2, queryFn: () => sleep(0).then(() => 'Some data'), }) const isFetching = useIsFetching() @@ -37,13 +39,14 @@ describe('useIsFetching', () => { }) test('should stop listening to changes on onScopeDispose', async () => { + const key = queryKey() const onScopeDisposeMock = onScopeDispose as MockedFunction< typeof onScopeDispose > onScopeDisposeMock.mockImplementation((fn) => fn()) const { status } = useQuery({ - queryKey: ['onScopeDispose'], + queryKey: key, queryFn: () => sleep(0).then(() => 'Some data'), }) const isFetching = useIsFetching() @@ -65,9 +68,10 @@ describe('useIsFetching', () => { }) test('should properly update filters', async () => { - const filter = reactive({ stale: false, queryKey: ['isFetchingFilter'] }) + const key = queryKey() + const filter = reactive({ stale: false, queryKey: key }) useQuery({ - queryKey: ['isFetchingFilter'], + queryKey: key, queryFn: () => sleep(10).then(() => 'Some data'), }) const isFetching = useIsFetching(filter) @@ -81,14 +85,15 @@ describe('useIsFetching', () => { }) test('should work with options getter and be reactive', async () => { + const key = queryKey() const staleRef = ref(false) useQuery({ - queryKey: ['isFetchingGetter'], + queryKey: key, queryFn: () => sleep(10).then(() => 'Some data'), }) const isFetching = useIsFetching(() => ({ stale: staleRef.value, - queryKey: ['isFetchingGetter'], + queryKey: key, })) expect(isFetching.value).toStrictEqual(0) diff --git a/packages/vue-query/src/__tests__/useIsMutating.test.ts b/packages/vue-query/src/__tests__/useIsMutating.test.ts index 237ccb765d..a4b92b10d4 100644 --- a/packages/vue-query/src/__tests__/useIsMutating.test.ts +++ b/packages/vue-query/src/__tests__/useIsMutating.test.ts @@ -1,6 +1,6 @@ import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest' import { onScopeDispose, reactive, ref } from 'vue-demi' -import { sleep } from '@tanstack/query-test-utils' +import { queryKey, sleep } from '@tanstack/query-test-utils' import { useMutation } from '../useMutation' import { useIsMutating } from '../useMutationState' import type { MockedFunction } from 'vitest' @@ -70,9 +70,11 @@ describe('useIsMutating', () => { }) test('should properly update filters', async () => { - const filter = reactive({ mutationKey: ['foo'] }) + const key = queryKey() + const filterKey = queryKey() + const filter = reactive({ mutationKey: filterKey }) const { mutate } = useMutation({ - mutationKey: ['isMutating'], + mutationKey: key, mutationFn: (params: string) => sleep(10).then(() => params), }) mutate('foo') @@ -81,7 +83,7 @@ describe('useIsMutating', () => { expect(isMutating.value).toStrictEqual(0) - filter.mutationKey = ['isMutating'] + filter.mutationKey = key await vi.advanceTimersByTimeAsync(0) @@ -89,9 +91,10 @@ describe('useIsMutating', () => { }) test('should work with options getter and be reactive', async () => { + const key = queryKey() const keyRef = ref('isMutatingGetter2') const { mutate } = useMutation({ - mutationKey: ['isMutatingGetter'], + mutationKey: key, mutationFn: (params: string) => sleep(10).then(() => params), }) mutate('foo') @@ -102,7 +105,7 @@ describe('useIsMutating', () => { expect(isMutating.value).toStrictEqual(0) - keyRef.value = 'isMutatingGetter' + keyRef.value = key[0]! await vi.advanceTimersByTimeAsync(0) diff --git a/packages/vue-query/src/__tests__/useMutation.test.ts b/packages/vue-query/src/__tests__/useMutation.test.ts index d24bfed675..993971853e 100644 --- a/packages/vue-query/src/__tests__/useMutation.test.ts +++ b/packages/vue-query/src/__tests__/useMutation.test.ts @@ -1,6 +1,6 @@ import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest' import { reactive, ref } from 'vue-demi' -import { sleep } from '@tanstack/query-test-utils' +import { queryKey, sleep } from '@tanstack/query-test-utils' import { useMutation } from '../useMutation' import { useQueryClient } from '../useQueryClient' @@ -83,11 +83,12 @@ describe('useMutation', () => { }) test('should work with options getter and be reactive', async () => { + const key = queryKey() const result = 'Mock data' const keyRef = ref('key01') const fnMock = vi.fn((params: string) => sleep(10).then(() => params)) const mutation = useMutation(() => ({ - mutationKey: [keyRef.value], + mutationKey: [...key, keyRef.value], mutationFn: fnMock, })) @@ -99,7 +100,7 @@ describe('useMutation', () => { expect(fnMock).toHaveBeenNthCalledWith( 1, result, - expect.objectContaining({ mutationKey: ['key01'] }), + expect.objectContaining({ mutationKey: [...key, 'key01'] }), ) keyRef.value = 'key02' @@ -111,28 +112,30 @@ describe('useMutation', () => { expect(fnMock).toHaveBeenNthCalledWith( 2, result, - expect.objectContaining({ mutationKey: ['key02'] }), + expect.objectContaining({ mutationKey: [...key, 'key02'] }), ) }) test('should update reactive options', async () => { + const key1 = queryKey() + const key2 = queryKey() const queryClient = useQueryClient() const mutationCache = queryClient.getMutationCache() const options = reactive({ - mutationKey: ['foo'], + mutationKey: key1, mutationFn: (params: string) => sleep(10).then(() => params), }) const mutation = useMutation(options) - options.mutationKey = ['bar'] + options.mutationKey = key2 await vi.advanceTimersByTimeAsync(10) mutation.mutate('xyz') await vi.advanceTimersByTimeAsync(10) - const mutations = mutationCache.find({ mutationKey: ['bar'] }) + const mutations = mutationCache.find({ mutationKey: key2 }) - expect(mutations?.options.mutationKey).toEqual(['bar']) + expect(mutations?.options.mutationKey).toEqual(key2) }) test('should update reactive options deeply', async () => { @@ -177,13 +180,15 @@ describe('useMutation', () => { }) test('should allow for non-options object (mutationFn or mutationKey) passed as arg1 & arg2 to trigger reactive updates', async () => { - const mutationKey = ref>(['foo2']) + const key1 = queryKey() + const key2 = queryKey() + const mutationKeyRef = ref>(key1) const mutationFn = ref((params: string) => sleep(0).then(() => params)) const queryClient = useQueryClient() const mutationCache = queryClient.getMutationCache() - const mutation = useMutation({ mutationKey, mutationFn }) + const mutation = useMutation({ mutationKey: mutationKeyRef, mutationFn }) - mutationKey.value = ['bar2'] + mutationKeyRef.value = key2 let proof = false mutationFn.value = (params: string) => { proof = true @@ -194,8 +199,8 @@ describe('useMutation', () => { mutation.mutate('xyz') await vi.advanceTimersByTimeAsync(10) - const mutations = mutationCache.find({ mutationKey: ['bar2'] }) - expect(mutations?.options.mutationKey).toEqual(['bar2']) + const mutations = mutationCache.find({ mutationKey: key2 }) + expect(mutations?.options.mutationKey).toEqual(key2) expect(proof).toEqual(true) }) diff --git a/packages/vue-query/src/__tests__/useMutationState.test.ts b/packages/vue-query/src/__tests__/useMutationState.test.ts index df15a1d9f8..816a1b164c 100644 --- a/packages/vue-query/src/__tests__/useMutationState.test.ts +++ b/packages/vue-query/src/__tests__/useMutationState.test.ts @@ -1,6 +1,6 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' import { ref } from 'vue-demi' -import { sleep } from '@tanstack/query-test-utils' +import { queryKey, sleep } from '@tanstack/query-test-utils' import { useMutation } from '../useMutation' import { useMutationState } from '../useMutationState' import { useQueryClient } from '../useQueryClient' @@ -17,18 +17,18 @@ describe('useMutationState', () => { }) it('should return variables after calling mutate 1', () => { - const mutationKey = ['mutation'] + const key = queryKey() const variables = 'foo123' const { mutate } = useMutation({ - mutationKey: mutationKey, + mutationKey: key, mutationFn: (params: string) => sleep(0).then(() => params), }) mutate(variables) const mutationState = useMutationState({ - filters: { mutationKey, status: 'pending' }, + filters: { mutationKey: key, status: 'pending' }, select: (mutation) => mutation.state.variables, }) @@ -38,11 +38,11 @@ describe('useMutationState', () => { it('should return variables after calling mutate 2', () => { const queryClient = useQueryClient() queryClient.clear() - const mutationKey = ['mutation'] + const key = queryKey() const variables = 'bar234' const { mutate } = useMutation({ - mutationKey: mutationKey, + mutationKey: key, mutationFn: (params: string) => sleep(0).then(() => params), }) @@ -54,11 +54,12 @@ describe('useMutationState', () => { }) it('should work with options getter and be reactive', async () => { + const key = queryKey() const keyRef = ref('useMutationStateGetter2') const variables = 'foo123' const { mutate } = useMutation({ - mutationKey: ['useMutationStateGetter'], + mutationKey: key, mutationFn: (params: string) => sleep(10).then(() => params), }) @@ -71,7 +72,7 @@ describe('useMutationState', () => { expect(mutationState.value).toEqual([]) - keyRef.value = 'useMutationStateGetter' + keyRef.value = key[0]! await vi.advanceTimersByTimeAsync(0) diff --git a/packages/vue-query/src/__tests__/useQueries.test-d.ts b/packages/vue-query/src/__tests__/useQueries.test-d.ts index c67de7b1a9..7e6783d422 100644 --- a/packages/vue-query/src/__tests__/useQueries.test-d.ts +++ b/packages/vue-query/src/__tests__/useQueries.test-d.ts @@ -1,5 +1,6 @@ import { describe, expectTypeOf, it } from 'vitest' import { reactive } from 'vue' +import { queryKey } from '@tanstack/query-test-utils' import { skipToken, useQueries } from '..' import { queryOptions } from '../queryOptions' import type { OmitKeyof, QueryObserverResult } from '..' @@ -7,8 +8,11 @@ import type { UseQueryOptions } from '../useQuery' describe('UseQueries config object overload', () => { it('TData should always be defined when initialData is provided as an object', () => { + const key1 = queryKey() + const key2 = queryKey() + const key3 = queryKey() const query1 = { - queryKey: ['key1'], + queryKey: key1, queryFn: () => { return { wow: true, @@ -20,13 +24,13 @@ describe('UseQueries config object overload', () => { } const query2 = queryOptions({ - queryKey: ['key2'], + queryKey: key2, queryFn: () => 'Query Data', initialData: 'initial data', }) const query3 = { - queryKey: ['key2'], + queryKey: key3, queryFn: () => 'Query Data', } @@ -40,8 +44,9 @@ describe('UseQueries config object overload', () => { }) it('TData should be defined when passed through queryOptions', () => { + const key = queryKey() const options = queryOptions({ - queryKey: ['key'], + queryKey: key, queryFn: () => { return { wow: true, @@ -58,14 +63,16 @@ describe('UseQueries config object overload', () => { }) it('should be possible to define a different TData than TQueryFnData using select with queryOptions spread into useQueries', () => { + const key1 = queryKey() + const key2 = queryKey() const query1 = queryOptions({ - queryKey: ['key'], + queryKey: key1, queryFn: () => Promise.resolve(1), select: (data) => data > 1, }) const query2 = { - queryKey: ['key'], + queryKey: key2, queryFn: () => Promise.resolve(1), select: (data: any) => data > 1, } @@ -81,10 +88,11 @@ describe('UseQueries config object overload', () => { }) it('TData should have undefined in the union when initialData is provided as a function which can return undefined', () => { + const key = queryKey() const { value: queriesState } = useQueries({ queries: [ { - queryKey: ['key'], + queryKey: key, queryFn: () => { return { wow: true, @@ -101,10 +109,11 @@ describe('UseQueries config object overload', () => { }) it('TData should have correct type when conditional skipToken is passed', () => { + const key = queryKey() const { value: queriesState } = useQueries({ queries: [ queryOptions({ - queryKey: ['key'], + queryKey: key, queryFn: Math.random() > 0.5 ? skipToken : () => Promise.resolve(5), }), ], @@ -131,7 +140,7 @@ describe('UseQueries config object overload', () => { queries: [ { ...options, - queryKey: ['todos-key'], + queryKey: queryKey(), queryFn: () => Promise.resolve('data'), }, ], @@ -146,7 +155,7 @@ describe('UseQueries config object overload', () => { // Fix #7270 it('should have proper type inference with different options provided', () => { const numbers = [1, 2, 3] - const queryKey = (n: number) => [n] + const getQueryKey = (n: number) => [n] const queryFn = (n: number) => () => Promise.resolve(n) const select = (data: number) => data.toString() @@ -157,13 +166,13 @@ describe('UseQueries config object overload', () => { })) const queriesWithoutSelect = numbers.map((n) => ({ - queryKey: queryKey(n), + queryKey: getQueryKey(n), queryFn: queryFn(n), })) const queriesWithQueryOptions = numbers.map((n) => queryOptions({ - queryKey: queryKey(n), + queryKey: getQueryKey(n), queryFn: queryFn(n), select, }), @@ -171,7 +180,7 @@ describe('UseQueries config object overload', () => { const queriesWithQueryOptionsWithoutSelect = numbers.map((n) => queryOptions({ - queryKey: queryKey(n), + queryKey: getQueryKey(n), queryFn: queryFn(n), }), ) @@ -221,17 +230,19 @@ describe('UseQueries config object overload', () => { }) it('should return correct data for dynamic queries with mixed result types', () => { + const key1 = queryKey() + const key2 = queryKey() const Queries1 = { get: () => queryOptions({ - queryKey: ['key1'], + queryKey: key1, queryFn: () => Promise.resolve(1), }), } const Queries2 = { get: () => queryOptions({ - queryKey: ['key2'], + queryKey: key2, queryFn: () => Promise.resolve(true), }), } diff --git a/packages/vue-query/src/__tests__/useQueries.test.ts b/packages/vue-query/src/__tests__/useQueries.test.ts index 4690df29c4..5c8189f8fb 100644 --- a/packages/vue-query/src/__tests__/useQueries.test.ts +++ b/packages/vue-query/src/__tests__/useQueries.test.ts @@ -1,6 +1,6 @@ import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest' import { onScopeDispose, ref } from 'vue-demi' -import { sleep } from '@tanstack/query-test-utils' +import { queryKey, sleep } from '@tanstack/query-test-utils' import { useQueries } from '../useQueries' import { useQueryClient } from '../useQueryClient' import { QueryClient } from '../queryClient' @@ -19,13 +19,15 @@ describe('useQueries', () => { }) test('should return result for each query', () => { + const key1 = queryKey() + const key2 = queryKey() const queries = [ { - queryKey: ['key1'], + queryKey: key1, queryFn: () => sleep(0).then(() => 'Some data'), }, { - queryKey: ['key2'], + queryKey: key2, queryFn: () => sleep(0).then(() => 'Some data'), }, ] @@ -48,13 +50,15 @@ describe('useQueries', () => { }) test('should resolve to success and update reactive state', async () => { + const key1 = queryKey() + const key2 = queryKey() const queries = [ { - queryKey: ['key11'], + queryKey: key1, queryFn: () => sleep(0).then(() => 'Some data'), }, { - queryKey: ['key12'], + queryKey: key2, queryFn: () => sleep(0).then(() => 'Some data'), }, ] @@ -79,14 +83,16 @@ describe('useQueries', () => { }) test('should reject one of the queries and update reactive state', async () => { + const key1 = queryKey() + const key2 = queryKey() const queries = [ { - queryKey: ['key21'], + queryKey: key1, queryFn: () => sleep(0).then(() => Promise.reject(new Error('Some error'))), }, { - queryKey: ['key22'], + queryKey: key2, queryFn: () => sleep(0).then(() => 'Some data'), }, ] @@ -111,17 +117,21 @@ describe('useQueries', () => { }) test('should return state for new queries', async () => { + const key1 = queryKey() + const key2 = queryKey() + const key3 = queryKey() + const key4 = queryKey() const queries = ref([ { - queryKey: ['key31'], + queryKey: key1, queryFn: () => sleep(0).then(() => 'value31'), }, { - queryKey: ['key32'], + queryKey: key2, queryFn: () => sleep(0).then(() => 'value32'), }, { - queryKey: ['key33'], + queryKey: key3, queryFn: () => sleep(0).then(() => 'value33'), }, ]) @@ -133,11 +143,11 @@ describe('useQueries', () => { 0, queries.value.length, { - queryKey: ['key31'], + queryKey: key1, queryFn: () => sleep(0).then(() => 'value31'), }, { - queryKey: ['key34'], + queryKey: key4, queryFn: () => sleep(0).then(() => 'value34'), }, ) @@ -165,6 +175,8 @@ describe('useQueries', () => { }) test('should stop listening to changes on onScopeDispose', async () => { + const key1 = queryKey() + const key2 = queryKey() const onScopeDisposeMock = onScopeDispose as MockedFunction< typeof onScopeDispose > @@ -172,11 +184,11 @@ describe('useQueries', () => { const queries = [ { - queryKey: ['key41'], + queryKey: key1, queryFn: () => sleep(0).then(() => 'Some data'), }, { - queryKey: ['key42'], + queryKey: key2, queryFn: () => sleep(0).then(() => 'Some data'), }, ] @@ -200,14 +212,16 @@ describe('useQueries', () => { }) test('should use queryClient provided via options', async () => { + const key1 = queryKey() + const key2 = queryKey() const queryClient = new QueryClient() const queries = [ { - queryKey: ['key41'], + queryKey: key1, queryFn: () => sleep(0).then(() => 'Some data'), }, { - queryKey: ['key42'], + queryKey: key2, queryFn: () => sleep(0).then(() => 'Some data'), }, ] @@ -219,17 +233,19 @@ describe('useQueries', () => { }) test('should combine queries', async () => { + const key1 = queryKey() + const key2 = queryKey() const firstResult = 'first result' const secondResult = 'second result' const queryClient = new QueryClient() const queries = [ { - queryKey: ['key41'], + queryKey: key1, queryFn: () => sleep(0).then(() => firstResult), }, { - queryKey: ['key42'], + queryKey: key2, queryFn: () => sleep(0).then(() => secondResult), }, ] @@ -255,13 +271,14 @@ describe('useQueries', () => { }) test('should be `enabled` to accept getter function', async () => { + const key = queryKey() const fetchFn = vi.fn(() => 'foo') const checked = ref(false) useQueries({ queries: [ { - queryKey: ['enabled'], + queryKey: key, queryFn: fetchFn, enabled: () => checked.value, }, @@ -278,6 +295,7 @@ describe('useQueries', () => { }) test('should allow getters for query keys', async () => { + const key = queryKey() const fetchFn = vi.fn(() => 'foo') const key1 = ref('key1') const key2 = ref('key2') @@ -285,7 +303,7 @@ describe('useQueries', () => { useQueries({ queries: [ { - queryKey: ['key', () => key1.value, () => key2.value], + queryKey: [...key, () => key1.value, () => key2.value], queryFn: fetchFn, }, ], @@ -307,6 +325,7 @@ describe('useQueries', () => { }) test('should allow arbitrarily nested getters for query keys', async () => { + const key = queryKey() const fetchFn = vi.fn(() => 'foo') const key1 = ref('key1') const key2 = ref('key2') @@ -318,7 +337,7 @@ describe('useQueries', () => { queries: [ { queryKey: [ - 'key', + ...key, key1, () => key2.value, { key: () => key3.value }, @@ -370,17 +389,19 @@ describe('useQueries', () => { }) test('should refetch only the specific query without affecting others', async () => { + const key1 = queryKey() + const key2 = queryKey() let userCount = 0 let postCount = 0 const queriesState = useQueries({ queries: [ { - queryKey: ['users'], + queryKey: key1, queryFn: () => sleep(10).then(() => `users-${++userCount}`), }, { - queryKey: ['posts'], + queryKey: key2, queryFn: () => sleep(20).then(() => `posts-${++postCount}`), }, ], @@ -406,7 +427,7 @@ describe('useQueries', () => { useQueries({ queries: [ { - queryKey: ['outsideScope'], + queryKey: queryKey(), queryFn: () => sleep(0).then(() => 'data'), }, ], @@ -422,6 +443,7 @@ describe('useQueries', () => { }) test('should work with options getter and be reactive', async () => { + const key = queryKey() const fetchFn = vi.fn(() => 'foo') const key1 = ref('key1') const key2 = ref('key2') @@ -433,7 +455,7 @@ describe('useQueries', () => { queries: () => [ { queryKey: [ - 'key', + ...key, key1, key2.value, { key: key3.value }, diff --git a/packages/vue-query/src/__tests__/useQuery.test-d.ts b/packages/vue-query/src/__tests__/useQuery.test-d.ts index 9111f049b2..12dbb4a41c 100644 --- a/packages/vue-query/src/__tests__/useQuery.test-d.ts +++ b/packages/vue-query/src/__tests__/useQuery.test-d.ts @@ -1,15 +1,17 @@ import { describe, expectTypeOf, it } from 'vitest' import { computed, reactive, ref } from 'vue-demi' -import { sleep } from '@tanstack/query-test-utils' +import { queryKey, sleep } from '@tanstack/query-test-utils' import { queryOptions, useQuery } from '..' import type { OmitKeyof, UseQueryOptions } from '..' describe('useQuery', () => { describe('Config object overload', () => { it('TData should always be defined when initialData is provided as an object', () => { + const key = queryKey() + const { data } = reactive( useQuery({ - queryKey: ['key'], + queryKey: key, queryFn: () => { return { wow: true, @@ -25,8 +27,10 @@ describe('useQuery', () => { }) it('TData should be defined when passed through queryOptions', () => { + const key = queryKey() + const options = queryOptions({ - queryKey: ['key'], + queryKey: key, queryFn: () => { return { wow: true, @@ -42,8 +46,10 @@ describe('useQuery', () => { }) it('should be possible to define a different TData than TQueryFnData using select with queryOptions spread into useQuery', () => { + const key = queryKey() + const options = queryOptions({ - queryKey: ['key'], + queryKey: key, queryFn: () => Promise.resolve(1), }) @@ -58,9 +64,11 @@ describe('useQuery', () => { }) it('TData should always be defined when initialData is provided as a function which ALWAYS returns the data', () => { + const key = queryKey() + const { data } = reactive( useQuery({ - queryKey: ['key'], + queryKey: key, queryFn: () => { return { wow: true, @@ -76,9 +84,11 @@ describe('useQuery', () => { }) it('TData should have undefined in the union when initialData is NOT provided', () => { + const key = queryKey() + const { data } = reactive( useQuery({ - queryKey: ['key'], + queryKey: key, queryFn: () => { return { wow: true, @@ -91,9 +101,11 @@ describe('useQuery', () => { }) it('TData should have undefined in the union when initialData is provided as a function which can return undefined', () => { + const key = queryKey() + const { data } = reactive( useQuery({ - queryKey: ['key'], + queryKey: key, queryFn: () => { return { wow: true, @@ -107,9 +119,11 @@ describe('useQuery', () => { }) it('TData should be narrowed after an isSuccess check when initialData is provided as a function which can return undefined', () => { + const key = queryKey() + const { data, isSuccess } = reactive( useQuery({ - queryKey: ['key'], + queryKey: key, queryFn: () => { return { wow: true, @@ -125,9 +139,11 @@ describe('useQuery', () => { }) it('data should not have undefined when initialData is provided', () => { + const key = queryKey() + const { data } = reactive( useQuery({ - queryKey: ['query-key'], + queryKey: key, initialData: 42, }), ) @@ -138,6 +154,8 @@ describe('useQuery', () => { describe('custom composable', () => { it('should allow custom composable using UseQueryOptions', () => { + const key = queryKey() + const useCustomQuery = ( options?: OmitKeyof< UseQueryOptions, @@ -147,7 +165,7 @@ describe('useQuery', () => { ) => { return useQuery({ ...options, - queryKey: ['todos-key'], + queryKey: key, queryFn: () => Promise.resolve('data'), }) } @@ -160,9 +178,11 @@ describe('useQuery', () => { describe('structuralSharing', () => { it('should be able to use structuralSharing with unknown types', () => { + const key = queryKey() + // https://github.com/TanStack/query/issues/6525#issuecomment-1938411343 useQuery({ - queryKey: ['key'], + queryKey: key, queryFn: () => 5, structuralSharing: (oldData, newData) => { expectTypeOf(oldData).toBeUnknown() @@ -175,9 +195,11 @@ describe('useQuery', () => { describe('Discriminated union return type', () => { it('data should be possibly undefined by default', () => { + const key = queryKey() + const query = reactive( useQuery({ - queryKey: ['key'], + queryKey: key, queryFn: () => sleep(0).then(() => 'Some data'), }), ) @@ -186,9 +208,11 @@ describe('useQuery', () => { }) it('data should be defined when query is success', () => { + const key = queryKey() + const query = reactive( useQuery({ - queryKey: ['key'], + queryKey: key, queryFn: () => sleep(0).then(() => 'Some data'), }), ) @@ -199,9 +223,11 @@ describe('useQuery', () => { }) it('error should be null when query is success', () => { + const key = queryKey() + const query = reactive( useQuery({ - queryKey: ['key'], + queryKey: key, queryFn: () => sleep(0).then(() => 'Some data'), }), ) @@ -212,9 +238,11 @@ describe('useQuery', () => { }) it('data should be undefined when query is pending', () => { + const key = queryKey() + const query = reactive( useQuery({ - queryKey: ['key'], + queryKey: key, queryFn: () => sleep(0).then(() => 'Some data'), }), ) @@ -225,9 +253,11 @@ describe('useQuery', () => { }) it('error should be defined when query is error', () => { + const key = queryKey() + const query = reactive( useQuery({ - queryKey: ['key'], + queryKey: key, queryFn: () => sleep(0).then(() => 'Some data'), }), ) diff --git a/packages/vue-query/src/__tests__/useQuery.test.ts b/packages/vue-query/src/__tests__/useQuery.test.ts index 5309510930..f5157e8902 100644 --- a/packages/vue-query/src/__tests__/useQuery.test.ts +++ b/packages/vue-query/src/__tests__/useQuery.test.ts @@ -7,7 +7,7 @@ import { ref, } from 'vue-demi' import { QueryObserver } from '@tanstack/query-core' -import { sleep } from '@tanstack/query-test-utils' +import { queryKey, sleep } from '@tanstack/query-test-utils' import { useQuery } from '../useQuery' import { useBaseQuery } from '../useBaseQuery' import type { Mock, MockedFunction } from 'vitest' @@ -25,10 +25,11 @@ describe('useQuery', () => { }) test('should properly execute query', () => { + const key = queryKey() const queryFn = () => sleep(0).then(() => 'Some data') useQuery({ - queryKey: ['key0'], + queryKey: key, queryFn, staleTime: 1000, }) @@ -36,7 +37,7 @@ describe('useQuery', () => { expect(useBaseQuery).toBeCalledWith( QueryObserver, { - queryKey: ['key0'], + queryKey: key, queryFn, staleTime: 1000, }, @@ -45,8 +46,9 @@ describe('useQuery', () => { }) test('should work with options getter', async () => { + const key = queryKey() const query = useQuery(() => ({ - queryKey: ['key01'], + queryKey: key, queryFn: () => sleep(0).then(() => 'result01'), })) @@ -63,10 +65,11 @@ describe('useQuery', () => { }) test('should work with options getter and be reactive', async () => { + const key = queryKey() const keyRef = ref('key011') const resultRef = ref('result02') const query = useQuery(() => ({ - queryKey: [keyRef.value], + queryKey: [...key, keyRef.value], queryFn: () => sleep(0).then(() => resultRef.value), })) @@ -96,8 +99,9 @@ describe('useQuery', () => { }) test('should return pending status initially', () => { + const key = queryKey() const query = useQuery({ - queryKey: ['key1'], + queryKey: key, queryFn: () => sleep(0).then(() => 'Some data'), }) @@ -110,8 +114,9 @@ describe('useQuery', () => { }) test('should resolve to success and update reactive state: useQuery(key, dataFn)', async () => { + const key = queryKey() const query = useQuery({ - queryKey: ['key2'], + queryKey: key, queryFn: () => sleep(0).then(() => 'result2'), }) @@ -128,8 +133,9 @@ describe('useQuery', () => { }) test('should resolve to success and update reactive state: useQuery(optionsObj)', async () => { + const key = queryKey() const query = useQuery({ - queryKey: ['key31'], + queryKey: key, queryFn: () => sleep(0).then(() => 'result31'), enabled: true, }) @@ -147,8 +153,9 @@ describe('useQuery', () => { }) test('should resolve to success and update reactive state: useQuery(key, optionsObj)', async () => { + const key = queryKey() const query = useQuery({ - queryKey: ['key32'], + queryKey: key, queryFn: () => sleep(0).then(() => 'result32'), enabled: true, }) @@ -166,8 +173,9 @@ describe('useQuery', () => { }) test('should reject and update reactive state', async () => { + const key = queryKey() const query = useQuery({ - queryKey: ['key3'], + queryKey: key, queryFn: () => sleep(0).then(() => Promise.reject(new Error('Some error'))), }) @@ -188,9 +196,10 @@ describe('useQuery', () => { }) test('should update query on reactive (Ref) key change', async () => { + const key = queryKey() const secondKeyRef = ref('key7') const query = useQuery({ - queryKey: ['key6', secondKeyRef], + queryKey: [...key, secondKeyRef], queryFn: () => sleep(10).then(() => 'Some data'), }) @@ -216,9 +225,10 @@ describe('useQuery', () => { }) test("should update query when an option is passed as Ref and it's changed", async () => { + const key = queryKey() const enabled = ref(false) const query = useQuery({ - queryKey: ['key9'], + queryKey: key, queryFn: () => sleep(10).then(() => 'Some data'), enabled, }) @@ -247,8 +257,10 @@ describe('useQuery', () => { }) test('should properly execute dependent queries', async () => { + const key1 = queryKey() + const key2 = queryKey() const { data } = useQuery({ - queryKey: ['dependent1'], + queryKey: key1, queryFn: () => sleep(0).then(() => 'Some data'), }) @@ -259,7 +271,7 @@ describe('useQuery', () => { .mockImplementation(() => sleep(10).then(() => 'Some data')) const { fetchStatus, status } = useQuery( reactive({ - queryKey: ['dependent2'], + queryKey: key2, queryFn: dependentQueryFn, enabled, }), @@ -280,18 +292,19 @@ describe('useQuery', () => { expect(status.value).toStrictEqual('success') expect(dependentQueryFn).toHaveBeenCalledTimes(1) expect(dependentQueryFn).toHaveBeenCalledWith( - expect.objectContaining({ queryKey: ['dependent2'] }), + expect.objectContaining({ queryKey: key2 }), ) }) test('should stop listening to changes on onScopeDispose', async () => { + const key = queryKey() const onScopeDisposeMock = onScopeDispose as MockedFunction< typeof onScopeDispose > onScopeDisposeMock.mockImplementationOnce((fn) => fn()) const { status } = useQuery({ - queryKey: ['onScopeDispose'], + queryKey: key, queryFn: () => sleep(0).then(() => 'Some data'), }) @@ -307,10 +320,11 @@ describe('useQuery', () => { }) test('should use the current value for the queryKey when refetch is called', async () => { + const key = queryKey() const fetchFn = vi.fn(() => 'foo') const keyRef = ref('key11') const query = useQuery({ - queryKey: ['key10', keyRef], + queryKey: [...key, keyRef], queryFn: fetchFn, enabled: false, }) @@ -320,7 +334,7 @@ describe('useQuery', () => { expect(fetchFn).toHaveBeenCalledTimes(1) expect(fetchFn).toHaveBeenCalledWith( expect.objectContaining({ - queryKey: ['key10', 'key11'], + queryKey: [...key, 'key11'], }), ) @@ -329,17 +343,18 @@ describe('useQuery', () => { expect(fetchFn).toHaveBeenCalledTimes(2) expect(fetchFn).toHaveBeenCalledWith( expect.objectContaining({ - queryKey: ['key10', 'key12'], + queryKey: [...key, 'key12'], }), ) }) test('should be `enabled` to accept getter function', async () => { + const key = queryKey() const fetchFn = vi.fn(() => 'foo') const checked = ref(false) useQuery({ - queryKey: ['enabled'], + queryKey: key, queryFn: fetchFn, enabled: () => checked.value, }) @@ -354,12 +369,13 @@ describe('useQuery', () => { }) test('should allow getters for query keys', async () => { + const key = queryKey() const fetchFn = vi.fn(() => 'foo') const key1 = ref('key1') const key2 = ref('key2') useQuery({ - queryKey: ['key', () => key1.value, () => key2.value], + queryKey: [...key, () => key1.value, () => key2.value], queryFn: fetchFn, }) @@ -379,6 +395,7 @@ describe('useQuery', () => { }) test('should allow arbitrarily nested getters for query keys', async () => { + const key = queryKey() const fetchFn = vi.fn(() => 'foo') const key1 = ref('key1') const key2 = ref('key2') @@ -388,7 +405,7 @@ describe('useQuery', () => { useQuery({ queryKey: [ - 'key', + ...key, key1, () => key2.value, { key: () => key3.value }, @@ -439,9 +456,10 @@ describe('useQuery', () => { describe('throwOnError', () => { test('should evaluate throwOnError when query is expected to throw', async () => { + const key = queryKey() const boundaryFn = vi.fn() useQuery({ - queryKey: ['key'], + queryKey: key, queryFn: () => sleep(0).then(() => Promise.reject(new Error('Some error'))), retry: false, @@ -467,7 +485,7 @@ describe('useQuery', () => { try { useQuery({ - queryKey: ['outsideScope'], + queryKey: queryKey(), queryFn: () => sleep(0).then(() => 'data'), }) @@ -483,11 +501,12 @@ describe('useQuery', () => { describe('suspense', () => { test('should return a Promise', () => { + const key = queryKey() const getCurrentInstanceSpy = getCurrentInstance as Mock getCurrentInstanceSpy.mockImplementation(() => ({ suspense: {} })) const query = useQuery({ - queryKey: ['suspense'], + queryKey: key, queryFn: () => sleep(0).then(() => 'Some data'), }) const result = query.suspense() @@ -496,13 +515,14 @@ describe('useQuery', () => { }) test('should resolve after being enabled', async () => { + const key = queryKey() const getCurrentInstanceSpy = getCurrentInstance as Mock getCurrentInstanceSpy.mockImplementation(() => ({ suspense: {} })) let afterTimeout = false const isEnabled = ref(false) const query = useQuery({ - queryKey: ['suspense2'], + queryKey: key, queryFn: () => sleep(0).then(() => 'Some data'), enabled: isEnabled, }) @@ -520,6 +540,7 @@ describe('useQuery', () => { }) test('should resolve immediately when stale without refetching', () => { + const key = queryKey() const getCurrentInstanceSpy = getCurrentInstance as Mock getCurrentInstanceSpy.mockImplementation(() => ({ suspense: {} })) @@ -527,7 +548,7 @@ describe('useQuery', () => { // let afterTimeout = false; const query = useQuery({ - queryKey: ['suspense3'], + queryKey: key, queryFn: () => sleep(0).then(() => 'Some data'), staleTime: 10000, initialData: 'foo', @@ -539,11 +560,12 @@ describe('useQuery', () => { }) test('should not throw from suspense by default', async () => { + const key = queryKey() const getCurrentInstanceSpy = getCurrentInstance as Mock getCurrentInstanceSpy.mockImplementation(() => ({ suspense: {} })) const query = useQuery({ - queryKey: ['suspense4'], + queryKey: key, queryFn: () => sleep(0).then(() => Promise.reject(new Error('Some error'))), staleTime: 10000, @@ -558,12 +580,13 @@ describe('useQuery', () => { }) test('should throw from suspense when throwOnError is true', async () => { + const key = queryKey() const getCurrentInstanceSpy = getCurrentInstance as Mock getCurrentInstanceSpy.mockImplementation(() => ({ suspense: {} })) const boundaryFn = vi.fn() const query = useQuery({ - queryKey: ['suspense5'], + queryKey: key, queryFn: () => sleep(0).then(() => Promise.reject(new Error('Some error'))), staleTime: 10000, diff --git a/packages/vue-query/src/__tests__/vueQueryPlugin.test.ts b/packages/vue-query/src/__tests__/vueQueryPlugin.test.ts index 6835133ed0..28084c0185 100644 --- a/packages/vue-query/src/__tests__/vueQueryPlugin.test.ts +++ b/packages/vue-query/src/__tests__/vueQueryPlugin.test.ts @@ -1,5 +1,6 @@ import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest' import { isVue2, isVue3, ref } from 'vue-demi' +import { queryKey } from '@tanstack/query-test-utils' import { QueryClient } from '../queryClient' import { VueQueryPlugin } from '../vueQueryPlugin' import { VUE_QUERY_CLIENT } from '../utils' @@ -284,6 +285,7 @@ describe('VueQueryPlugin', () => { }) test('should delay useQuery subscription and not call fetcher if data is not stale', async () => { + const key = queryKey() const appMock = getAppMock() const customClient = new QueryClient({ defaultOptions: { @@ -299,7 +301,7 @@ describe('VueQueryPlugin', () => { vi.fn(), new Promise((resolve) => { setTimeout(() => { - client.setQueryData(['persist'], () => ({ + client.setQueryData(key, () => ({ foo: 'bar', })) resolve() @@ -312,7 +314,7 @@ describe('VueQueryPlugin', () => { const query = useQuery( { - queryKey: ['persist'], + queryKey: key, queryFn: fnSpy, }, customClient, @@ -331,6 +333,8 @@ describe('VueQueryPlugin', () => { }) test('should delay useQueries subscription and not call fetcher if data is not stale', async () => { + const key1 = queryKey() + const key2 = queryKey() const appMock = getAppMock() const customClient = new QueryClient({ defaultOptions: { @@ -346,10 +350,10 @@ describe('VueQueryPlugin', () => { vi.fn(), new Promise((resolve) => { setTimeout(() => { - client.setQueryData(['persist1'], () => ({ + client.setQueryData(key1, () => ({ foo1: 'bar1', })) - client.setQueryData(['persist2'], () => ({ + client.setQueryData(key2, () => ({ foo2: 'bar2', })) resolve() @@ -362,7 +366,7 @@ describe('VueQueryPlugin', () => { const query = useQuery( { - queryKey: ['persist1'], + queryKey: key1, queryFn: fnSpy, }, customClient, @@ -372,7 +376,7 @@ describe('VueQueryPlugin', () => { { queries: [ { - queryKey: ['persist2'], + queryKey: key2, queryFn: fnSpy, }, ],