Skip to content

Commit afb5812

Browse files
test({react,preact}-query/useSuspenseQueries): inline test helpers, remove shared 'queryClient', and use 'beforeEach'/'afterEach' for setup and teardown (#10352)
* test({react,preact}-query/useSuspenseQueries): inline test helpers, remove shared 'queryClient', and use 'beforeEach'/'afterEach' for setup and teardown * ci: apply automated fixes * test({react,preact}-query/useSuspenseQueries): replace '[1] as const' with 'queryKey()' util and fix 'act' callback type in preact-query --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
1 parent 9e1bb94 commit afb5812

2 files changed

Lines changed: 322 additions & 129 deletions

File tree

packages/preact-query/src/__tests__/useSuspenseQueries.test.tsx

Lines changed: 165 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { queryKey, sleep } from '@tanstack/query-test-utils'
22
import { act, fireEvent, render } from '@testing-library/preact'
3-
import type { FunctionalComponent } from 'preact'
43
import { Suspense, startTransition, useTransition } from 'preact/compat'
54
import { useEffect, useRef, useState } from 'preact/hooks'
65
import {
@@ -24,33 +23,18 @@ import type { UseSuspenseQueryOptions } from '..'
2423
import { ErrorBoundary } from './ErrorBoundary'
2524
import { renderWithClient } from './utils'
2625

27-
type NumberQueryOptions = UseSuspenseQueryOptions<number>
28-
29-
const QUERY_DURATION = 1000
30-
31-
const createQuery: (id: number) => NumberQueryOptions = (id) => ({
32-
queryKey: [id],
33-
queryFn: () => sleep(QUERY_DURATION).then(() => id),
34-
})
35-
const resolveQueries = async () => {
36-
await vi.advanceTimersByTimeAsync(QUERY_DURATION)
37-
}
38-
39-
const queryClient = new QueryClient()
40-
4126
describe('useSuspenseQueries', () => {
27+
let queryClient: QueryClient
4228
const onSuspend = vi.fn()
4329
const onQueriesResolution = vi.fn()
4430

45-
beforeAll(() => {
31+
beforeEach(() => {
4632
vi.useFakeTimers()
47-
})
48-
49-
afterAll(() => {
50-
vi.useRealTimers()
33+
queryClient = new QueryClient()
5134
})
5235

5336
afterEach(() => {
37+
vi.useRealTimers()
5438
queryClient.clear()
5539
onSuspend.mockClear()
5640
onQueriesResolution.mockClear()
@@ -64,89 +48,199 @@ describe('useSuspenseQueries', () => {
6448
return <div>loading</div>
6549
}
6650

67-
const withSuspenseWrapper = <T extends object>(
68-
Component: FunctionalComponent<T>,
69-
) => {
70-
function SuspendedComponent(props: T) {
71-
return (
72-
<Suspense fallback={<SuspenseFallback />}>
73-
<Component {...props} />
74-
</Suspense>
51+
it('should suspend on mount', () => {
52+
function Page() {
53+
const queriesResults = useSuspenseQueries(
54+
{
55+
queries: [1, 2].map((id) => ({
56+
queryKey: [id],
57+
queryFn: () => sleep(1000).then(() => id),
58+
})),
59+
combine: (results) => results.map((r) => r.data),
60+
},
61+
queryClient,
7562
)
76-
}
77-
78-
return SuspendedComponent
79-
}
80-
81-
function QueriesContainer({
82-
queries,
83-
}: {
84-
queries: Array<NumberQueryOptions>
85-
}) {
86-
const queriesResults = useSuspenseQueries(
87-
{ queries, combine: (results) => results.map((r) => r.data) },
88-
queryClient,
89-
)
90-
91-
useEffect(() => {
92-
onQueriesResolution(queriesResults)
93-
}, [queriesResults])
9463

95-
return null
96-
}
64+
useEffect(() => {
65+
onQueriesResolution(queriesResults)
66+
}, [queriesResults])
9767

98-
const TestComponent = withSuspenseWrapper(QueriesContainer)
68+
return null
69+
}
9970

100-
it('should suspend on mount', () => {
101-
render(<TestComponent queries={[1, 2].map(createQuery)} />)
71+
render(
72+
<Suspense fallback={<SuspenseFallback />}>
73+
<Page />
74+
</Suspense>,
75+
)
10276

10377
expect(onSuspend).toHaveBeenCalledOnce()
10478
})
10579

10680
it('should resolve queries', async () => {
107-
render(<TestComponent queries={[1, 2].map(createQuery)} />)
81+
function Page() {
82+
const queriesResults = useSuspenseQueries(
83+
{
84+
queries: [1, 2].map((id) => ({
85+
queryKey: [id],
86+
queryFn: () => sleep(1000).then(() => id),
87+
})),
88+
combine: (results) => results.map((r) => r.data),
89+
},
90+
queryClient,
91+
)
10892

109-
await act(resolveQueries)
93+
useEffect(() => {
94+
onQueriesResolution(queriesResults)
95+
}, [queriesResults])
96+
97+
return null
98+
}
99+
100+
render(
101+
<Suspense fallback={<SuspenseFallback />}>
102+
<Page />
103+
</Suspense>,
104+
)
105+
106+
await act(async () => {
107+
await vi.advanceTimersByTimeAsync(1000)
108+
})
110109

111110
expect(onQueriesResolution).toHaveBeenCalledTimes(1)
112111
expect(onQueriesResolution).toHaveBeenLastCalledWith([1, 2])
113112
})
114113

115114
it('should not suspend on mount if query has been already fetched', () => {
116-
const query = createQuery(1)
115+
const key = queryKey()
116+
const queryFn = () => sleep(1000).then(() => 1)
117117

118-
queryClient.setQueryData(query.queryKey, query.queryFn)
118+
queryClient.setQueryData(key, queryFn)
119119

120-
render(<TestComponent queries={[query]} />)
120+
function Page() {
121+
const queriesResults = useSuspenseQueries(
122+
{
123+
queries: [{ queryKey: key, queryFn }],
124+
combine: (results) => results.map((r) => r.data),
125+
},
126+
queryClient,
127+
)
128+
129+
useEffect(() => {
130+
onQueriesResolution(queriesResults)
131+
}, [queriesResults])
132+
133+
return null
134+
}
135+
136+
render(
137+
<Suspense fallback={<SuspenseFallback />}>
138+
<Page />
139+
</Suspense>,
140+
)
121141

122142
expect(onSuspend).not.toHaveBeenCalled()
123143
})
124144

125145
it('should not break suspense when queries change without resolving', async () => {
126-
const initQueries = [1, 2].map(createQuery)
127-
const nextQueries = [3, 4, 5, 6].map(createQuery)
146+
const initQueries = [1, 2].map((id) => ({
147+
queryKey: [id],
148+
queryFn: () => sleep(1000).then(() => id),
149+
}))
150+
const nextQueries = [3, 4, 5, 6].map((id) => ({
151+
queryKey: [id],
152+
queryFn: () => sleep(1000).then(() => id),
153+
}))
154+
155+
function Page({
156+
queries,
157+
}: {
158+
queries: Array<UseSuspenseQueryOptions<number>>
159+
}) {
160+
const queriesResults = useSuspenseQueries(
161+
{
162+
queries,
163+
combine: (results) => results.map((r) => r.data),
164+
},
165+
queryClient,
166+
)
167+
168+
useEffect(() => {
169+
onQueriesResolution(queriesResults)
170+
}, [queriesResults])
128171

129-
const { rerender } = render(<TestComponent queries={initQueries} />)
172+
return null
173+
}
130174

131-
rerender(<TestComponent queries={nextQueries} />)
175+
const { rerender } = render(
176+
<Suspense fallback={<SuspenseFallback />}>
177+
<Page queries={initQueries} />
178+
</Suspense>,
179+
)
132180

133-
await act(resolveQueries)
181+
rerender(
182+
<Suspense fallback={<SuspenseFallback />}>
183+
<Page queries={nextQueries} />
184+
</Suspense>,
185+
)
186+
187+
await act(async () => {
188+
await vi.advanceTimersByTimeAsync(1000)
189+
})
134190

135191
expect(onSuspend).toHaveBeenCalled()
136192
// the test for onQueriesResolution is React-specific and not applicable to Preact
137193
})
138194

139195
it('should suspend only once per queries change', async () => {
140-
const initQueries = [1, 2].map(createQuery)
141-
const nextQueries = [3, 4, 5, 6].map(createQuery)
196+
const initQueries = [1, 2].map((id) => ({
197+
queryKey: [id],
198+
queryFn: () => sleep(1000).then(() => id),
199+
}))
200+
const nextQueries = [3, 4, 5, 6].map((id) => ({
201+
queryKey: [id],
202+
queryFn: () => sleep(1000).then(() => id),
203+
}))
204+
205+
function Page({
206+
queries,
207+
}: {
208+
queries: Array<UseSuspenseQueryOptions<number>>
209+
}) {
210+
const queriesResults = useSuspenseQueries(
211+
{
212+
queries,
213+
combine: (results) => results.map((r) => r.data),
214+
},
215+
queryClient,
216+
)
217+
218+
useEffect(() => {
219+
onQueriesResolution(queriesResults)
220+
}, [queriesResults])
221+
222+
return null
223+
}
142224

143-
const { rerender } = render(<TestComponent queries={initQueries} />)
225+
const { rerender } = render(
226+
<Suspense fallback={<SuspenseFallback />}>
227+
<Page queries={initQueries} />
228+
</Suspense>,
229+
)
144230

145-
await act(resolveQueries)
231+
await act(async () => {
232+
await vi.advanceTimersByTimeAsync(1000)
233+
})
146234

147-
rerender(<TestComponent queries={nextQueries} />)
235+
rerender(
236+
<Suspense fallback={<SuspenseFallback />}>
237+
<Page queries={nextQueries} />
238+
</Suspense>,
239+
)
148240

149-
await act(resolveQueries)
241+
await act(async () => {
242+
await vi.advanceTimersByTimeAsync(1000)
243+
})
150244

151245
expect(onSuspend).toHaveBeenCalledTimes(2)
152246
expect(onQueriesResolution).toHaveBeenCalledTimes(2)
@@ -263,12 +357,16 @@ describe('useSuspenseQueries', () => {
263357
})
264358

265359
describe('useSuspenseQueries 2', () => {
360+
let queryClient: QueryClient
361+
266362
beforeEach(() => {
267363
vi.useFakeTimers()
364+
queryClient = new QueryClient()
268365
})
269366

270367
afterEach(() => {
271368
vi.useRealTimers()
369+
queryClient.clear()
272370
})
273371

274372
it('should suspend all queries in parallel', async () => {

0 commit comments

Comments
 (0)