Skip to content

Commit 38e5c4b

Browse files
authoredJul 16, 2024··
test(svelte-query): Check query states (#7741)
* chore(svelte-query-persist-client): Use store subscribe shortcut * Use statesStore logic in svelte-query * Use toHaveLength * Stricter types
1 parent 28af03f commit 38e5c4b

File tree

12 files changed

+327
-172
lines changed

12 files changed

+327
-172
lines changed
 
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
<script lang="ts">
22
import { createQuery } from '@tanstack/svelte-query'
3-
import { get } from 'svelte/store'
43
import { sleep } from '../utils'
54
import type { Writable } from 'svelte/store'
65
@@ -16,16 +15,9 @@
1615
return 'fetched'
1716
},
1817
})
19-
20-
let data = get(state).data
21-
let fetchStatus = get(state).fetchStatus
22-
state.subscribe((s) => {
23-
data = s.data
24-
fetchStatus = s.fetchStatus
25-
})
2618
</script>
2719

2820
<div>
29-
<h1>{data}</h1>
30-
<h2>fetchStatus: {fetchStatus}</h2>
21+
<h1>{$state.data}</h1>
22+
<h2>fetchStatus: {$state.fetchStatus}</h2>
3123
</div>
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
<script lang="ts">
22
import { createQuery } from '@tanstack/svelte-query'
3-
import { get } from 'svelte/store'
43
import { sleep } from '../utils'
54
import type { Writable } from 'svelte/store'
65
import type { StatusResult } from '../utils'
@@ -20,19 +19,10 @@
2019
staleTime: Infinity,
2120
})
2221
23-
let data = get(state).data
24-
let fetchStatus = get(state).fetchStatus
25-
state.subscribe((s) => {
26-
states.update((prev) => [
27-
...prev,
28-
{ status: s.status, data: s.data, fetchStatus: s.fetchStatus },
29-
])
30-
data = s.data
31-
fetchStatus = s.fetchStatus
32-
})
22+
$: states.update((prev) => [...prev, $state])
3323
</script>
3424

3525
<div>
36-
<h1>data: {data ?? 'null'}</h1>
37-
<h2>fetchStatus: {fetchStatus}</h2>
26+
<h1>data: {$state.data ?? 'null'}</h1>
27+
<h2>fetchStatus: {$state.fetchStatus}</h2>
3828
</div>
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
<script lang="ts">
22
import { createQuery } from '@tanstack/svelte-query'
3-
import { get } from 'svelte/store'
43
import { sleep } from '../utils'
54
import type { Writable } from 'svelte/store'
65
import type { StatusResult } from '../utils'
@@ -21,19 +20,10 @@
2120
initialDataUpdatedAt: 1,
2221
})
2322
24-
let data = get(state).data
25-
let fetchStatus = get(state).fetchStatus
26-
state.subscribe((s) => {
27-
states.update((prev) => [
28-
...prev,
29-
{ status: s.status, data: s.data, fetchStatus: s.fetchStatus },
30-
])
31-
data = s.data
32-
fetchStatus = s.fetchStatus
33-
})
23+
$: states.update((prev) => [...prev, $state])
3424
</script>
3525

3626
<div>
37-
<h1>{data}</h1>
38-
<h2>fetchStatus: {fetchStatus}</h2>
27+
<h1>{$state.data}</h1>
28+
<h2>fetchStatus: {$state.fetchStatus}</h2>
3929
</div>
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
<script lang="ts">
22
import { createQuery } from '@tanstack/svelte-query'
3-
import { get } from 'svelte/store'
43
import { sleep } from '../utils'
54
65
export let key: Array<string>
@@ -12,16 +11,9 @@
1211
return 'fetched'
1312
},
1413
})
15-
16-
let data = get(state).data
17-
let fetchStatus = get(state).fetchStatus
18-
state.subscribe((s) => {
19-
data = s.data
20-
fetchStatus = s.fetchStatus
21-
})
2214
</script>
2315

2416
<div>
25-
<h1>{data}</h1>
26-
<h2>fetchStatus: {fetchStatus}</h2>
17+
<h1>{$state.data}</h1>
18+
<h2>fetchStatus: {$state.fetchStatus}</h2>
2719
</div>

‎packages/svelte-query-persist-client/tests/PersistQueryClientProvider.test.ts

+38-35
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ const createMockErrorPersister = (
5757
describe('PersistQueryClientProvider', () => {
5858
test('restores cache from persister', async () => {
5959
const key = queryKey()
60-
const states: Writable<Array<StatusResult<string>>> = writable([])
60+
const statesStore: Writable<Array<StatusResult<string>>> = writable([])
6161

6262
const queryClient = createQueryClient()
6363
await queryClient.prefetchQuery({
@@ -76,36 +76,36 @@ describe('PersistQueryClientProvider', () => {
7676
queryClient,
7777
persistOptions: { persister },
7878
key,
79-
states,
79+
states: statesStore,
8080
},
8181
})
8282

8383
await waitFor(() => rendered.getByText('fetchStatus: idle'))
8484
await waitFor(() => rendered.getByText('hydrated'))
8585
await waitFor(() => rendered.getByText('fetched'))
8686

87-
const states_ = get(states)
88-
expect(states_).toHaveLength(4)
87+
const states = get(statesStore)
88+
expect(states).toHaveLength(4)
8989

90-
expect(states_[0]).toMatchObject({
90+
expect(states[0]).toMatchObject({
9191
status: 'pending',
9292
fetchStatus: 'idle',
9393
data: undefined,
9494
})
9595

96-
expect(states_[1]).toMatchObject({
96+
expect(states[1]).toMatchObject({
9797
status: 'success',
9898
fetchStatus: 'fetching',
9999
data: 'hydrated',
100100
})
101101

102-
expect(states_[2]).toMatchObject({
102+
expect(states[2]).toMatchObject({
103103
status: 'success',
104104
fetchStatus: 'fetching',
105105
data: 'hydrated',
106106
})
107107

108-
expect(states_[3]).toMatchObject({
108+
expect(states[3]).toMatchObject({
109109
status: 'success',
110110
fetchStatus: 'idle',
111111
data: 'fetched',
@@ -114,7 +114,7 @@ describe('PersistQueryClientProvider', () => {
114114

115115
test('should also put useQueries into idle state', async () => {
116116
const key = queryKey()
117-
const states: Writable<Array<StatusResult<string>>> = writable([])
117+
const statesStore: Writable<Array<StatusResult<string>>> = writable([])
118118

119119
const queryClient = createQueryClient()
120120
await queryClient.prefetchQuery({
@@ -133,37 +133,37 @@ describe('PersistQueryClientProvider', () => {
133133
queryClient,
134134
persistOptions: { persister },
135135
key,
136-
states,
136+
states: statesStore,
137137
},
138138
})
139139

140140
await waitFor(() => rendered.getByText('fetchStatus: idle'))
141141
await waitFor(() => rendered.getByText('hydrated'))
142142
await waitFor(() => rendered.getByText('fetched'))
143143

144-
const states_ = get(states)
144+
const states = get(statesStore)
145145

146-
expect(states_).toHaveLength(4)
146+
expect(states).toHaveLength(4)
147147

148-
expect(states_[0]).toMatchObject({
148+
expect(states[0]).toMatchObject({
149149
status: 'pending',
150150
fetchStatus: 'idle',
151151
data: undefined,
152152
})
153153

154-
expect(states_[1]).toMatchObject({
154+
expect(states[1]).toMatchObject({
155155
status: 'success',
156156
fetchStatus: 'fetching',
157157
data: 'hydrated',
158158
})
159159

160-
expect(states_[2]).toMatchObject({
160+
expect(states[2]).toMatchObject({
161161
status: 'success',
162162
fetchStatus: 'fetching',
163163
data: 'hydrated',
164164
})
165165

166-
expect(states_[3]).toMatchObject({
166+
expect(states[3]).toMatchObject({
167167
status: 'success',
168168
fetchStatus: 'idle',
169169
data: 'fetched',
@@ -172,7 +172,7 @@ describe('PersistQueryClientProvider', () => {
172172

173173
test('should show initialData while restoring', async () => {
174174
const key = queryKey()
175-
const states: Writable<Array<StatusResult<string>>> = writable([])
175+
const statesStore: Writable<Array<StatusResult<string>>> = writable([])
176176

177177
const queryClient = createQueryClient()
178178
await queryClient.prefetchQuery({
@@ -191,36 +191,36 @@ describe('PersistQueryClientProvider', () => {
191191
queryClient,
192192
persistOptions: { persister },
193193
key,
194-
states,
194+
states: statesStore,
195195
},
196196
})
197197

198198
await waitFor(() => rendered.getByText('initial'))
199199
await waitFor(() => rendered.getByText('hydrated'))
200200
await waitFor(() => rendered.getByText('fetched'))
201201

202-
const states_ = get(states)
203-
expect(states_).toHaveLength(4)
202+
const states = get(statesStore)
203+
expect(states).toHaveLength(4)
204204

205-
expect(states_[0]).toMatchObject({
205+
expect(states[0]).toMatchObject({
206206
status: 'success',
207207
fetchStatus: 'idle',
208208
data: 'initial',
209209
})
210210

211-
expect(states_[1]).toMatchObject({
211+
expect(states[1]).toMatchObject({
212212
status: 'success',
213213
fetchStatus: 'fetching',
214214
data: 'hydrated',
215215
})
216216

217-
expect(states_[2]).toMatchObject({
217+
expect(states[2]).toMatchObject({
218218
status: 'success',
219219
fetchStatus: 'fetching',
220220
data: 'hydrated',
221221
})
222222

223-
expect(states_[3]).toMatchObject({
223+
expect(states[3]).toMatchObject({
224224
status: 'success',
225225
fetchStatus: 'idle',
226226
data: 'fetched',
@@ -229,7 +229,7 @@ describe('PersistQueryClientProvider', () => {
229229

230230
test('should not refetch after restoring when data is fresh', async () => {
231231
const key = queryKey()
232-
const states: Writable<Array<StatusResult<string>>> = writable([])
232+
const statesStore: Writable<Array<StatusResult<string>>> = writable([])
233233

234234
const queryClient = createQueryClient()
235235
await queryClient.prefetchQuery({
@@ -250,26 +250,26 @@ describe('PersistQueryClientProvider', () => {
250250
queryClient,
251251
persistOptions: { persister },
252252
key,
253-
states,
253+
states: statesStore,
254254
fetched,
255255
},
256256
})
257257

258258
await waitFor(() => rendered.getByText('data: null'))
259259
await waitFor(() => rendered.getByText('data: hydrated'))
260260

261-
const states_ = get(states)
262-
expect(states_).toHaveLength(2)
261+
const states = get(statesStore)
262+
expect(states).toHaveLength(2)
263263

264264
expect(get(fetched)).toBe(false)
265265

266-
expect(states_[0]).toMatchObject({
266+
expect(states[0]).toMatchObject({
267267
status: 'pending',
268268
fetchStatus: 'idle',
269269
data: undefined,
270270
})
271271

272-
expect(states_[1]).toMatchObject({
272+
expect(states[1]).toMatchObject({
273273
status: 'success',
274274
fetchStatus: 'idle',
275275
data: 'hydrated',
@@ -324,25 +324,28 @@ describe('PersistQueryClientProvider', () => {
324324

325325
queryClient.clear()
326326

327-
const states: Writable<Array<string>> = writable([])
327+
const statesStore: Writable<Array<string>> = writable([])
328328

329329
const rendered = render(AwaitOnSuccess, {
330330
props: {
331331
queryClient,
332332
persistOptions: { persister },
333333
key,
334-
states,
334+
states: statesStore,
335335
onSuccess: async () => {
336-
states.update((s) => [...s, 'onSuccess'])
336+
statesStore.update((s) => [...s, 'onSuccess'])
337337
await sleep(20)
338-
states.update((s) => [...s, 'onSuccess done'])
338+
statesStore.update((s) => [...s, 'onSuccess done'])
339339
},
340340
},
341341
})
342342

343343
await waitFor(() => rendered.getByText('hydrated'))
344344
await waitFor(() => rendered.getByText('fetched'))
345-
expect(get(states)).toEqual([
345+
346+
const states = get(statesStore)
347+
348+
expect(states).toEqual([
346349
'onSuccess',
347350
'onSuccess done',
348351
'fetching',
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
<script lang="ts">
22
import { createQuery } from '@tanstack/svelte-query'
3-
import { get } from 'svelte/store'
43
import { sleep } from '../utils'
54
65
export let key: Array<string>
@@ -12,16 +11,9 @@
1211
return 'fetched'
1312
},
1413
})
15-
16-
let data = get(state).data
17-
let fetchStatus = get(state).fetchStatus
18-
state.subscribe((s) => {
19-
data = s.data
20-
fetchStatus = s.fetchStatus
21-
})
2214
</script>
2315

2416
<div>
25-
<h1>{data}</h1>
26-
<h2>fetchStatus: {fetchStatus}</h2>
17+
<h1>{$state.data}</h1>
18+
<h2>fetchStatus: {$state.fetchStatus}</h2>
2719
</div>
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
<script lang="ts">
22
import { createQuery } from '@tanstack/svelte-query'
3-
import { get } from 'svelte/store'
43
import { sleep } from '../utils'
54
import type { Writable } from 'svelte/store'
65
import type { StatusResult } from '../utils'
@@ -16,19 +15,10 @@
1615
},
1716
})
1817
19-
let data = get(state).data
20-
let fetchStatus = get(state).fetchStatus
21-
state.subscribe((s) => {
22-
states.update((prev) => [
23-
...prev,
24-
{ status: s.status, data: s.data, fetchStatus: s.fetchStatus },
25-
])
26-
data = s.data
27-
fetchStatus = s.fetchStatus
28-
})
18+
$: states.update((prev) => [...prev, $state])
2919
</script>
3020

3121
<div>
32-
<h1>{data}</h1>
33-
<h2>fetchStatus: {fetchStatus}</h2>
22+
<h1>{$state.data}</h1>
23+
<h2>fetchStatus: {$state.fetchStatus}</h2>
3424
</div>
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
<script lang="ts">
22
import { createQueries } from '@tanstack/svelte-query'
3-
import { get } from 'svelte/store'
43
import { sleep } from '../utils'
54
import type { Writable } from 'svelte/store'
65
import type { StatusResult } from '../utils'
@@ -20,19 +19,10 @@
2019
],
2120
})
2221
23-
let data = get(state)[0].data
24-
let fetchStatus = get(state)[0].fetchStatus
25-
state.subscribe(([s]) => {
26-
states.update((prev) => [
27-
...prev,
28-
{ status: s.status, data: s.data, fetchStatus: s.fetchStatus },
29-
])
30-
data = s.data
31-
fetchStatus = s.fetchStatus
32-
})
22+
$: states.update((prev) => [...prev, $state[0]])
3323
</script>
3424

3525
<div>
36-
<h1>{data}</h1>
37-
<h2>fetchStatus: {fetchStatus}</h2>
26+
<h1>{$state[0].data}</h1>
27+
<h2>fetchStatus: {$state[0].fetchStatus}</h2>
3828
</div>

‎packages/svelte-query/tests/createQueries/BaseExample.svelte

+4-4
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,13 @@
1515
{#if Array.isArray($queries)}
1616
{#each $queries as query, index}
1717
{#if query.isPending}
18-
<p>Loading {index + 1}</p>
18+
<div>Loading {index + 1}</div>
1919
{:else if query.isSuccess}
20-
<p>{query.data}</p>
20+
<div>{query.data}</div>
2121
{/if}
2222
{/each}
2323
{:else if $queries.isPending}
24-
<p>Loading</p>
24+
<div>Loading</div>
2525
{:else if $queries.isSuccess}
26-
<p>{$queries.data}</p>
26+
<div>{$queries.data}</div>
2727
{/if}
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,25 @@
11
<script lang="ts">
22
import { createQuery } from '../../src/createQuery'
3-
import type { QueryClient } from '@tanstack/query-core'
3+
import type { QueryClient, QueryObserverResult } from '@tanstack/query-core'
4+
import type { Writable } from 'svelte/store'
45
import type { CreateQueryOptions, StoreOrVal } from '../../src/types'
56
67
export let options: StoreOrVal<CreateQueryOptions<any>>
78
export let queryClient: QueryClient
9+
export let states: Writable<Array<QueryObserverResult>>
810
911
const query = createQuery(options, queryClient)
12+
13+
$: states.update((prev) => [...prev, $query])
1014
</script>
1115

16+
<div>Status: {$query.status}</div>
17+
<div>Failure Count: {$query.failureCount}</div>
18+
1219
{#if $query.isPending}
13-
<p>Loading</p>
20+
<div>Loading</div>
1421
{:else if $query.isError}
15-
<p>Error</p>
22+
<div>Error</div>
1623
{:else if $query.isSuccess}
17-
{#if Array.isArray($query.data)}
18-
{#each $query.data as item}
19-
<p>{item}</p>
20-
{/each}
21-
{:else}
22-
<p>{$query.data}</p>
23-
{/if}
24+
<div>{$query.data}</div>
2425
{/if}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<script lang="ts">
2+
import { derived, writable } from 'svelte/store'
3+
import { createQuery, keepPreviousData } from '../../src/index'
4+
import { sleep } from '../utils'
5+
import type { QueryClient, QueryObserverResult } from '@tanstack/query-core'
6+
import type { Writable } from 'svelte/store'
7+
8+
export let queryClient: QueryClient
9+
export let states: Writable<Array<QueryObserverResult>>
10+
11+
const count = writable(0)
12+
13+
const options = derived(count, ($count) => ({
14+
queryKey: ['test', $count],
15+
queryFn: async () => {
16+
await sleep(10)
17+
return $count
18+
},
19+
placeholderData: keepPreviousData,
20+
}))
21+
22+
const query = createQuery(options, queryClient)
23+
24+
$: states.update((prev) => [...prev, $query])
25+
</script>
26+
27+
<button on:click={() => ($count += 1)}>setCount</button>
28+
29+
<div>Status: {$query.status}</div>
30+
<div>Data: {$query.data}</div>

‎packages/svelte-query/tests/createQuery/createQuery.test.ts

+226-41
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,206 @@
11
import { describe, expect, test } from 'vitest'
22
import { fireEvent, render, waitFor } from '@testing-library/svelte'
3-
import { derived, writable } from 'svelte/store'
3+
import { derived, get, writable } from 'svelte/store'
44
import { QueryClient } from '@tanstack/query-core'
55
import { sleep } from '../utils'
66
import BaseExample from './BaseExample.svelte'
77
import DisabledExample from './DisabledExample.svelte'
8+
import PlaceholderData from './PlaceholderData.svelte'
9+
import type { Writable } from 'svelte/store'
10+
import type { QueryObserverResult } from '@tanstack/query-core'
811

912
describe('createQuery', () => {
10-
test('Render and wait for success', async () => {
13+
test('Return the correct states for a successful query', async () => {
14+
const statesStore: Writable<Array<QueryObserverResult>> = writable([])
15+
16+
const options = {
17+
queryKey: ['test'],
18+
queryFn: async () => {
19+
await sleep(10)
20+
return 'Success'
21+
},
22+
}
23+
1124
const rendered = render(BaseExample, {
1225
props: {
13-
options: {
14-
queryKey: ['test'],
15-
queryFn: async () => {
16-
await sleep(10)
17-
return 'Success'
18-
},
19-
},
26+
options,
2027
queryClient: new QueryClient(),
28+
states: statesStore,
2129
},
2230
})
2331

2432
await waitFor(() => {
25-
expect(rendered.queryByText('Loading')).toBeInTheDocument()
33+
expect(rendered.queryByText('Success')).toBeInTheDocument()
2634
})
2735

28-
await waitFor(() => {
29-
expect(rendered.queryByText('Success')).toBeInTheDocument()
36+
const states = get(statesStore)
37+
38+
expect(states).toHaveLength(2)
39+
40+
expect(states[0]).toMatchObject({
41+
data: undefined,
42+
dataUpdatedAt: 0,
43+
error: null,
44+
errorUpdatedAt: 0,
45+
failureCount: 0,
46+
failureReason: null,
47+
errorUpdateCount: 0,
48+
isError: false,
49+
isFetched: false,
50+
isFetchedAfterMount: false,
51+
isFetching: true,
52+
isPaused: false,
53+
isPending: true,
54+
isInitialLoading: true,
55+
isLoading: true,
56+
isLoadingError: false,
57+
isPlaceholderData: false,
58+
isRefetchError: false,
59+
isRefetching: false,
60+
isStale: true,
61+
isSuccess: false,
62+
refetch: expect.any(Function),
63+
status: 'pending',
64+
fetchStatus: 'fetching',
65+
})
66+
67+
expect(states[1]).toMatchObject({
68+
data: 'Success',
69+
dataUpdatedAt: expect.any(Number),
70+
error: null,
71+
errorUpdatedAt: 0,
72+
failureCount: 0,
73+
failureReason: null,
74+
errorUpdateCount: 0,
75+
isError: false,
76+
isFetched: true,
77+
isFetchedAfterMount: true,
78+
isFetching: false,
79+
isPaused: false,
80+
isPending: false,
81+
isInitialLoading: false,
82+
isLoading: false,
83+
isLoadingError: false,
84+
isPlaceholderData: false,
85+
isRefetchError: false,
86+
isRefetching: false,
87+
isStale: true,
88+
isSuccess: true,
89+
refetch: expect.any(Function),
90+
status: 'success',
91+
fetchStatus: 'idle',
92+
})
93+
})
94+
95+
test('Return the correct states for an unsuccessful query', async () => {
96+
const statesStore: Writable<Array<QueryObserverResult>> = writable([])
97+
98+
const options = {
99+
queryKey: ['test'],
100+
queryFn: async () => Promise.reject(new Error('Rejected')),
101+
retry: 1,
102+
retryDelay: 1,
103+
}
104+
105+
const rendered = render(BaseExample, {
106+
props: {
107+
options,
108+
queryClient: new QueryClient(),
109+
states: statesStore,
110+
},
111+
})
112+
113+
await waitFor(() => rendered.getByText('Status: error'))
114+
115+
const states = get(statesStore)
116+
117+
expect(states).toHaveLength(3)
118+
119+
expect(states[0]).toMatchObject({
120+
data: undefined,
121+
dataUpdatedAt: 0,
122+
error: null,
123+
errorUpdatedAt: 0,
124+
failureCount: 0,
125+
failureReason: null,
126+
errorUpdateCount: 0,
127+
isError: false,
128+
isFetched: false,
129+
isFetchedAfterMount: false,
130+
isFetching: true,
131+
isPaused: false,
132+
isPending: true,
133+
isInitialLoading: true,
134+
isLoading: true,
135+
isLoadingError: false,
136+
isPlaceholderData: false,
137+
isRefetchError: false,
138+
isRefetching: false,
139+
isStale: true,
140+
isSuccess: false,
141+
refetch: expect.any(Function),
142+
status: 'pending',
143+
fetchStatus: 'fetching',
144+
})
145+
146+
expect(states[1]).toMatchObject({
147+
data: undefined,
148+
dataUpdatedAt: 0,
149+
error: null,
150+
errorUpdatedAt: 0,
151+
failureCount: 1,
152+
failureReason: new Error('Rejected'),
153+
errorUpdateCount: 0,
154+
isError: false,
155+
isFetched: false,
156+
isFetchedAfterMount: false,
157+
isFetching: true,
158+
isPaused: false,
159+
isPending: true,
160+
isInitialLoading: true,
161+
isLoading: true,
162+
isLoadingError: false,
163+
isPlaceholderData: false,
164+
isRefetchError: false,
165+
isRefetching: false,
166+
isStale: true,
167+
isSuccess: false,
168+
refetch: expect.any(Function),
169+
status: 'pending',
170+
fetchStatus: 'fetching',
171+
})
172+
173+
expect(states[2]).toMatchObject({
174+
data: undefined,
175+
dataUpdatedAt: 0,
176+
error: new Error('Rejected'),
177+
errorUpdatedAt: expect.any(Number),
178+
failureCount: 2,
179+
failureReason: new Error('Rejected'),
180+
errorUpdateCount: 1,
181+
isError: true,
182+
isFetched: true,
183+
isFetchedAfterMount: true,
184+
isFetching: false,
185+
isPaused: false,
186+
isPending: false,
187+
isInitialLoading: false,
188+
isLoading: false,
189+
isLoadingError: true,
190+
isPlaceholderData: false,
191+
isRefetchError: false,
192+
isRefetching: false,
193+
isStale: true,
194+
isSuccess: false,
195+
refetch: expect.any(Function),
196+
status: 'error',
197+
fetchStatus: 'idle',
30198
})
31199
})
32200

33201
test('Accept a writable store for options', async () => {
202+
const statesStore: Writable<Array<QueryObserverResult>> = writable([])
203+
34204
const optionsStore = writable({
35205
queryKey: ['test'],
36206
queryFn: async () => {
@@ -43,6 +213,7 @@ describe('createQuery', () => {
43213
props: {
44214
options: optionsStore,
45215
queryClient: new QueryClient(),
216+
states: statesStore,
46217
},
47218
})
48219

@@ -52,6 +223,8 @@ describe('createQuery', () => {
52223
})
53224

54225
test('Accept a derived store for options', async () => {
226+
const statesStore: Writable<Array<QueryObserverResult>> = writable([])
227+
55228
const writableStore = writable('test')
56229

57230
const derivedStore = derived(writableStore, ($store) => ({
@@ -66,6 +239,7 @@ describe('createQuery', () => {
66239
props: {
67240
options: derivedStore,
68241
queryClient: new QueryClient(),
242+
states: statesStore,
69243
},
70244
})
71245

@@ -75,6 +249,8 @@ describe('createQuery', () => {
75249
})
76250

77251
test('Ensure reactivity when queryClient defaults are set', async () => {
252+
const statesStore: Writable<Array<QueryObserverResult>> = writable([])
253+
78254
const writableStore = writable(1)
79255

80256
const derivedStore = derived(writableStore, ($store) => ({
@@ -91,6 +267,7 @@ describe('createQuery', () => {
91267
queryClient: new QueryClient({
92268
defaultOptions: { queries: { staleTime: 60 * 1000 } },
93269
}),
270+
states: statesStore,
94271
},
95272
})
96273

@@ -114,45 +291,53 @@ describe('createQuery', () => {
114291
})
115292
})
116293

117-
test('Keep previous data when returned as placeholder data', async () => {
118-
const writableStore = writable<Array<number>>([1])
119-
120-
const derivedStore = derived(writableStore, ($store) => ({
121-
queryKey: ['test', $store],
122-
queryFn: async () => {
123-
await sleep(10)
124-
return $store.map((id) => `Success ${id}`)
125-
},
126-
placeholderData: (previousData: string) => previousData,
127-
}))
294+
test('Keep previous data when placeholderData is set', async () => {
295+
const statesStore: Writable<Array<QueryObserverResult>> = writable([])
128296

129-
const rendered = render(BaseExample, {
297+
const rendered = render(PlaceholderData, {
130298
props: {
131-
options: derivedStore,
132299
queryClient: new QueryClient(),
300+
states: statesStore,
133301
},
134302
})
135303

136-
await waitFor(() => {
137-
expect(rendered.queryByText('Success 1')).not.toBeInTheDocument()
138-
expect(rendered.queryByText('Success 2')).not.toBeInTheDocument()
139-
})
304+
await waitFor(() => rendered.getByText('Data: 0'))
140305

141-
await waitFor(() => {
142-
expect(rendered.queryByText('Success 1')).toBeInTheDocument()
143-
expect(rendered.queryByText('Success 2')).not.toBeInTheDocument()
144-
})
306+
fireEvent.click(rendered.getByRole('button', { name: 'setCount' }))
145307

146-
writableStore.set([1, 2])
308+
await waitFor(() => rendered.getByText('Data: 1'))
147309

148-
await waitFor(() => {
149-
expect(rendered.queryByText('Success 1')).toBeInTheDocument()
150-
expect(rendered.queryByText('Success 2')).not.toBeInTheDocument()
151-
})
310+
const states = get(statesStore)
152311

153-
await waitFor(() => {
154-
expect(rendered.queryByText('Success 1')).toBeInTheDocument()
155-
expect(rendered.queryByText('Success 2')).toBeInTheDocument()
312+
expect(states).toHaveLength(4)
313+
314+
// Initial
315+
expect(states[0]).toMatchObject({
316+
data: undefined,
317+
isFetching: true,
318+
isSuccess: false,
319+
isPlaceholderData: false,
320+
})
321+
// Fetched
322+
expect(states[1]).toMatchObject({
323+
data: 0,
324+
isFetching: false,
325+
isSuccess: true,
326+
isPlaceholderData: false,
327+
})
328+
// Set state
329+
expect(states[2]).toMatchObject({
330+
data: 0,
331+
isFetching: true,
332+
isSuccess: true,
333+
isPlaceholderData: true,
334+
})
335+
// New data
336+
expect(states[3]).toMatchObject({
337+
data: 1,
338+
isFetching: false,
339+
isSuccess: true,
340+
isPlaceholderData: false,
156341
})
157342
})
158343

0 commit comments

Comments
 (0)
Please sign in to comment.