@tanstack/solid-query 4.24.9 → 5.0.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/cjs/index.js +298 -0
- package/build/cjs/index.js.map +1 -0
- package/build/esm/index.js +283 -0
- package/build/esm/index.js.map +1 -0
- package/build/source/QueryClientProvider.jsx +21 -0
- package/build/source/__tests__/QueryClientProvider.test.jsx +120 -0
- package/build/{solid → source}/__tests__/createInfiniteQuery.test.jsx +228 -372
- package/build/{solid → source}/__tests__/createMutation.test.jsx +174 -165
- package/build/{solid → source}/__tests__/createQueries.test.jsx +86 -367
- package/build/{solid → source}/__tests__/createQuery.test.jsx +991 -943
- package/build/{solid → source}/__tests__/createQuery.types.test.jsx +35 -24
- package/build/{solid → source}/__tests__/suspense.test.jsx +177 -148
- package/build/{solid → source}/__tests__/transition.test.jsx +7 -4
- package/build/{solid → source}/__tests__/useIsFetching.test.jsx +68 -85
- package/build/{solid → source}/__tests__/useIsMutating.test.jsx +78 -93
- package/build/{solid → source}/__tests__/utils.jsx +3 -9
- package/build/source/createBaseQuery.js +147 -0
- package/build/source/createInfiniteQuery.js +6 -0
- package/build/{solid → source}/createMutation.js +7 -9
- package/build/source/createQueries.js +32 -0
- package/build/source/createQuery.js +6 -0
- package/build/{solid → source}/index.js +5 -3
- package/build/source/setBatchUpdatesFn.js +3 -0
- package/build/source/useIsFetching.js +12 -0
- package/build/source/useIsMutating.js +12 -0
- package/build/source/utils.js +7 -0
- package/build/types/QueryClientProvider.d.ts +9 -0
- package/build/{lib → types}/__tests__/utils.d.ts +3 -8
- package/build/types/createBaseQuery.d.ts +4 -0
- package/build/types/createInfiniteQuery.d.ts +3 -0
- package/build/types/createMutation.d.ts +3 -0
- package/build/{lib → types}/createQueries.d.ts +10 -8
- package/build/types/createQuery.d.ts +11 -0
- package/build/{lib → types}/index.d.ts +4 -3
- package/build/types/setBatchUpdatesFn.d.ts +1 -0
- package/build/types/types.d.ts +33 -0
- package/build/types/useIsFetching.d.ts +8 -0
- package/build/types/useIsMutating.d.ts +8 -0
- package/build/types/utils.d.ts +1 -0
- package/build/umd/index.js +2 -0
- package/build/umd/index.js.map +1 -0
- package/package.json +25 -17
- package/src/QueryClientProvider.tsx +17 -86
- package/src/__tests__/QueryClientProvider.test.tsx +37 -140
- package/src/__tests__/createInfiniteQuery.test.tsx +277 -508
- package/src/__tests__/createMutation.test.tsx +177 -225
- package/src/__tests__/createQueries.test.tsx +180 -528
- package/src/__tests__/createQuery.test.tsx +970 -1200
- package/src/__tests__/createQuery.types.test.tsx +30 -25
- package/src/__tests__/suspense.test.tsx +141 -178
- package/src/__tests__/transition.test.tsx +7 -4
- package/src/__tests__/useIsFetching.test.tsx +77 -122
- package/src/__tests__/useIsMutating.test.tsx +83 -128
- package/src/__tests__/utils.tsx +4 -11
- package/src/createBaseQuery.ts +148 -60
- package/src/createInfiniteQuery.ts +15 -94
- package/src/createMutation.ts +9 -63
- package/src/createQueries.ts +44 -55
- package/src/createQuery.ts +42 -127
- package/src/index.ts +6 -3
- package/src/setBatchUpdatesFn.ts +4 -0
- package/src/types.ts +81 -75
- package/src/useIsFetching.ts +12 -44
- package/src/useIsMutating.ts +13 -29
- package/src/utils.ts +5 -79
- package/build/lib/QueryClientProvider.d.ts +0 -24
- package/build/lib/QueryClientProvider.esm.js +0 -74
- package/build/lib/QueryClientProvider.esm.js.map +0 -1
- package/build/lib/QueryClientProvider.js +0 -80
- package/build/lib/QueryClientProvider.js.map +0 -1
- package/build/lib/QueryClientProvider.mjs +0 -74
- package/build/lib/QueryClientProvider.mjs.map +0 -1
- package/build/lib/createBaseQuery.d.ts +0 -4
- package/build/lib/createBaseQuery.esm.js +0 -93
- package/build/lib/createBaseQuery.esm.js.map +0 -1
- package/build/lib/createBaseQuery.js +0 -97
- package/build/lib/createBaseQuery.js.map +0 -1
- package/build/lib/createBaseQuery.mjs +0 -93
- package/build/lib/createBaseQuery.mjs.map +0 -1
- package/build/lib/createInfiniteQuery.d.ts +0 -5
- package/build/lib/createInfiniteQuery.esm.js +0 -20
- package/build/lib/createInfiniteQuery.esm.js.map +0 -1
- package/build/lib/createInfiniteQuery.js +0 -24
- package/build/lib/createInfiniteQuery.js.map +0 -1
- package/build/lib/createInfiniteQuery.mjs +0 -20
- package/build/lib/createInfiniteQuery.mjs.map +0 -1
- package/build/lib/createMutation.d.ts +0 -6
- package/build/lib/createMutation.esm.js +0 -45
- package/build/lib/createMutation.esm.js.map +0 -1
- package/build/lib/createMutation.js +0 -49
- package/build/lib/createMutation.js.map +0 -1
- package/build/lib/createMutation.mjs +0 -45
- package/build/lib/createMutation.mjs.map +0 -1
- package/build/lib/createQueries.esm.js +0 -54
- package/build/lib/createQueries.esm.js.map +0 -1
- package/build/lib/createQueries.js +0 -58
- package/build/lib/createQueries.js.map +0 -1
- package/build/lib/createQueries.mjs +0 -54
- package/build/lib/createQueries.mjs.map +0 -1
- package/build/lib/createQuery.d.ts +0 -23
- package/build/lib/createQuery.esm.js +0 -25
- package/build/lib/createQuery.esm.js.map +0 -1
- package/build/lib/createQuery.js +0 -29
- package/build/lib/createQuery.js.map +0 -1
- package/build/lib/createQuery.mjs +0 -25
- package/build/lib/createQuery.mjs.map +0 -1
- package/build/lib/index.esm.js +0 -9
- package/build/lib/index.esm.js.map +0 -1
- package/build/lib/index.js +0 -31
- package/build/lib/index.js.map +0 -1
- package/build/lib/index.mjs +0 -9
- package/build/lib/index.mjs.map +0 -1
- package/build/lib/types.d.ts +0 -47
- package/build/lib/useIsFetching.d.ts +0 -7
- package/build/lib/useIsFetching.esm.js +0 -29
- package/build/lib/useIsFetching.esm.js.map +0 -1
- package/build/lib/useIsFetching.js +0 -33
- package/build/lib/useIsFetching.js.map +0 -1
- package/build/lib/useIsFetching.mjs +0 -29
- package/build/lib/useIsFetching.mjs.map +0 -1
- package/build/lib/useIsMutating.d.ts +0 -8
- package/build/lib/useIsMutating.esm.js +0 -22
- package/build/lib/useIsMutating.esm.js.map +0 -1
- package/build/lib/useIsMutating.js +0 -26
- package/build/lib/useIsMutating.js.map +0 -1
- package/build/lib/useIsMutating.mjs +0 -22
- package/build/lib/useIsMutating.mjs.map +0 -1
- package/build/lib/utils.d.ts +0 -14
- package/build/lib/utils.esm.js +0 -63
- package/build/lib/utils.esm.js.map +0 -1
- package/build/lib/utils.js +0 -72
- package/build/lib/utils.js.map +0 -1
- package/build/lib/utils.mjs +0 -63
- package/build/lib/utils.mjs.map +0 -1
- package/build/solid/QueryClientProvider.jsx +0 -49
- package/build/solid/__tests__/QueryClientProvider.test.jsx +0 -185
- package/build/solid/createBaseQuery.js +0 -81
- package/build/solid/createInfiniteQuery.js +0 -16
- package/build/solid/createQueries.js +0 -39
- package/build/solid/createQuery.js +0 -16
- package/build/solid/useIsFetching.js +0 -23
- package/build/solid/useIsMutating.js +0 -16
- package/build/solid/utils.js +0 -45
- package/build/umd/index.development.js +0 -3572
- package/build/umd/index.development.js.map +0 -1
- package/build/umd/index.production.js +0 -2
- package/build/umd/index.production.js.map +0 -1
- /package/build/{solid → source}/types.js +0 -0
- /package/build/{lib → types}/__tests__/QueryClientProvider.test.d.ts +0 -0
- /package/build/{lib → types}/__tests__/createInfiniteQuery.test.d.ts +0 -0
- /package/build/{lib → types}/__tests__/createMutation.test.d.ts +0 -0
- /package/build/{lib → types}/__tests__/createQueries.test.d.ts +0 -0
- /package/build/{lib → types}/__tests__/createQuery.test.d.ts +0 -0
- /package/build/{lib → types}/__tests__/createQuery.types.test.d.ts +0 -0
- /package/build/{lib → types}/__tests__/suspense.test.d.ts +0 -0
- /package/build/{lib → types}/__tests__/transition.test.d.ts +0 -0
- /package/build/{lib → types}/__tests__/useIsFetching.test.d.ts +0 -0
- /package/build/{lib → types}/__tests__/useIsMutating.test.d.ts +0 -0
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import '@testing-library/jest-dom';
|
|
2
2
|
import { createEffect, createMemo, createRenderEffect, createSignal, ErrorBoundary, Match, on, Switch, } from 'solid-js';
|
|
3
3
|
import { fireEvent, render, screen, waitFor } from 'solid-testing-library';
|
|
4
|
-
import { createQuery, QueryCache, QueryClientProvider } from '..';
|
|
5
|
-
import { Blink, createQueryClient, expectType,
|
|
4
|
+
import { createQuery, QueryCache, QueryClientProvider, keepPreviousData, } from '..';
|
|
5
|
+
import { Blink, createQueryClient, expectType, mockNavigatorOnLine, mockVisibilityState, queryKey, setActTimeout, sleep, } from './utils';
|
|
6
6
|
describe('createQuery', () => {
|
|
7
7
|
const queryCache = new QueryCache();
|
|
8
8
|
const queryClient = createQueryClient({ queryCache });
|
|
@@ -12,75 +12,100 @@ describe('createQuery', () => {
|
|
|
12
12
|
// eslint-disable-next-line
|
|
13
13
|
function Page() {
|
|
14
14
|
// unspecified query function should default to unknown
|
|
15
|
-
const noQueryFn = createQuery(key);
|
|
15
|
+
const noQueryFn = createQuery(() => ({ queryKey: key }));
|
|
16
16
|
expectType(noQueryFn.data);
|
|
17
17
|
expectType(noQueryFn.error);
|
|
18
18
|
// it should infer the result type from the query function
|
|
19
|
-
const fromQueryFn = createQuery(
|
|
19
|
+
const fromQueryFn = createQuery(() => ({
|
|
20
|
+
queryKey: key,
|
|
21
|
+
queryFn: () => 'test',
|
|
22
|
+
}));
|
|
20
23
|
expectType(fromQueryFn.data);
|
|
21
24
|
expectType(fromQueryFn.error);
|
|
22
25
|
// it should be possible to specify the result type
|
|
23
|
-
const withResult = createQuery(
|
|
26
|
+
const withResult = createQuery(() => ({
|
|
27
|
+
queryKey: key,
|
|
28
|
+
queryFn: () => 'test',
|
|
29
|
+
}));
|
|
24
30
|
expectType(withResult.data);
|
|
25
31
|
expectType(withResult.error);
|
|
26
32
|
// it should be possible to specify the error type
|
|
27
|
-
const withError = createQuery(
|
|
33
|
+
const withError = createQuery(() => ({
|
|
34
|
+
queryKey: key,
|
|
35
|
+
queryFn: () => 'test',
|
|
36
|
+
}));
|
|
28
37
|
expectType(withError.data);
|
|
29
38
|
expectType(withError.error);
|
|
30
39
|
// it should provide the result type in the configuration
|
|
31
|
-
createQuery(() =>
|
|
40
|
+
createQuery(() => ({
|
|
41
|
+
queryKey: [key],
|
|
42
|
+
queryFn: async () => true,
|
|
32
43
|
onSuccess: (data) => expectType(data),
|
|
33
44
|
onSettled: (data) => expectType(data),
|
|
34
|
-
});
|
|
45
|
+
}));
|
|
35
46
|
// it should be possible to specify a union type as result type
|
|
36
|
-
const unionTypeSync = createQuery(
|
|
47
|
+
const unionTypeSync = createQuery(() => ({
|
|
48
|
+
queryKey: key,
|
|
49
|
+
queryFn: () => (Math.random() > 0.5 ? 'a' : 'b'),
|
|
37
50
|
onSuccess: (data) => expectType(data),
|
|
38
|
-
});
|
|
51
|
+
}));
|
|
39
52
|
expectType(unionTypeSync.data);
|
|
40
|
-
const unionTypeAsync = createQuery(
|
|
53
|
+
const unionTypeAsync = createQuery(() => ({
|
|
54
|
+
queryKey: key,
|
|
55
|
+
queryFn: () => Promise.resolve(Math.random() > 0.5 ? 'a' : 'b'),
|
|
41
56
|
onSuccess: (data) => expectType(data),
|
|
42
|
-
});
|
|
57
|
+
}));
|
|
43
58
|
expectType(unionTypeAsync.data);
|
|
44
59
|
// should error when the query function result does not match with the specified type
|
|
45
60
|
// @ts-expect-error
|
|
46
|
-
createQuery(key, () => 'test');
|
|
61
|
+
createQuery(() => ({ queryKey: key, queryFn: () => 'test' }));
|
|
47
62
|
// it should infer the result type from a generic query function
|
|
48
63
|
function queryFn() {
|
|
49
64
|
return Promise.resolve({});
|
|
50
65
|
}
|
|
51
|
-
const fromGenericQueryFn = createQuery(
|
|
66
|
+
const fromGenericQueryFn = createQuery(() => ({
|
|
67
|
+
queryKey: key,
|
|
68
|
+
queryFn: () => queryFn(),
|
|
69
|
+
}));
|
|
52
70
|
expectType(fromGenericQueryFn.data);
|
|
53
71
|
expectType(fromGenericQueryFn.error);
|
|
54
|
-
const fromGenericOptionsQueryFn = createQuery({
|
|
72
|
+
const fromGenericOptionsQueryFn = createQuery(() => ({
|
|
55
73
|
queryKey: key,
|
|
56
74
|
queryFn: () => queryFn(),
|
|
57
|
-
});
|
|
75
|
+
}));
|
|
58
76
|
expectType(fromGenericOptionsQueryFn.data);
|
|
59
77
|
expectType(fromGenericOptionsQueryFn.error);
|
|
60
78
|
const getMyDataArrayKey = async ({ queryKey: [, n], }) => {
|
|
61
79
|
return n + 42;
|
|
62
80
|
};
|
|
63
|
-
createQuery({
|
|
64
|
-
queryKey:
|
|
81
|
+
createQuery(() => ({
|
|
82
|
+
queryKey: ['my-data', 100],
|
|
65
83
|
queryFn: getMyDataArrayKey,
|
|
66
|
-
});
|
|
84
|
+
}));
|
|
67
85
|
const getMyDataStringKey = async (context) => {
|
|
68
86
|
expectType(context.queryKey);
|
|
69
87
|
return Number(context.queryKey[0]) + 42;
|
|
70
88
|
};
|
|
71
|
-
createQuery({
|
|
72
|
-
queryKey:
|
|
89
|
+
createQuery(() => ({
|
|
90
|
+
queryKey: ['1'],
|
|
73
91
|
queryFn: getMyDataStringKey,
|
|
74
|
-
});
|
|
92
|
+
}));
|
|
75
93
|
// it should handle query-functions that return Promise<any>
|
|
76
|
-
createQuery(
|
|
94
|
+
createQuery(() => ({
|
|
95
|
+
queryKey: key,
|
|
96
|
+
queryFn: () => fetch('return Promise<any>').then((resp) => resp.json()),
|
|
97
|
+
}));
|
|
77
98
|
// handles wrapped queries with custom fetcher passed as inline queryFn
|
|
78
|
-
const useWrappedQuery = (qk, fetcher, options) => createQuery(
|
|
79
|
-
|
|
99
|
+
const useWrappedQuery = (qk, fetcher, options) => createQuery(() => ({
|
|
100
|
+
queryKey: qk,
|
|
101
|
+
queryFn: () => fetcher(qk[1], 'token'),
|
|
102
|
+
...options,
|
|
103
|
+
}));
|
|
104
|
+
const test = useWrappedQuery([''], async () => '1');
|
|
80
105
|
expectType(test.data);
|
|
81
106
|
// handles wrapped queries with custom fetcher passed directly to createQuery
|
|
82
|
-
const useWrappedFuncStyleQuery = (qk, fetcher, options) => createQuery(qk, fetcher, options);
|
|
83
|
-
const testFuncStyle = useWrappedFuncStyleQuery(
|
|
107
|
+
const useWrappedFuncStyleQuery = (qk, fetcher, options) => createQuery(() => ({ queryKey: qk, queryFn: fetcher, ...options }));
|
|
108
|
+
const testFuncStyle = useWrappedFuncStyleQuery([''], async () => true);
|
|
84
109
|
expectType(testFuncStyle.data);
|
|
85
110
|
}
|
|
86
111
|
});
|
|
@@ -88,10 +113,13 @@ describe('createQuery', () => {
|
|
|
88
113
|
it('should allow to set default data value', async () => {
|
|
89
114
|
const key = queryKey();
|
|
90
115
|
function Page() {
|
|
91
|
-
const state = createQuery(
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
116
|
+
const state = createQuery(() => ({
|
|
117
|
+
queryKey: key,
|
|
118
|
+
queryFn: async () => {
|
|
119
|
+
await sleep(10);
|
|
120
|
+
return 'test';
|
|
121
|
+
},
|
|
122
|
+
}));
|
|
95
123
|
return (<div>
|
|
96
124
|
<h1>{state.data ?? 'default'}</h1>
|
|
97
125
|
</div>);
|
|
@@ -106,14 +134,17 @@ describe('createQuery', () => {
|
|
|
106
134
|
const key = queryKey();
|
|
107
135
|
const states = [];
|
|
108
136
|
function Page() {
|
|
109
|
-
const state = createQuery(
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
137
|
+
const state = createQuery(() => ({
|
|
138
|
+
queryKey: key,
|
|
139
|
+
queryFn: async () => {
|
|
140
|
+
await sleep(10);
|
|
141
|
+
return 'test';
|
|
142
|
+
},
|
|
143
|
+
}));
|
|
113
144
|
createRenderEffect(() => {
|
|
114
145
|
states.push({ ...state });
|
|
115
146
|
});
|
|
116
|
-
if (state.
|
|
147
|
+
if (state.isPending) {
|
|
117
148
|
expectType(state.data);
|
|
118
149
|
expectType(state.error);
|
|
119
150
|
}
|
|
@@ -126,8 +157,8 @@ describe('createQuery', () => {
|
|
|
126
157
|
expectType(state.error);
|
|
127
158
|
}
|
|
128
159
|
return (<Switch fallback={<span>{state.data}</span>}>
|
|
129
|
-
<Match when={state.
|
|
130
|
-
<span>
|
|
160
|
+
<Match when={state.isPending}>
|
|
161
|
+
<span>pending</span>
|
|
131
162
|
</Match>
|
|
132
163
|
<Match when={state.isLoadingError}>
|
|
133
164
|
<span>{state.error.message}</span>
|
|
@@ -152,18 +183,17 @@ describe('createQuery', () => {
|
|
|
152
183
|
isFetchedAfterMount: false,
|
|
153
184
|
isFetching: true,
|
|
154
185
|
isPaused: false,
|
|
155
|
-
|
|
186
|
+
isPending: true,
|
|
156
187
|
isInitialLoading: true,
|
|
188
|
+
isLoading: true,
|
|
157
189
|
isLoadingError: false,
|
|
158
190
|
isPlaceholderData: false,
|
|
159
|
-
isPreviousData: false,
|
|
160
191
|
isRefetchError: false,
|
|
161
192
|
isRefetching: false,
|
|
162
193
|
isStale: true,
|
|
163
194
|
isSuccess: false,
|
|
164
195
|
refetch: expect.any(Function),
|
|
165
|
-
|
|
166
|
-
status: 'loading',
|
|
196
|
+
status: 'pending',
|
|
167
197
|
fetchStatus: 'fetching',
|
|
168
198
|
});
|
|
169
199
|
expect(states[1]).toEqual({
|
|
@@ -179,17 +209,16 @@ describe('createQuery', () => {
|
|
|
179
209
|
isFetchedAfterMount: true,
|
|
180
210
|
isFetching: false,
|
|
181
211
|
isPaused: false,
|
|
182
|
-
|
|
212
|
+
isPending: false,
|
|
183
213
|
isInitialLoading: false,
|
|
214
|
+
isLoading: false,
|
|
184
215
|
isLoadingError: false,
|
|
185
216
|
isPlaceholderData: false,
|
|
186
|
-
isPreviousData: false,
|
|
187
217
|
isRefetchError: false,
|
|
188
218
|
isRefetching: false,
|
|
189
219
|
isStale: true,
|
|
190
220
|
isSuccess: true,
|
|
191
221
|
refetch: expect.any(Function),
|
|
192
|
-
remove: expect.any(Function),
|
|
193
222
|
status: 'success',
|
|
194
223
|
fetchStatus: 'idle',
|
|
195
224
|
});
|
|
@@ -198,17 +227,19 @@ describe('createQuery', () => {
|
|
|
198
227
|
const key = queryKey();
|
|
199
228
|
const states = [];
|
|
200
229
|
function Page() {
|
|
201
|
-
const state = createQuery(
|
|
230
|
+
const state = createQuery(() => ({
|
|
231
|
+
queryKey: key,
|
|
232
|
+
queryFn: () => Promise.reject(new Error('rejected')),
|
|
202
233
|
retry: 1,
|
|
203
234
|
retryDelay: 1,
|
|
204
|
-
});
|
|
235
|
+
}));
|
|
205
236
|
createRenderEffect(() => {
|
|
206
237
|
states.push({ ...state });
|
|
207
238
|
});
|
|
208
239
|
return (<div>
|
|
209
240
|
<h1>Status: {state.status}</h1>
|
|
210
241
|
<div>Failure Count: {state.failureCount}</div>
|
|
211
|
-
<div>Failure Reason: {state.failureReason}</div>
|
|
242
|
+
<div>Failure Reason: {state.failureReason?.message}</div>
|
|
212
243
|
</div>);
|
|
213
244
|
}
|
|
214
245
|
render(() => (<QueryClientProvider client={queryClient}>
|
|
@@ -228,18 +259,17 @@ describe('createQuery', () => {
|
|
|
228
259
|
isFetchedAfterMount: false,
|
|
229
260
|
isFetching: true,
|
|
230
261
|
isPaused: false,
|
|
231
|
-
|
|
262
|
+
isPending: true,
|
|
232
263
|
isInitialLoading: true,
|
|
264
|
+
isLoading: true,
|
|
233
265
|
isLoadingError: false,
|
|
234
266
|
isPlaceholderData: false,
|
|
235
|
-
isPreviousData: false,
|
|
236
267
|
isRefetchError: false,
|
|
237
268
|
isRefetching: false,
|
|
238
269
|
isStale: true,
|
|
239
270
|
isSuccess: false,
|
|
240
271
|
refetch: expect.any(Function),
|
|
241
|
-
|
|
242
|
-
status: 'loading',
|
|
272
|
+
status: 'pending',
|
|
243
273
|
fetchStatus: 'fetching',
|
|
244
274
|
});
|
|
245
275
|
expect(states[1]).toEqual({
|
|
@@ -248,51 +278,49 @@ describe('createQuery', () => {
|
|
|
248
278
|
error: null,
|
|
249
279
|
errorUpdatedAt: 0,
|
|
250
280
|
failureCount: 1,
|
|
251
|
-
failureReason: 'rejected',
|
|
281
|
+
failureReason: new Error('rejected'),
|
|
252
282
|
errorUpdateCount: 0,
|
|
253
283
|
isError: false,
|
|
254
284
|
isFetched: false,
|
|
255
285
|
isFetchedAfterMount: false,
|
|
256
286
|
isFetching: true,
|
|
257
287
|
isPaused: false,
|
|
258
|
-
|
|
288
|
+
isPending: true,
|
|
259
289
|
isInitialLoading: true,
|
|
290
|
+
isLoading: true,
|
|
260
291
|
isLoadingError: false,
|
|
261
292
|
isPlaceholderData: false,
|
|
262
|
-
isPreviousData: false,
|
|
263
293
|
isRefetchError: false,
|
|
264
294
|
isRefetching: false,
|
|
265
295
|
isStale: true,
|
|
266
296
|
isSuccess: false,
|
|
267
297
|
refetch: expect.any(Function),
|
|
268
|
-
|
|
269
|
-
status: 'loading',
|
|
298
|
+
status: 'pending',
|
|
270
299
|
fetchStatus: 'fetching',
|
|
271
300
|
});
|
|
272
301
|
expect(states[2]).toEqual({
|
|
273
302
|
data: undefined,
|
|
274
303
|
dataUpdatedAt: 0,
|
|
275
|
-
error: 'rejected',
|
|
304
|
+
error: new Error('rejected'),
|
|
276
305
|
errorUpdatedAt: expect.any(Number),
|
|
277
306
|
failureCount: 2,
|
|
278
|
-
failureReason: 'rejected',
|
|
307
|
+
failureReason: new Error('rejected'),
|
|
279
308
|
errorUpdateCount: 1,
|
|
280
309
|
isError: true,
|
|
281
310
|
isFetched: true,
|
|
282
311
|
isFetchedAfterMount: true,
|
|
283
312
|
isFetching: false,
|
|
284
313
|
isPaused: false,
|
|
285
|
-
|
|
314
|
+
isPending: false,
|
|
286
315
|
isInitialLoading: false,
|
|
316
|
+
isLoading: false,
|
|
287
317
|
isLoadingError: true,
|
|
288
318
|
isPlaceholderData: false,
|
|
289
|
-
isPreviousData: false,
|
|
290
319
|
isRefetchError: false,
|
|
291
320
|
isRefetching: false,
|
|
292
321
|
isStale: true,
|
|
293
322
|
isSuccess: false,
|
|
294
323
|
refetch: expect.any(Function),
|
|
295
|
-
remove: expect.any(Function),
|
|
296
324
|
status: 'error',
|
|
297
325
|
fetchStatus: 'idle',
|
|
298
326
|
});
|
|
@@ -300,10 +328,15 @@ describe('createQuery', () => {
|
|
|
300
328
|
it('should set isFetchedAfterMount to true after a query has been fetched', async () => {
|
|
301
329
|
const key = queryKey();
|
|
302
330
|
const states = [];
|
|
303
|
-
|
|
304
|
-
|
|
331
|
+
await queryClient.prefetchQuery({
|
|
332
|
+
queryKey: key,
|
|
333
|
+
queryFn: () => 'prefetched',
|
|
334
|
+
});
|
|
305
335
|
function Page() {
|
|
306
|
-
const state = createQuery(
|
|
336
|
+
const state = createQuery(() => ({
|
|
337
|
+
queryKey: key,
|
|
338
|
+
queryFn: () => 'data',
|
|
339
|
+
}));
|
|
307
340
|
createRenderEffect(() => {
|
|
308
341
|
states.push({ ...state });
|
|
309
342
|
});
|
|
@@ -330,10 +363,14 @@ describe('createQuery', () => {
|
|
|
330
363
|
const states = [];
|
|
331
364
|
const onSuccess = jest.fn();
|
|
332
365
|
function Page() {
|
|
333
|
-
const state = createQuery(
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
366
|
+
const state = createQuery(() => ({
|
|
367
|
+
queryKey: key,
|
|
368
|
+
queryFn: async () => {
|
|
369
|
+
await sleep(10);
|
|
370
|
+
return 'data';
|
|
371
|
+
},
|
|
372
|
+
onSuccess,
|
|
373
|
+
}));
|
|
337
374
|
createRenderEffect(() => {
|
|
338
375
|
states.push({ ...state });
|
|
339
376
|
});
|
|
@@ -347,44 +384,17 @@ describe('createQuery', () => {
|
|
|
347
384
|
expect(onSuccess).toHaveBeenCalledTimes(1);
|
|
348
385
|
expect(onSuccess).toHaveBeenCalledWith('data');
|
|
349
386
|
});
|
|
350
|
-
it('should call onSuccess after a query has been refetched', async () => {
|
|
351
|
-
const key = queryKey();
|
|
352
|
-
const states = [];
|
|
353
|
-
const onSuccess = jest.fn();
|
|
354
|
-
let count = 0;
|
|
355
|
-
function Page() {
|
|
356
|
-
const state = createQuery(key, async () => {
|
|
357
|
-
count++;
|
|
358
|
-
await sleep(10);
|
|
359
|
-
return 'data' + count;
|
|
360
|
-
}, { onSuccess });
|
|
361
|
-
createRenderEffect(on(() => [state.data, state.refetch], () => {
|
|
362
|
-
states.push(state);
|
|
363
|
-
}));
|
|
364
|
-
return (<div>
|
|
365
|
-
<div>data: {state.data}</div>
|
|
366
|
-
<button onClick={() => state.refetch()}>refetch</button>
|
|
367
|
-
</div>);
|
|
368
|
-
}
|
|
369
|
-
render(() => (<QueryClientProvider client={queryClient}>
|
|
370
|
-
<Page />
|
|
371
|
-
</QueryClientProvider>));
|
|
372
|
-
await screen.findByText('data: data1');
|
|
373
|
-
fireEvent.click(screen.getByRole('button', { name: /refetch/i }));
|
|
374
|
-
await screen.findByText('data: data2');
|
|
375
|
-
expect(states.length).toBe(3); //loading, success, success after refetch
|
|
376
|
-
expect(count).toBe(2);
|
|
377
|
-
expect(onSuccess).toHaveBeenCalledTimes(2);
|
|
378
|
-
});
|
|
379
387
|
it('should call onSuccess after a disabled query has been fetched', async () => {
|
|
380
388
|
const key = queryKey();
|
|
381
389
|
const states = [];
|
|
382
390
|
const onSuccess = jest.fn();
|
|
383
391
|
function Page() {
|
|
384
|
-
const state = createQuery(
|
|
392
|
+
const state = createQuery(() => ({
|
|
393
|
+
queryKey: key,
|
|
394
|
+
queryFn: () => 'data',
|
|
385
395
|
enabled: false,
|
|
386
396
|
onSuccess,
|
|
387
|
-
});
|
|
397
|
+
}));
|
|
388
398
|
createRenderEffect(() => {
|
|
389
399
|
states.push({ ...state });
|
|
390
400
|
});
|
|
@@ -415,10 +425,14 @@ describe('createQuery', () => {
|
|
|
415
425
|
return <>{show() && <Component />}</>;
|
|
416
426
|
}
|
|
417
427
|
function Component() {
|
|
418
|
-
const state = createQuery(
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
428
|
+
const state = createQuery(() => ({
|
|
429
|
+
queryKey: key,
|
|
430
|
+
queryFn: async () => {
|
|
431
|
+
await sleep(10);
|
|
432
|
+
return 'data';
|
|
433
|
+
},
|
|
434
|
+
onSuccess,
|
|
435
|
+
}));
|
|
422
436
|
createRenderEffect(() => {
|
|
423
437
|
states.push({ ...state });
|
|
424
438
|
});
|
|
@@ -436,10 +450,12 @@ describe('createQuery', () => {
|
|
|
436
450
|
const states = [];
|
|
437
451
|
const onError = jest.fn();
|
|
438
452
|
function Page() {
|
|
439
|
-
const state = createQuery(
|
|
453
|
+
const state = createQuery(() => ({
|
|
454
|
+
queryKey: key,
|
|
455
|
+
queryFn: () => Promise.reject(new Error('error')),
|
|
440
456
|
retry: false,
|
|
441
457
|
onError,
|
|
442
|
-
});
|
|
458
|
+
}));
|
|
443
459
|
createRenderEffect(() => {
|
|
444
460
|
states.push({ ...state });
|
|
445
461
|
});
|
|
@@ -451,18 +467,20 @@ describe('createQuery', () => {
|
|
|
451
467
|
await sleep(10);
|
|
452
468
|
expect(states.length).toBe(2);
|
|
453
469
|
expect(onError).toHaveBeenCalledTimes(1);
|
|
454
|
-
expect(onError).toHaveBeenCalledWith('error');
|
|
470
|
+
expect(onError).toHaveBeenCalledWith(new Error('error'));
|
|
455
471
|
});
|
|
456
472
|
it('should not call onError when receiving a CancelledError', async () => {
|
|
457
473
|
const key = queryKey();
|
|
458
474
|
const onError = jest.fn();
|
|
459
475
|
function Page() {
|
|
460
|
-
const state = createQuery(
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
476
|
+
const state = createQuery(() => ({
|
|
477
|
+
queryKey: key,
|
|
478
|
+
queryFn: async () => {
|
|
479
|
+
await sleep(10);
|
|
480
|
+
return 23;
|
|
481
|
+
},
|
|
464
482
|
onError,
|
|
465
|
-
});
|
|
483
|
+
}));
|
|
466
484
|
return (<span>
|
|
467
485
|
status: {state.status}, fetchStatus: {state.fetchStatus}
|
|
468
486
|
</span>);
|
|
@@ -471,9 +489,9 @@ describe('createQuery', () => {
|
|
|
471
489
|
<Page />
|
|
472
490
|
</QueryClientProvider>));
|
|
473
491
|
await sleep(5);
|
|
474
|
-
await queryClient.cancelQueries(key
|
|
492
|
+
await queryClient.cancelQueries({ queryKey: key });
|
|
475
493
|
// query cancellation will reset the query to it's initial state
|
|
476
|
-
await waitFor(() => screen.getByText('status:
|
|
494
|
+
await waitFor(() => screen.getByText('status: pending, fetchStatus: idle'));
|
|
477
495
|
expect(onError).not.toHaveBeenCalled();
|
|
478
496
|
});
|
|
479
497
|
it('should call onSettled after a query has been fetched', async () => {
|
|
@@ -481,7 +499,11 @@ describe('createQuery', () => {
|
|
|
481
499
|
const states = [];
|
|
482
500
|
const onSettled = jest.fn();
|
|
483
501
|
function Page() {
|
|
484
|
-
const state = createQuery(
|
|
502
|
+
const state = createQuery(() => ({
|
|
503
|
+
queryKey: key,
|
|
504
|
+
queryFn: () => 'data',
|
|
505
|
+
onSettled,
|
|
506
|
+
}));
|
|
485
507
|
createRenderEffect(() => {
|
|
486
508
|
states.push({ ...state });
|
|
487
509
|
});
|
|
@@ -500,10 +522,12 @@ describe('createQuery', () => {
|
|
|
500
522
|
const states = [];
|
|
501
523
|
const onSettled = jest.fn();
|
|
502
524
|
function Page() {
|
|
503
|
-
const state = createQuery(
|
|
525
|
+
const state = createQuery(() => ({
|
|
526
|
+
queryKey: key,
|
|
527
|
+
queryFn: () => Promise.reject('error'),
|
|
504
528
|
retry: false,
|
|
505
529
|
onSettled,
|
|
506
|
-
});
|
|
530
|
+
}));
|
|
507
531
|
createRenderEffect(() => {
|
|
508
532
|
states.push({ ...state });
|
|
509
533
|
});
|
|
@@ -521,11 +545,16 @@ describe('createQuery', () => {
|
|
|
521
545
|
const key = queryKey();
|
|
522
546
|
let fetchCount = 0;
|
|
523
547
|
function Page() {
|
|
524
|
-
const state = createQuery(
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
548
|
+
const state = createQuery(() => ({
|
|
549
|
+
queryKey: key,
|
|
550
|
+
queryFn: async () => {
|
|
551
|
+
fetchCount++;
|
|
552
|
+
await sleep(10);
|
|
553
|
+
return 'data';
|
|
554
|
+
},
|
|
555
|
+
enabled: false,
|
|
556
|
+
initialData: 'initialData',
|
|
557
|
+
}));
|
|
529
558
|
createEffect(() => {
|
|
530
559
|
setActTimeout(() => {
|
|
531
560
|
state.refetch();
|
|
@@ -547,11 +576,16 @@ describe('createQuery', () => {
|
|
|
547
576
|
const key = queryKey();
|
|
548
577
|
let fetchCount = 0;
|
|
549
578
|
function Page() {
|
|
550
|
-
const state = createQuery(
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
579
|
+
const state = createQuery(() => ({
|
|
580
|
+
queryKey: key,
|
|
581
|
+
queryFn: async () => {
|
|
582
|
+
fetchCount++;
|
|
583
|
+
await sleep(10);
|
|
584
|
+
return 'data';
|
|
585
|
+
},
|
|
586
|
+
enabled: false,
|
|
587
|
+
initialData: 'initialData',
|
|
588
|
+
}));
|
|
555
589
|
createEffect(() => {
|
|
556
590
|
setActTimeout(() => {
|
|
557
591
|
state.refetch();
|
|
@@ -573,11 +607,15 @@ describe('createQuery', () => {
|
|
|
573
607
|
const key = queryKey();
|
|
574
608
|
let fetchCount = 0;
|
|
575
609
|
function Page() {
|
|
576
|
-
const state = createQuery(
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
610
|
+
const state = createQuery(() => ({
|
|
611
|
+
queryKey: key,
|
|
612
|
+
queryFn: async () => {
|
|
613
|
+
fetchCount++;
|
|
614
|
+
await sleep(10);
|
|
615
|
+
return 'data';
|
|
616
|
+
},
|
|
617
|
+
enabled: false,
|
|
618
|
+
}));
|
|
581
619
|
createEffect(() => {
|
|
582
620
|
setActTimeout(() => {
|
|
583
621
|
state.refetch();
|
|
@@ -598,10 +636,9 @@ describe('createQuery', () => {
|
|
|
598
636
|
it('should be able to watch a query without providing a query function', async () => {
|
|
599
637
|
const key = queryKey();
|
|
600
638
|
const states = [];
|
|
601
|
-
|
|
602
|
-
queryClient.setQueryDefaults(key(), { queryFn: () => 'data' });
|
|
639
|
+
queryClient.setQueryDefaults(key, { queryFn: () => 'data' });
|
|
603
640
|
function Page() {
|
|
604
|
-
const state = createQuery(key);
|
|
641
|
+
const state = createQuery(() => ({ queryKey: key }));
|
|
605
642
|
createRenderEffect(() => {
|
|
606
643
|
states.push({ ...state });
|
|
607
644
|
});
|
|
@@ -615,7 +652,7 @@ describe('createQuery', () => {
|
|
|
615
652
|
expect(states[0]).toMatchObject({ data: undefined });
|
|
616
653
|
expect(states[1]).toMatchObject({ data: 'data' });
|
|
617
654
|
});
|
|
618
|
-
it('should pick up a query when re-mounting with
|
|
655
|
+
it('should pick up a query when re-mounting with gcTime 0', async () => {
|
|
619
656
|
const key = queryKey();
|
|
620
657
|
const states = [];
|
|
621
658
|
function Page() {
|
|
@@ -633,13 +670,14 @@ describe('createQuery', () => {
|
|
|
633
670
|
</div>);
|
|
634
671
|
}
|
|
635
672
|
function Component({ value }) {
|
|
636
|
-
const state = createQuery(
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
673
|
+
const state = createQuery(() => ({
|
|
674
|
+
queryKey: key,
|
|
675
|
+
queryFn: async () => {
|
|
676
|
+
await sleep(10);
|
|
677
|
+
return 'data: ' + value;
|
|
678
|
+
},
|
|
679
|
+
gcTime: 0,
|
|
680
|
+
}));
|
|
643
681
|
createRenderEffect(() => {
|
|
644
682
|
states.push({ ...state });
|
|
645
683
|
});
|
|
@@ -656,78 +694,38 @@ describe('createQuery', () => {
|
|
|
656
694
|
expect(states.length).toBe(4);
|
|
657
695
|
// First load
|
|
658
696
|
expect(states[0]).toMatchObject({
|
|
659
|
-
|
|
697
|
+
isPending: true,
|
|
660
698
|
isSuccess: false,
|
|
661
699
|
isFetching: true,
|
|
662
700
|
});
|
|
663
701
|
// First success
|
|
664
702
|
expect(states[1]).toMatchObject({
|
|
665
|
-
|
|
703
|
+
isPending: false,
|
|
666
704
|
isSuccess: true,
|
|
667
705
|
isFetching: false,
|
|
668
706
|
});
|
|
669
707
|
// Switch, goes to fetching
|
|
670
708
|
expect(states[2]).toMatchObject({
|
|
671
|
-
|
|
709
|
+
isPending: false,
|
|
672
710
|
isSuccess: true,
|
|
673
711
|
isFetching: true,
|
|
674
712
|
});
|
|
675
713
|
// Second success
|
|
676
714
|
expect(states[3]).toMatchObject({
|
|
677
|
-
|
|
715
|
+
isPending: false,
|
|
678
716
|
isSuccess: true,
|
|
679
717
|
isFetching: false,
|
|
680
718
|
});
|
|
681
719
|
});
|
|
682
|
-
it.skip('should not get into an infinite loop when removing a query with cacheTime 0 and rerendering', async () => {
|
|
683
|
-
const key = queryKey();
|
|
684
|
-
const states = [];
|
|
685
|
-
function Page() {
|
|
686
|
-
//@ts-expect-error -- skip this test
|
|
687
|
-
const [, rerender] = NotReact.useState({});
|
|
688
|
-
const state = createQuery(key, async () => {
|
|
689
|
-
await sleep(5);
|
|
690
|
-
return 'data';
|
|
691
|
-
}, {
|
|
692
|
-
cacheTime: 0,
|
|
693
|
-
notifyOnChangeProps: 'all',
|
|
694
|
-
});
|
|
695
|
-
createRenderEffect(() => {
|
|
696
|
-
states.push({ ...state });
|
|
697
|
-
});
|
|
698
|
-
const { remove } = state;
|
|
699
|
-
//@ts-expect-error skip this test
|
|
700
|
-
NotReact.useEffect(() => {
|
|
701
|
-
setActTimeout(() => {
|
|
702
|
-
remove();
|
|
703
|
-
rerender({});
|
|
704
|
-
}, 20);
|
|
705
|
-
}, [remove]);
|
|
706
|
-
return null;
|
|
707
|
-
}
|
|
708
|
-
render(() => (<QueryClientProvider client={queryClient}>
|
|
709
|
-
<Page />
|
|
710
|
-
</QueryClientProvider>));
|
|
711
|
-
await sleep(100);
|
|
712
|
-
expect(states.length).toBe(5);
|
|
713
|
-
// First load
|
|
714
|
-
expect(states[0]).toMatchObject({ isLoading: true, isSuccess: false });
|
|
715
|
-
// First success
|
|
716
|
-
expect(states[1]).toMatchObject({ isLoading: false, isSuccess: true });
|
|
717
|
-
// Remove
|
|
718
|
-
expect(states[2]).toMatchObject({ isLoading: true, isSuccess: false });
|
|
719
|
-
// Hook state update
|
|
720
|
-
expect(states[3]).toMatchObject({ isLoading: true, isSuccess: false });
|
|
721
|
-
// Second success
|
|
722
|
-
expect(states[4]).toMatchObject({ isLoading: false, isSuccess: true });
|
|
723
|
-
});
|
|
724
720
|
it('should fetch when refetchOnMount is false and nothing has been fetched yet', async () => {
|
|
725
721
|
const key = queryKey();
|
|
726
722
|
const states = [];
|
|
727
723
|
function Page() {
|
|
728
|
-
const state = createQuery(
|
|
724
|
+
const state = createQuery(() => ({
|
|
725
|
+
queryKey: key,
|
|
726
|
+
queryFn: () => 'test',
|
|
729
727
|
refetchOnMount: false,
|
|
730
|
-
});
|
|
728
|
+
}));
|
|
731
729
|
createRenderEffect(() => {
|
|
732
730
|
states.push({ ...state });
|
|
733
731
|
});
|
|
@@ -744,11 +742,13 @@ describe('createQuery', () => {
|
|
|
744
742
|
it('should not fetch when refetchOnMount is false and data has been fetched already', async () => {
|
|
745
743
|
const key = queryKey();
|
|
746
744
|
const states = [];
|
|
747
|
-
queryClient.setQueryData(key
|
|
745
|
+
queryClient.setQueryData(key, 'prefetched');
|
|
748
746
|
function Page() {
|
|
749
|
-
const state = createQuery(
|
|
747
|
+
const state = createQuery(() => ({
|
|
748
|
+
queryKey: key,
|
|
749
|
+
queryFn: () => 'test',
|
|
750
750
|
refetchOnMount: false,
|
|
751
|
-
});
|
|
751
|
+
}));
|
|
752
752
|
createRenderEffect(() => {
|
|
753
753
|
states.push({ ...state });
|
|
754
754
|
});
|
|
@@ -765,9 +765,11 @@ describe('createQuery', () => {
|
|
|
765
765
|
const key = queryKey();
|
|
766
766
|
const states = [];
|
|
767
767
|
function Page() {
|
|
768
|
-
const state = createQuery(
|
|
768
|
+
const state = createQuery(() => ({
|
|
769
|
+
queryKey: key,
|
|
770
|
+
queryFn: () => ({ name: 'test' }),
|
|
769
771
|
select: (data) => data.name,
|
|
770
|
-
});
|
|
772
|
+
}));
|
|
771
773
|
createRenderEffect(() => {
|
|
772
774
|
states.push({ ...state });
|
|
773
775
|
});
|
|
@@ -785,11 +787,11 @@ describe('createQuery', () => {
|
|
|
785
787
|
const key = queryKey();
|
|
786
788
|
const states = [];
|
|
787
789
|
function Page() {
|
|
788
|
-
const state = createQuery({
|
|
790
|
+
const state = createQuery(() => ({
|
|
789
791
|
queryKey: key,
|
|
790
792
|
queryFn: () => ({ name: 'test' }),
|
|
791
793
|
select: (data) => data.name,
|
|
792
|
-
});
|
|
794
|
+
}));
|
|
793
795
|
createRenderEffect(() => {
|
|
794
796
|
states.push({ ...state });
|
|
795
797
|
});
|
|
@@ -803,23 +805,18 @@ describe('createQuery', () => {
|
|
|
803
805
|
expect(states[0]).toMatchObject({ data: undefined });
|
|
804
806
|
expect(states[1]).toMatchObject({ data: 'test' });
|
|
805
807
|
});
|
|
806
|
-
it('should
|
|
808
|
+
it('should be able to select a part of the data with select in object syntax', async () => {
|
|
807
809
|
const key = queryKey();
|
|
808
810
|
const states = [];
|
|
809
811
|
function Page() {
|
|
810
|
-
const state = createQuery(
|
|
812
|
+
const state = createQuery(() => ({
|
|
813
|
+
queryKey: key,
|
|
814
|
+
queryFn: () => ({ name: 'test' }),
|
|
811
815
|
select: (data) => data.name,
|
|
812
|
-
|
|
813
|
-
});
|
|
816
|
+
}));
|
|
814
817
|
createRenderEffect(() => {
|
|
815
818
|
states.push({ ...state });
|
|
816
819
|
});
|
|
817
|
-
createEffect(() => {
|
|
818
|
-
const refetch = state.refetch;
|
|
819
|
-
setActTimeout(() => {
|
|
820
|
-
refetch();
|
|
821
|
-
}, 5);
|
|
822
|
-
});
|
|
823
820
|
return null;
|
|
824
821
|
}
|
|
825
822
|
render(() => (<QueryClientProvider client={queryClient}>
|
|
@@ -830,69 +827,71 @@ describe('createQuery', () => {
|
|
|
830
827
|
expect(states[0]).toMatchObject({ data: undefined });
|
|
831
828
|
expect(states[1]).toMatchObject({ data: 'test' });
|
|
832
829
|
});
|
|
833
|
-
it('should
|
|
830
|
+
it('should not re-render when it should only re-render only data change and the selected data did not change', async () => {
|
|
834
831
|
const key = queryKey();
|
|
835
832
|
const states = [];
|
|
836
|
-
const error = new Error('Select Error');
|
|
837
833
|
function Page() {
|
|
838
|
-
const state = createQuery(
|
|
839
|
-
|
|
840
|
-
|
|
834
|
+
const state = createQuery(() => ({
|
|
835
|
+
queryKey: key,
|
|
836
|
+
queryFn: async () => {
|
|
837
|
+
await sleep(10);
|
|
838
|
+
return { name: 'test' };
|
|
841
839
|
},
|
|
842
|
-
|
|
840
|
+
select: (data) => data.name,
|
|
841
|
+
notifyOnChangeProps: ['data'],
|
|
842
|
+
}));
|
|
843
843
|
createRenderEffect(() => {
|
|
844
844
|
states.push({ ...state });
|
|
845
845
|
});
|
|
846
|
-
return
|
|
846
|
+
return (<div>
|
|
847
|
+
data: {state.data}
|
|
848
|
+
<button onClick={() => state.refetch()}>refetch</button>
|
|
849
|
+
</div>);
|
|
847
850
|
}
|
|
848
851
|
render(() => (<QueryClientProvider client={queryClient}>
|
|
849
852
|
<Page />
|
|
850
853
|
</QueryClientProvider>));
|
|
851
|
-
await
|
|
852
|
-
expect(mockLogger.error).toHaveBeenCalledWith(error);
|
|
854
|
+
await waitFor(() => screen.getByText('data: test'));
|
|
853
855
|
expect(states.length).toBe(2);
|
|
854
|
-
expect(states[0]).toMatchObject({
|
|
855
|
-
expect(states[1]).toMatchObject({
|
|
856
|
+
expect(states[0]).toMatchObject({ data: undefined });
|
|
857
|
+
expect(states[1]).toMatchObject({ data: 'test' });
|
|
856
858
|
});
|
|
857
|
-
it
|
|
859
|
+
it('should throw an error when a selector throws', async () => {
|
|
858
860
|
const key = queryKey();
|
|
861
|
+
const states = [];
|
|
859
862
|
const error = new Error('Select Error');
|
|
860
|
-
let runs = 0;
|
|
861
863
|
function Page() {
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
864
|
+
const state = createQuery(() => ({
|
|
865
|
+
queryKey: key,
|
|
866
|
+
queryFn: () => ({ name: 'test' }),
|
|
865
867
|
select: () => {
|
|
866
|
-
runs++;
|
|
867
868
|
throw error;
|
|
868
869
|
},
|
|
870
|
+
}));
|
|
871
|
+
createRenderEffect(() => {
|
|
872
|
+
states.push({ ...state });
|
|
869
873
|
});
|
|
870
|
-
return
|
|
871
|
-
<div>error: {state.error?.message}</div>
|
|
872
|
-
<button onClick={rerender}>rerender</button>
|
|
873
|
-
<button onClick={() => state.refetch()}>refetch</button>
|
|
874
|
-
</div>);
|
|
874
|
+
return null;
|
|
875
875
|
}
|
|
876
876
|
render(() => (<QueryClientProvider client={queryClient}>
|
|
877
877
|
<Page />
|
|
878
878
|
</QueryClientProvider>));
|
|
879
|
-
await waitFor(() => screen.getByText('error: Select Error'));
|
|
880
|
-
expect(runs).toEqual(1);
|
|
881
|
-
fireEvent.click(screen.getByRole('button', { name: 'rerender' }));
|
|
882
|
-
await sleep(10);
|
|
883
|
-
expect(runs).toEqual(1);
|
|
884
|
-
fireEvent.click(screen.getByRole('button', { name: 'refetch' }));
|
|
885
879
|
await sleep(10);
|
|
886
|
-
expect(
|
|
880
|
+
expect(states.length).toBe(2);
|
|
881
|
+
expect(states[0]).toMatchObject({ status: 'pending', data: undefined });
|
|
882
|
+
expect(states[1]).toMatchObject({ status: 'error', error });
|
|
887
883
|
});
|
|
888
884
|
it('should track properties and only re-render when a tracked property changes', async () => {
|
|
889
885
|
const key = queryKey();
|
|
890
886
|
const states = [];
|
|
891
887
|
function Page() {
|
|
892
|
-
const state = createQuery(
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
888
|
+
const state = createQuery(() => ({
|
|
889
|
+
queryKey: key,
|
|
890
|
+
queryFn: async () => {
|
|
891
|
+
await sleep(10);
|
|
892
|
+
return 'test';
|
|
893
|
+
},
|
|
894
|
+
}));
|
|
896
895
|
createRenderEffect(() => {
|
|
897
896
|
states.push({ ...state });
|
|
898
897
|
});
|
|
@@ -922,7 +921,10 @@ describe('createQuery', () => {
|
|
|
922
921
|
let renderCount = 0;
|
|
923
922
|
const states = [];
|
|
924
923
|
function Page() {
|
|
925
|
-
const state = createQuery(
|
|
924
|
+
const state = createQuery(() => ({
|
|
925
|
+
queryKey: key,
|
|
926
|
+
queryFn: () => 'test',
|
|
927
|
+
}));
|
|
926
928
|
createRenderEffect(() => {
|
|
927
929
|
states.push({ ...state });
|
|
928
930
|
});
|
|
@@ -942,80 +944,6 @@ describe('createQuery', () => {
|
|
|
942
944
|
expect(states[0]).toMatchObject({ data: undefined });
|
|
943
945
|
expect(states[1]).toMatchObject({ data: 'test' });
|
|
944
946
|
});
|
|
945
|
-
it.skip('should be able to remove a query', async () => {
|
|
946
|
-
const key = queryKey();
|
|
947
|
-
const states = [];
|
|
948
|
-
let count = 0;
|
|
949
|
-
function Page() {
|
|
950
|
-
//@ts-expect-error -- we skip this test, and no such thing as rerender in solid
|
|
951
|
-
const [, rerender] = NotReact.useState({});
|
|
952
|
-
const state = createQuery(key, () => ++count, {
|
|
953
|
-
notifyOnChangeProps: 'all',
|
|
954
|
-
});
|
|
955
|
-
createRenderEffect(() => {
|
|
956
|
-
states.push({ ...state });
|
|
957
|
-
});
|
|
958
|
-
const { remove } = state;
|
|
959
|
-
return (<div>
|
|
960
|
-
<button onClick={() => remove()}>remove</button>
|
|
961
|
-
<button onClick={() => rerender({})}>rerender</button>
|
|
962
|
-
data: {state.data ?? 'null'}
|
|
963
|
-
</div>);
|
|
964
|
-
}
|
|
965
|
-
render(() => (<QueryClientProvider client={queryClient}>
|
|
966
|
-
<Page />
|
|
967
|
-
</QueryClientProvider>));
|
|
968
|
-
await waitFor(() => screen.getByText('data: 1'));
|
|
969
|
-
fireEvent.click(screen.getByRole('button', { name: /remove/i }));
|
|
970
|
-
await sleep(20);
|
|
971
|
-
fireEvent.click(screen.getByRole('button', { name: /rerender/i }));
|
|
972
|
-
await waitFor(() => screen.getByText('data: 2'));
|
|
973
|
-
expect(states.length).toBe(4);
|
|
974
|
-
// Initial
|
|
975
|
-
expect(states[0]).toMatchObject({ status: 'loading', data: undefined });
|
|
976
|
-
// Fetched
|
|
977
|
-
expect(states[1]).toMatchObject({ status: 'success', data: 1 });
|
|
978
|
-
// Remove + Hook state update, batched
|
|
979
|
-
expect(states[2]).toMatchObject({ status: 'loading', data: undefined });
|
|
980
|
-
// Fetched
|
|
981
|
-
expect(states[3]).toMatchObject({ status: 'success', data: 2 });
|
|
982
|
-
});
|
|
983
|
-
it('should create a new query when refetching a removed query', async () => {
|
|
984
|
-
const key = queryKey();
|
|
985
|
-
const states = [];
|
|
986
|
-
let count = 0;
|
|
987
|
-
function Page() {
|
|
988
|
-
const state = createQuery(key, async () => {
|
|
989
|
-
await sleep(10);
|
|
990
|
-
return ++count;
|
|
991
|
-
}, { notifyOnChangeProps: 'all' });
|
|
992
|
-
createRenderEffect(() => {
|
|
993
|
-
states.push({ ...state });
|
|
994
|
-
});
|
|
995
|
-
return (<div>
|
|
996
|
-
<button onClick={() => state.remove()}>remove</button>
|
|
997
|
-
<button onClick={() => state.refetch()}>refetch</button>
|
|
998
|
-
data: {state.data ?? 'null'}
|
|
999
|
-
</div>);
|
|
1000
|
-
}
|
|
1001
|
-
render(() => (<QueryClientProvider client={queryClient}>
|
|
1002
|
-
<Page />
|
|
1003
|
-
</QueryClientProvider>));
|
|
1004
|
-
await waitFor(() => screen.getByText('data: 1'));
|
|
1005
|
-
fireEvent.click(screen.getByRole('button', { name: /remove/i }));
|
|
1006
|
-
await sleep(50);
|
|
1007
|
-
fireEvent.click(screen.getByRole('button', { name: /refetch/i }));
|
|
1008
|
-
await waitFor(() => screen.getByText('data: 2'));
|
|
1009
|
-
expect(states.length).toBe(4);
|
|
1010
|
-
// Initial
|
|
1011
|
-
expect(states[0]).toMatchObject({ data: undefined, dataUpdatedAt: 0 });
|
|
1012
|
-
// Fetched
|
|
1013
|
-
expect(states[1]).toMatchObject({ data: 1 });
|
|
1014
|
-
// Switch
|
|
1015
|
-
expect(states[2]).toMatchObject({ data: undefined, dataUpdatedAt: 0 });
|
|
1016
|
-
// Fetched
|
|
1017
|
-
expect(states[3]).toMatchObject({ data: 2 });
|
|
1018
|
-
});
|
|
1019
947
|
it('should share equal data structures between query results', async () => {
|
|
1020
948
|
const key = queryKey();
|
|
1021
949
|
const result1 = [
|
|
@@ -1029,11 +957,15 @@ describe('createQuery', () => {
|
|
|
1029
957
|
const states = [];
|
|
1030
958
|
let count = 0;
|
|
1031
959
|
function Page() {
|
|
1032
|
-
const state = createQuery(
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
960
|
+
const state = createQuery(() => ({
|
|
961
|
+
queryKey: key,
|
|
962
|
+
queryFn: async () => {
|
|
963
|
+
await sleep(10);
|
|
964
|
+
count++;
|
|
965
|
+
return count === 1 ? result1 : result2;
|
|
966
|
+
},
|
|
967
|
+
notifyOnChangeProps: 'all',
|
|
968
|
+
}));
|
|
1037
969
|
createRenderEffect(() => {
|
|
1038
970
|
states.push({ ...state });
|
|
1039
971
|
});
|
|
@@ -1067,21 +999,23 @@ describe('createQuery', () => {
|
|
|
1067
999
|
it('should use query function from hook when the existing query does not have a query function', async () => {
|
|
1068
1000
|
const key = queryKey();
|
|
1069
1001
|
const results = [];
|
|
1070
|
-
queryClient.setQueryData(key
|
|
1002
|
+
queryClient.setQueryData(key, 'set');
|
|
1071
1003
|
function Page() {
|
|
1072
|
-
const result = createQuery(
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1004
|
+
const result = createQuery(() => ({
|
|
1005
|
+
queryKey: key,
|
|
1006
|
+
queryFn: async () => {
|
|
1007
|
+
await sleep(10);
|
|
1008
|
+
return 'fetched';
|
|
1009
|
+
},
|
|
1076
1010
|
initialData: 'initial',
|
|
1077
1011
|
staleTime: Infinity,
|
|
1078
|
-
});
|
|
1012
|
+
}));
|
|
1079
1013
|
createRenderEffect(() => {
|
|
1080
1014
|
results.push({ ...result });
|
|
1081
1015
|
});
|
|
1082
1016
|
return (<div>
|
|
1083
1017
|
<div>isFetching: {result.isFetching}</div>
|
|
1084
|
-
<button onClick={() => queryClient.refetchQueries(key
|
|
1018
|
+
<button onClick={() => queryClient.refetchQueries({ queryKey: key })}>
|
|
1085
1019
|
refetch
|
|
1086
1020
|
</button>
|
|
1087
1021
|
data: {result.data}
|
|
@@ -1103,16 +1037,20 @@ describe('createQuery', () => {
|
|
|
1103
1037
|
const states = [];
|
|
1104
1038
|
let count = 0;
|
|
1105
1039
|
function Page() {
|
|
1106
|
-
const state = createQuery(
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1040
|
+
const state = createQuery(() => ({
|
|
1041
|
+
queryKey: key,
|
|
1042
|
+
queryFn: async () => {
|
|
1043
|
+
await sleep(10);
|
|
1044
|
+
count++;
|
|
1045
|
+
return count;
|
|
1046
|
+
},
|
|
1047
|
+
staleTime: Infinity,
|
|
1048
|
+
}));
|
|
1111
1049
|
createEffect(() => {
|
|
1112
1050
|
states.push({ ...state });
|
|
1113
1051
|
});
|
|
1114
1052
|
return (<div>
|
|
1115
|
-
<button onClick={() => queryClient.invalidateQueries(key
|
|
1053
|
+
<button onClick={() => queryClient.invalidateQueries({ queryKey: key })}>
|
|
1116
1054
|
invalidate
|
|
1117
1055
|
</button>
|
|
1118
1056
|
data: {state.data}
|
|
@@ -1159,17 +1097,21 @@ describe('createQuery', () => {
|
|
|
1159
1097
|
const states = [];
|
|
1160
1098
|
let count = 0;
|
|
1161
1099
|
function Page() {
|
|
1162
|
-
const state = createQuery(
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1100
|
+
const state = createQuery(() => ({
|
|
1101
|
+
queryKey: key,
|
|
1102
|
+
queryFn: async () => {
|
|
1103
|
+
await sleep(10);
|
|
1104
|
+
count++;
|
|
1105
|
+
return count;
|
|
1106
|
+
},
|
|
1107
|
+
enabled: false,
|
|
1108
|
+
}));
|
|
1167
1109
|
createRenderEffect(() => {
|
|
1168
1110
|
states.push({ ...state });
|
|
1169
1111
|
});
|
|
1170
1112
|
createEffect(() => {
|
|
1171
1113
|
setActTimeout(() => {
|
|
1172
|
-
queryClient.refetchQueries({ queryKey: key
|
|
1114
|
+
queryClient.refetchQueries({ queryKey: key });
|
|
1173
1115
|
}, 20);
|
|
1174
1116
|
});
|
|
1175
1117
|
return null;
|
|
@@ -1191,17 +1133,21 @@ describe('createQuery', () => {
|
|
|
1191
1133
|
const states = [];
|
|
1192
1134
|
let count = 0;
|
|
1193
1135
|
function Page() {
|
|
1194
|
-
const state = createQuery(
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1136
|
+
const state = createQuery(() => ({
|
|
1137
|
+
queryKey: key,
|
|
1138
|
+
queryFn: async () => {
|
|
1139
|
+
await sleep(10);
|
|
1140
|
+
count++;
|
|
1141
|
+
return count;
|
|
1142
|
+
},
|
|
1143
|
+
enabled: false,
|
|
1144
|
+
}));
|
|
1199
1145
|
createRenderEffect(() => {
|
|
1200
1146
|
states.push({ ...state });
|
|
1201
1147
|
});
|
|
1202
1148
|
createEffect(() => {
|
|
1203
1149
|
setActTimeout(() => {
|
|
1204
|
-
queryClient.invalidateQueries(key
|
|
1150
|
+
queryClient.invalidateQueries({ queryKey: key });
|
|
1205
1151
|
}, 20);
|
|
1206
1152
|
});
|
|
1207
1153
|
return null;
|
|
@@ -1223,14 +1169,14 @@ describe('createQuery', () => {
|
|
|
1223
1169
|
const states = [];
|
|
1224
1170
|
function Page() {
|
|
1225
1171
|
const [count, setCount] = createSignal(0);
|
|
1226
|
-
const state = createQuery(() =>
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
return count() === 0;
|
|
1172
|
+
const state = createQuery(() => ({
|
|
1173
|
+
queryKey: [key, count()],
|
|
1174
|
+
queryFn: async () => {
|
|
1175
|
+
await sleep(5);
|
|
1176
|
+
return count();
|
|
1232
1177
|
},
|
|
1233
|
-
|
|
1178
|
+
enabled: count() === 0,
|
|
1179
|
+
}));
|
|
1234
1180
|
createRenderEffect(() => {
|
|
1235
1181
|
states.push({ ...state });
|
|
1236
1182
|
});
|
|
@@ -1248,7 +1194,6 @@ describe('createQuery', () => {
|
|
|
1248
1194
|
expect(states.length).toBe(3);
|
|
1249
1195
|
// Fetch query
|
|
1250
1196
|
expect(states[0]).toMatchObject({
|
|
1251
|
-
data: undefined,
|
|
1252
1197
|
isFetching: true,
|
|
1253
1198
|
isSuccess: false,
|
|
1254
1199
|
});
|
|
@@ -1260,20 +1205,23 @@ describe('createQuery', () => {
|
|
|
1260
1205
|
});
|
|
1261
1206
|
// Switch to disabled query
|
|
1262
1207
|
expect(states[2]).toMatchObject({
|
|
1263
|
-
data: undefined,
|
|
1264
1208
|
isFetching: false,
|
|
1265
1209
|
isSuccess: false,
|
|
1266
1210
|
});
|
|
1267
1211
|
});
|
|
1268
|
-
it('should keep the previous data when
|
|
1212
|
+
it('should keep the previous data when placeholderData is set', async () => {
|
|
1269
1213
|
const key = queryKey();
|
|
1270
1214
|
const states = [];
|
|
1271
1215
|
function Page() {
|
|
1272
1216
|
const [count, setCount] = createSignal(0);
|
|
1273
|
-
const state = createQuery(() =>
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1217
|
+
const state = createQuery(() => ({
|
|
1218
|
+
queryKey: [key, count()],
|
|
1219
|
+
queryFn: async () => {
|
|
1220
|
+
await sleep(10);
|
|
1221
|
+
return count();
|
|
1222
|
+
},
|
|
1223
|
+
placeholderData: keepPreviousData,
|
|
1224
|
+
}));
|
|
1277
1225
|
createRenderEffect(() => {
|
|
1278
1226
|
states.push({ ...state });
|
|
1279
1227
|
});
|
|
@@ -1293,139 +1241,44 @@ describe('createQuery', () => {
|
|
|
1293
1241
|
data: undefined,
|
|
1294
1242
|
isFetching: true,
|
|
1295
1243
|
isSuccess: false,
|
|
1296
|
-
|
|
1244
|
+
isPlaceholderData: false,
|
|
1297
1245
|
});
|
|
1298
1246
|
// Fetched
|
|
1299
1247
|
expect(states[1]).toMatchObject({
|
|
1300
1248
|
data: 0,
|
|
1301
1249
|
isFetching: false,
|
|
1302
1250
|
isSuccess: true,
|
|
1303
|
-
|
|
1251
|
+
isPlaceholderData: false,
|
|
1304
1252
|
});
|
|
1305
1253
|
// Set state
|
|
1306
1254
|
expect(states[2]).toMatchObject({
|
|
1307
1255
|
data: 0,
|
|
1308
1256
|
isFetching: true,
|
|
1309
1257
|
isSuccess: true,
|
|
1310
|
-
|
|
1258
|
+
isPlaceholderData: true,
|
|
1311
1259
|
});
|
|
1312
1260
|
// New data
|
|
1313
1261
|
expect(states[3]).toMatchObject({
|
|
1314
1262
|
data: 1,
|
|
1315
1263
|
isFetching: false,
|
|
1316
1264
|
isSuccess: true,
|
|
1317
|
-
|
|
1318
|
-
});
|
|
1319
|
-
});
|
|
1320
|
-
// this test relies on rerenders which don't exist in solid
|
|
1321
|
-
it.skip('should transition to error state when keepPreviousData is set', async () => {
|
|
1322
|
-
const key = queryKey();
|
|
1323
|
-
const states = [];
|
|
1324
|
-
function Page(props) {
|
|
1325
|
-
const state = createQuery(() => [key(), props.count], async () => {
|
|
1326
|
-
await sleep(10);
|
|
1327
|
-
if (props.count === 2) {
|
|
1328
|
-
throw new Error('Error test');
|
|
1329
|
-
}
|
|
1330
|
-
return Promise.resolve(props.count);
|
|
1331
|
-
}, {
|
|
1332
|
-
retry: false,
|
|
1333
|
-
keepPreviousData: true,
|
|
1334
|
-
});
|
|
1335
|
-
createRenderEffect(() => {
|
|
1336
|
-
states.push({ ...state });
|
|
1337
|
-
});
|
|
1338
|
-
return (<div>
|
|
1339
|
-
<h1>data: {state.data}</h1>
|
|
1340
|
-
<h2>error: {state.error?.message}</h2>
|
|
1341
|
-
<p>previous data: {state.isPreviousData}</p>
|
|
1342
|
-
</div>);
|
|
1343
|
-
}
|
|
1344
|
-
render(() => (<QueryClientProvider client={queryClient}>
|
|
1345
|
-
<Page count={0}/>
|
|
1346
|
-
</QueryClientProvider>));
|
|
1347
|
-
await waitFor(() => screen.getByText('data: 0'));
|
|
1348
|
-
// @ts-expect-error we skip this test and rerenders don't exist in solid
|
|
1349
|
-
act(() => screen.rerender(<Page count={1}/>));
|
|
1350
|
-
await waitFor(() => screen.getByText('data: 1'));
|
|
1351
|
-
// @ts-expect-error we skip this test and rerenders don't exist in solid
|
|
1352
|
-
act(() => screen.rerender(<Page count={2}/>));
|
|
1353
|
-
await waitFor(() => screen.getByText('error: Error test'));
|
|
1354
|
-
await waitFor(() => expect(states.length).toBe(8));
|
|
1355
|
-
// Initial
|
|
1356
|
-
expect(states[0]).toMatchObject({
|
|
1357
|
-
data: undefined,
|
|
1358
|
-
isFetching: true,
|
|
1359
|
-
status: 'loading',
|
|
1360
|
-
error: null,
|
|
1361
|
-
isPreviousData: false,
|
|
1362
|
-
});
|
|
1363
|
-
// Fetched
|
|
1364
|
-
expect(states[1]).toMatchObject({
|
|
1365
|
-
data: 0,
|
|
1366
|
-
isFetching: false,
|
|
1367
|
-
status: 'success',
|
|
1368
|
-
error: null,
|
|
1369
|
-
isPreviousData: false,
|
|
1370
|
-
});
|
|
1371
|
-
// rerender Page 1
|
|
1372
|
-
expect(states[2]).toMatchObject({
|
|
1373
|
-
data: 0,
|
|
1374
|
-
isFetching: true,
|
|
1375
|
-
status: 'success',
|
|
1376
|
-
error: null,
|
|
1377
|
-
isPreviousData: true,
|
|
1378
|
-
});
|
|
1379
|
-
// Hook state update
|
|
1380
|
-
expect(states[3]).toMatchObject({
|
|
1381
|
-
data: 0,
|
|
1382
|
-
isFetching: true,
|
|
1383
|
-
status: 'success',
|
|
1384
|
-
error: null,
|
|
1385
|
-
isPreviousData: true,
|
|
1386
|
-
});
|
|
1387
|
-
// New data
|
|
1388
|
-
expect(states[4]).toMatchObject({
|
|
1389
|
-
data: 1,
|
|
1390
|
-
isFetching: false,
|
|
1391
|
-
status: 'success',
|
|
1392
|
-
error: null,
|
|
1393
|
-
isPreviousData: false,
|
|
1394
|
-
});
|
|
1395
|
-
// rerender Page 2
|
|
1396
|
-
expect(states[5]).toMatchObject({
|
|
1397
|
-
data: 1,
|
|
1398
|
-
isFetching: true,
|
|
1399
|
-
status: 'success',
|
|
1400
|
-
error: null,
|
|
1401
|
-
isPreviousData: true,
|
|
1402
|
-
});
|
|
1403
|
-
// Hook state update again
|
|
1404
|
-
expect(states[6]).toMatchObject({
|
|
1405
|
-
data: 1,
|
|
1406
|
-
isFetching: true,
|
|
1407
|
-
status: 'success',
|
|
1408
|
-
error: null,
|
|
1409
|
-
isPreviousData: true,
|
|
1410
|
-
});
|
|
1411
|
-
// Error
|
|
1412
|
-
expect(states[7]).toMatchObject({
|
|
1413
|
-
data: undefined,
|
|
1414
|
-
isFetching: false,
|
|
1415
|
-
status: 'error',
|
|
1416
|
-
isPreviousData: false,
|
|
1265
|
+
isPlaceholderData: false,
|
|
1417
1266
|
});
|
|
1418
|
-
expect(states[7]?.error).toHaveProperty('message', 'Error test');
|
|
1419
1267
|
});
|
|
1420
|
-
it('should not show initial data from next query if
|
|
1268
|
+
it('should not show initial data from next query if placeholderData is set', async () => {
|
|
1421
1269
|
const key = queryKey();
|
|
1422
1270
|
const states = [];
|
|
1423
1271
|
function Page() {
|
|
1424
1272
|
const [count, setCount] = createSignal(0);
|
|
1425
|
-
const state = createQuery(() =>
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1273
|
+
const state = createQuery(() => ({
|
|
1274
|
+
queryKey: [key, count()],
|
|
1275
|
+
queryFn: async () => {
|
|
1276
|
+
await sleep(10);
|
|
1277
|
+
return count();
|
|
1278
|
+
},
|
|
1279
|
+
initialData: 99,
|
|
1280
|
+
placeholderData: keepPreviousData,
|
|
1281
|
+
}));
|
|
1429
1282
|
createRenderEffect(() => {
|
|
1430
1283
|
states.push({ ...state });
|
|
1431
1284
|
});
|
|
@@ -1449,39 +1302,45 @@ describe('createQuery', () => {
|
|
|
1449
1302
|
data: 99,
|
|
1450
1303
|
isFetching: true,
|
|
1451
1304
|
isSuccess: true,
|
|
1452
|
-
|
|
1305
|
+
isPlaceholderData: false,
|
|
1453
1306
|
});
|
|
1454
1307
|
// Fetched
|
|
1455
1308
|
expect(states[1]).toMatchObject({
|
|
1456
1309
|
data: 0,
|
|
1457
1310
|
isFetching: false,
|
|
1458
1311
|
isSuccess: true,
|
|
1459
|
-
|
|
1312
|
+
isPlaceholderData: false,
|
|
1460
1313
|
});
|
|
1461
1314
|
// Set state
|
|
1462
1315
|
expect(states[2]).toMatchObject({
|
|
1463
1316
|
data: 99,
|
|
1464
1317
|
isFetching: true,
|
|
1465
1318
|
isSuccess: true,
|
|
1466
|
-
|
|
1319
|
+
isPlaceholderData: false,
|
|
1467
1320
|
});
|
|
1468
1321
|
// New data
|
|
1469
1322
|
expect(states[3]).toMatchObject({
|
|
1470
1323
|
data: 1,
|
|
1471
1324
|
isFetching: false,
|
|
1472
1325
|
isSuccess: true,
|
|
1473
|
-
|
|
1326
|
+
isPlaceholderData: false,
|
|
1474
1327
|
});
|
|
1475
1328
|
});
|
|
1476
|
-
it('should keep the previous data on disabled query when
|
|
1329
|
+
it('should keep the previous data on disabled query when placeholderData is set to identity function', async () => {
|
|
1477
1330
|
const key = queryKey();
|
|
1478
1331
|
const states = [];
|
|
1479
1332
|
function Page() {
|
|
1480
1333
|
const [count, setCount] = createSignal(0);
|
|
1481
|
-
const state = createQuery(() =>
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1334
|
+
const state = createQuery(() => ({
|
|
1335
|
+
queryKey: [key, count()],
|
|
1336
|
+
queryFn: async () => {
|
|
1337
|
+
await sleep(10);
|
|
1338
|
+
return count();
|
|
1339
|
+
},
|
|
1340
|
+
enabled: false,
|
|
1341
|
+
placeholderData: keepPreviousData,
|
|
1342
|
+
notifyOnChangeProps: 'all',
|
|
1343
|
+
}));
|
|
1485
1344
|
createRenderEffect(() => {
|
|
1486
1345
|
states.push({ ...state });
|
|
1487
1346
|
});
|
|
@@ -1507,55 +1366,61 @@ describe('createQuery', () => {
|
|
|
1507
1366
|
data: undefined,
|
|
1508
1367
|
isFetching: false,
|
|
1509
1368
|
isSuccess: false,
|
|
1510
|
-
|
|
1369
|
+
isPlaceholderData: false,
|
|
1511
1370
|
});
|
|
1512
1371
|
// Fetching query
|
|
1513
1372
|
expect(states[1]).toMatchObject({
|
|
1514
1373
|
data: undefined,
|
|
1515
1374
|
isFetching: true,
|
|
1516
1375
|
isSuccess: false,
|
|
1517
|
-
|
|
1376
|
+
isPlaceholderData: false,
|
|
1518
1377
|
});
|
|
1519
1378
|
// Fetched query
|
|
1520
1379
|
expect(states[2]).toMatchObject({
|
|
1521
1380
|
data: 0,
|
|
1522
1381
|
isFetching: false,
|
|
1523
1382
|
isSuccess: true,
|
|
1524
|
-
|
|
1383
|
+
isPlaceholderData: false,
|
|
1525
1384
|
});
|
|
1526
1385
|
// Set state
|
|
1527
1386
|
expect(states[3]).toMatchObject({
|
|
1528
1387
|
data: 0,
|
|
1529
1388
|
isFetching: false,
|
|
1530
1389
|
isSuccess: true,
|
|
1531
|
-
|
|
1390
|
+
isPlaceholderData: true,
|
|
1532
1391
|
});
|
|
1533
1392
|
// Fetching new query
|
|
1534
1393
|
expect(states[4]).toMatchObject({
|
|
1535
1394
|
data: 0,
|
|
1536
1395
|
isFetching: true,
|
|
1537
1396
|
isSuccess: true,
|
|
1538
|
-
|
|
1397
|
+
isPlaceholderData: true,
|
|
1539
1398
|
});
|
|
1540
1399
|
// Fetched new query
|
|
1541
1400
|
expect(states[5]).toMatchObject({
|
|
1542
1401
|
data: 1,
|
|
1543
1402
|
isFetching: false,
|
|
1544
1403
|
isSuccess: true,
|
|
1545
|
-
|
|
1404
|
+
isPlaceholderData: false,
|
|
1546
1405
|
});
|
|
1547
1406
|
});
|
|
1548
|
-
it('should keep the previous data on disabled query when
|
|
1407
|
+
it('should keep the previous data on disabled query when placeholderData is set and switching query key multiple times', async () => {
|
|
1549
1408
|
const key = queryKey();
|
|
1550
1409
|
const states = [];
|
|
1551
|
-
queryClient.setQueryData([key
|
|
1410
|
+
queryClient.setQueryData([key, 10], 10);
|
|
1552
1411
|
await sleep(10);
|
|
1553
1412
|
function Page() {
|
|
1554
1413
|
const [count, setCount] = createSignal(10);
|
|
1555
|
-
const state = createQuery(() =>
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1414
|
+
const state = createQuery(() => ({
|
|
1415
|
+
queryKey: [key, count()],
|
|
1416
|
+
queryFn: async () => {
|
|
1417
|
+
await sleep(10);
|
|
1418
|
+
return count();
|
|
1419
|
+
},
|
|
1420
|
+
enabled: false,
|
|
1421
|
+
placeholderData: keepPreviousData,
|
|
1422
|
+
notifyOnChangeProps: 'all',
|
|
1423
|
+
}));
|
|
1559
1424
|
createRenderEffect(() => {
|
|
1560
1425
|
states.push({ ...state });
|
|
1561
1426
|
});
|
|
@@ -1583,38 +1448,41 @@ describe('createQuery', () => {
|
|
|
1583
1448
|
data: 10,
|
|
1584
1449
|
isFetching: false,
|
|
1585
1450
|
isSuccess: true,
|
|
1586
|
-
|
|
1451
|
+
isPlaceholderData: false,
|
|
1587
1452
|
});
|
|
1588
1453
|
// Set state
|
|
1589
1454
|
expect(states[1]).toMatchObject({
|
|
1590
1455
|
data: 10,
|
|
1591
1456
|
isFetching: false,
|
|
1592
1457
|
isSuccess: true,
|
|
1593
|
-
|
|
1458
|
+
isPlaceholderData: true,
|
|
1594
1459
|
});
|
|
1595
1460
|
// Refetch
|
|
1596
1461
|
expect(states[2]).toMatchObject({
|
|
1597
1462
|
data: 10,
|
|
1598
1463
|
isFetching: true,
|
|
1599
1464
|
isSuccess: true,
|
|
1600
|
-
|
|
1465
|
+
isPlaceholderData: true,
|
|
1601
1466
|
});
|
|
1602
1467
|
// Refetch done
|
|
1603
1468
|
expect(states[3]).toMatchObject({
|
|
1604
1469
|
data: 12,
|
|
1605
1470
|
isFetching: false,
|
|
1606
1471
|
isSuccess: true,
|
|
1607
|
-
|
|
1472
|
+
isPlaceholderData: false,
|
|
1608
1473
|
});
|
|
1609
1474
|
});
|
|
1610
1475
|
it('should use the correct query function when components use different configurations', async () => {
|
|
1611
1476
|
const key = queryKey();
|
|
1612
1477
|
const states = [];
|
|
1613
1478
|
function FirstComponent() {
|
|
1614
|
-
const state = createQuery(
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1479
|
+
const state = createQuery(() => ({
|
|
1480
|
+
queryKey: key,
|
|
1481
|
+
queryFn: async () => {
|
|
1482
|
+
await sleep(10);
|
|
1483
|
+
return 1;
|
|
1484
|
+
},
|
|
1485
|
+
}));
|
|
1618
1486
|
createRenderEffect(() => {
|
|
1619
1487
|
states.push({ ...state });
|
|
1620
1488
|
});
|
|
@@ -1624,7 +1492,10 @@ describe('createQuery', () => {
|
|
|
1624
1492
|
</div>);
|
|
1625
1493
|
}
|
|
1626
1494
|
function SecondComponent() {
|
|
1627
|
-
createQuery(
|
|
1495
|
+
createQuery(() => ({
|
|
1496
|
+
queryKey: key,
|
|
1497
|
+
queryFn: () => 2,
|
|
1498
|
+
}));
|
|
1628
1499
|
return null;
|
|
1629
1500
|
}
|
|
1630
1501
|
function Page() {
|
|
@@ -1657,30 +1528,37 @@ describe('createQuery', () => {
|
|
|
1657
1528
|
const key = queryKey();
|
|
1658
1529
|
const states1 = [];
|
|
1659
1530
|
const states2 = [];
|
|
1660
|
-
await queryClient.prefetchQuery(
|
|
1661
|
-
|
|
1662
|
-
|
|
1531
|
+
await queryClient.prefetchQuery({
|
|
1532
|
+
queryKey: key,
|
|
1533
|
+
queryFn: async () => {
|
|
1534
|
+
await sleep(10);
|
|
1535
|
+
return 'prefetch';
|
|
1536
|
+
},
|
|
1663
1537
|
});
|
|
1664
1538
|
await sleep(20);
|
|
1665
1539
|
function FirstComponent() {
|
|
1666
|
-
const state = createQuery(
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1540
|
+
const state = createQuery(() => ({
|
|
1541
|
+
queryKey: key,
|
|
1542
|
+
queryFn: async () => {
|
|
1543
|
+
await sleep(10);
|
|
1544
|
+
return 'one';
|
|
1545
|
+
},
|
|
1670
1546
|
staleTime: 100,
|
|
1671
|
-
});
|
|
1547
|
+
}));
|
|
1672
1548
|
createRenderEffect(() => {
|
|
1673
1549
|
states1.push({ ...state });
|
|
1674
1550
|
});
|
|
1675
1551
|
return null;
|
|
1676
1552
|
}
|
|
1677
1553
|
function SecondComponent() {
|
|
1678
|
-
const state = createQuery(
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1554
|
+
const state = createQuery(() => ({
|
|
1555
|
+
queryKey: key,
|
|
1556
|
+
queryFn: async () => {
|
|
1557
|
+
await sleep(10);
|
|
1558
|
+
return 'two';
|
|
1559
|
+
},
|
|
1682
1560
|
staleTime: 10,
|
|
1683
|
-
});
|
|
1561
|
+
}));
|
|
1684
1562
|
createRenderEffect(() => {
|
|
1685
1563
|
states2.push({ ...state });
|
|
1686
1564
|
});
|
|
@@ -1742,9 +1620,11 @@ describe('createQuery', () => {
|
|
|
1742
1620
|
const key = queryKey();
|
|
1743
1621
|
const states = [];
|
|
1744
1622
|
function Page() {
|
|
1745
|
-
const state = createQuery(
|
|
1623
|
+
const state = createQuery(() => ({
|
|
1624
|
+
queryKey: key,
|
|
1625
|
+
queryFn: () => 'test',
|
|
1746
1626
|
staleTime: 50,
|
|
1747
|
-
});
|
|
1627
|
+
}));
|
|
1748
1628
|
createRenderEffect(() => {
|
|
1749
1629
|
states.push({ ...state });
|
|
1750
1630
|
});
|
|
@@ -1763,12 +1643,14 @@ describe('createQuery', () => {
|
|
|
1763
1643
|
const key = queryKey();
|
|
1764
1644
|
const states = [];
|
|
1765
1645
|
function Page() {
|
|
1766
|
-
const state = createQuery(
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1646
|
+
const state = createQuery(() => ({
|
|
1647
|
+
queryKey: key,
|
|
1648
|
+
queryFn: async () => {
|
|
1649
|
+
await sleep(5);
|
|
1650
|
+
return 'test';
|
|
1651
|
+
},
|
|
1770
1652
|
notifyOnChangeProps: ['data'],
|
|
1771
|
-
});
|
|
1653
|
+
}));
|
|
1772
1654
|
createRenderEffect(() => {
|
|
1773
1655
|
states.push({ ...state });
|
|
1774
1656
|
});
|
|
@@ -1787,7 +1669,7 @@ describe('createQuery', () => {
|
|
|
1787
1669
|
expect(states.length).toBe(2);
|
|
1788
1670
|
expect(states[0]).toMatchObject({
|
|
1789
1671
|
data: undefined,
|
|
1790
|
-
status: '
|
|
1672
|
+
status: 'pending',
|
|
1791
1673
|
isFetching: true,
|
|
1792
1674
|
});
|
|
1793
1675
|
expect(states[1]).toMatchObject({
|
|
@@ -1801,14 +1683,18 @@ describe('createQuery', () => {
|
|
|
1801
1683
|
const key1 = queryKey();
|
|
1802
1684
|
const key2 = queryKey();
|
|
1803
1685
|
function Page() {
|
|
1804
|
-
const first = createQuery(
|
|
1686
|
+
const first = createQuery(() => ({
|
|
1687
|
+
queryKey: key1,
|
|
1688
|
+
queryFn: () => 'data',
|
|
1805
1689
|
enabled: false,
|
|
1806
1690
|
initialData: 'init',
|
|
1807
|
-
});
|
|
1808
|
-
const second = createQuery(
|
|
1691
|
+
}));
|
|
1692
|
+
const second = createQuery(() => ({
|
|
1693
|
+
queryKey: key2,
|
|
1694
|
+
queryFn: () => 'data',
|
|
1809
1695
|
enabled: false,
|
|
1810
1696
|
initialData: 'init',
|
|
1811
|
-
});
|
|
1697
|
+
}));
|
|
1812
1698
|
return (<div>
|
|
1813
1699
|
<h2>First Data: {first.data}</h2>
|
|
1814
1700
|
<h2>Second Data: {second.data}</h2>
|
|
@@ -1835,14 +1721,14 @@ describe('createQuery', () => {
|
|
|
1835
1721
|
return 'data2';
|
|
1836
1722
|
};
|
|
1837
1723
|
function Page() {
|
|
1838
|
-
createQuery(key, queryFn1);
|
|
1839
|
-
createQuery(key, queryFn2);
|
|
1724
|
+
createQuery(() => ({ queryKey: key, queryFn: queryFn1 }));
|
|
1725
|
+
createQuery(() => ({ queryKey: key, queryFn: queryFn2 }));
|
|
1840
1726
|
return null;
|
|
1841
1727
|
}
|
|
1842
1728
|
render(() => (<QueryClientProvider client={queryClient}>
|
|
1843
1729
|
<Page />
|
|
1844
1730
|
</QueryClientProvider>));
|
|
1845
|
-
expect(queryCache.find(key
|
|
1731
|
+
expect(queryCache.find({ queryKey: key }).options.queryFn).toBe(queryFn1);
|
|
1846
1732
|
});
|
|
1847
1733
|
it('should batch re-renders', async () => {
|
|
1848
1734
|
const key = queryKey();
|
|
@@ -1852,8 +1738,8 @@ describe('createQuery', () => {
|
|
|
1852
1738
|
return 'data';
|
|
1853
1739
|
};
|
|
1854
1740
|
function Page() {
|
|
1855
|
-
createQuery(key, queryFn);
|
|
1856
|
-
createQuery(key, queryFn);
|
|
1741
|
+
createQuery(() => ({ queryKey: key, queryFn }));
|
|
1742
|
+
createQuery(() => ({ queryKey: key, queryFn }));
|
|
1857
1743
|
renders++;
|
|
1858
1744
|
return null;
|
|
1859
1745
|
}
|
|
@@ -1875,16 +1761,20 @@ describe('createQuery', () => {
|
|
|
1875
1761
|
};
|
|
1876
1762
|
function Page() {
|
|
1877
1763
|
const [count, setCount] = createSignal(0);
|
|
1878
|
-
createQuery(
|
|
1764
|
+
createQuery(() => ({
|
|
1765
|
+
queryKey: key,
|
|
1766
|
+
queryFn,
|
|
1879
1767
|
onSuccess: () => {
|
|
1880
1768
|
setCount((x) => x + 1);
|
|
1881
1769
|
},
|
|
1882
|
-
});
|
|
1883
|
-
createQuery(
|
|
1770
|
+
}));
|
|
1771
|
+
createQuery(() => ({
|
|
1772
|
+
queryKey: key,
|
|
1773
|
+
queryFn,
|
|
1884
1774
|
onSuccess: () => {
|
|
1885
1775
|
setCount((x) => x + 1);
|
|
1886
1776
|
},
|
|
1887
|
-
});
|
|
1777
|
+
}));
|
|
1888
1778
|
createEffect(() => {
|
|
1889
1779
|
renders++;
|
|
1890
1780
|
callbackCount = count();
|
|
@@ -1904,10 +1794,13 @@ describe('createQuery', () => {
|
|
|
1904
1794
|
const key = queryKey();
|
|
1905
1795
|
function Page() {
|
|
1906
1796
|
const [, setNewState] = createSignal('state');
|
|
1907
|
-
const state = createQuery(
|
|
1797
|
+
const state = createQuery(() => ({
|
|
1798
|
+
queryKey: key,
|
|
1799
|
+
queryFn: () => 'data',
|
|
1800
|
+
}));
|
|
1908
1801
|
createEffect(() => {
|
|
1909
1802
|
setActTimeout(() => {
|
|
1910
|
-
queryClient.setQueryData(key
|
|
1803
|
+
queryClient.setQueryData(key, 'new');
|
|
1911
1804
|
// Update with same state to make react discard the next render
|
|
1912
1805
|
setNewState('state');
|
|
1913
1806
|
}, 10);
|
|
@@ -1920,14 +1813,19 @@ describe('createQuery', () => {
|
|
|
1920
1813
|
await waitFor(() => screen.getByText('new'));
|
|
1921
1814
|
});
|
|
1922
1815
|
// See https://github.com/tannerlinsley/react-query/issues/170
|
|
1923
|
-
it('should start with status
|
|
1816
|
+
it('should start with status pending, fetchStatus idle if enabled is false', async () => {
|
|
1924
1817
|
const key1 = queryKey();
|
|
1925
1818
|
const key2 = queryKey();
|
|
1926
1819
|
function Page() {
|
|
1927
|
-
const first = createQuery(
|
|
1820
|
+
const first = createQuery(() => ({
|
|
1821
|
+
queryKey: key1,
|
|
1822
|
+
queryFn: () => 'data',
|
|
1928
1823
|
enabled: false,
|
|
1929
|
-
});
|
|
1930
|
-
const second = createQuery(
|
|
1824
|
+
}));
|
|
1825
|
+
const second = createQuery(() => ({
|
|
1826
|
+
queryKey: key2,
|
|
1827
|
+
queryFn: () => 'data',
|
|
1828
|
+
}));
|
|
1931
1829
|
return (<div>
|
|
1932
1830
|
<div>
|
|
1933
1831
|
First Status: {first.status}, {first.fetchStatus}
|
|
@@ -1941,36 +1839,41 @@ describe('createQuery', () => {
|
|
|
1941
1839
|
<Page />
|
|
1942
1840
|
</QueryClientProvider>));
|
|
1943
1841
|
// use "act" to wait for state update and prevent console warning
|
|
1944
|
-
screen.getByText('First Status:
|
|
1945
|
-
await waitFor(() => screen.getByText('Second Status:
|
|
1842
|
+
screen.getByText('First Status: pending, idle');
|
|
1843
|
+
await waitFor(() => screen.getByText('Second Status: pending, fetching'));
|
|
1946
1844
|
await waitFor(() => screen.getByText('Second Status: success, idle'));
|
|
1947
1845
|
});
|
|
1948
1846
|
// See https://github.com/tannerlinsley/react-query/issues/144
|
|
1949
|
-
it('should be in "
|
|
1847
|
+
it('should be in "pending" state by default', async () => {
|
|
1950
1848
|
const key = queryKey();
|
|
1951
1849
|
function Page() {
|
|
1952
|
-
const { status } = createQuery(
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1850
|
+
const { status } = createQuery(() => ({
|
|
1851
|
+
queryKey: key,
|
|
1852
|
+
queryFn: async () => {
|
|
1853
|
+
await sleep(10);
|
|
1854
|
+
return 'test';
|
|
1855
|
+
},
|
|
1856
|
+
}));
|
|
1956
1857
|
return <div>status: {status}</div>;
|
|
1957
1858
|
}
|
|
1958
1859
|
render(() => (<QueryClientProvider client={queryClient}>
|
|
1959
1860
|
<Page />
|
|
1960
1861
|
</QueryClientProvider>));
|
|
1961
|
-
screen.getByText('status:
|
|
1862
|
+
screen.getByText('status: pending');
|
|
1962
1863
|
});
|
|
1963
1864
|
// See https://github.com/tannerlinsley/react-query/issues/147
|
|
1964
1865
|
it('should not pass stringified variables to query function', async () => {
|
|
1965
1866
|
const key = queryKey();
|
|
1966
1867
|
const variables = { number: 5, boolean: false, object: {}, array: [] };
|
|
1967
1868
|
const states = [];
|
|
1968
|
-
// TODO(lukemurray): extract the query function to a variable queryFn
|
|
1969
1869
|
function Page() {
|
|
1970
|
-
const state = createQuery(() =>
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1870
|
+
const state = createQuery(() => ({
|
|
1871
|
+
queryKey: [key, variables],
|
|
1872
|
+
queryFn: async (ctx) => {
|
|
1873
|
+
await sleep(10);
|
|
1874
|
+
return ctx.queryKey;
|
|
1875
|
+
},
|
|
1876
|
+
}));
|
|
1974
1877
|
createRenderEffect(() => {
|
|
1975
1878
|
states.push({ ...state });
|
|
1976
1879
|
});
|
|
@@ -1980,15 +1883,17 @@ describe('createQuery', () => {
|
|
|
1980
1883
|
<Page />
|
|
1981
1884
|
</QueryClientProvider>));
|
|
1982
1885
|
await sleep(20);
|
|
1983
|
-
expect(states[1]?.data).toEqual([key
|
|
1886
|
+
expect(states[1]?.data).toEqual([key, variables]);
|
|
1984
1887
|
});
|
|
1985
1888
|
it('should not refetch query on focus when `enabled` is set to `false`', async () => {
|
|
1986
1889
|
const key = queryKey();
|
|
1987
1890
|
const queryFn = jest.fn().mockReturnValue('data');
|
|
1988
1891
|
function Page() {
|
|
1989
|
-
const { data = 'default' } = createQuery(
|
|
1892
|
+
const { data = 'default' } = createQuery(() => ({
|
|
1893
|
+
queryKey: key,
|
|
1894
|
+
queryFn,
|
|
1990
1895
|
enabled: false,
|
|
1991
|
-
});
|
|
1896
|
+
}));
|
|
1992
1897
|
return (<div>
|
|
1993
1898
|
<h1>{data}</h1>
|
|
1994
1899
|
</div>);
|
|
@@ -1997,7 +1902,7 @@ describe('createQuery', () => {
|
|
|
1997
1902
|
<Page />
|
|
1998
1903
|
</QueryClientProvider>));
|
|
1999
1904
|
await waitFor(() => screen.getByText('default'));
|
|
2000
|
-
window.dispatchEvent(new
|
|
1905
|
+
window.dispatchEvent(new Event('visibilitychange'));
|
|
2001
1906
|
expect(queryFn).not.toHaveBeenCalled();
|
|
2002
1907
|
});
|
|
2003
1908
|
it('should not refetch stale query on focus when `refetchOnWindowFocus` is set to `false`', async () => {
|
|
@@ -2005,10 +1910,12 @@ describe('createQuery', () => {
|
|
|
2005
1910
|
const states = [];
|
|
2006
1911
|
let count = 0;
|
|
2007
1912
|
function Page() {
|
|
2008
|
-
const state = createQuery(
|
|
1913
|
+
const state = createQuery(() => ({
|
|
1914
|
+
queryKey: key,
|
|
1915
|
+
queryFn: () => count++,
|
|
2009
1916
|
staleTime: 0,
|
|
2010
1917
|
refetchOnWindowFocus: false,
|
|
2011
|
-
});
|
|
1918
|
+
}));
|
|
2012
1919
|
createRenderEffect(() => {
|
|
2013
1920
|
states.push({ ...state });
|
|
2014
1921
|
});
|
|
@@ -2018,7 +1925,7 @@ describe('createQuery', () => {
|
|
|
2018
1925
|
<Page />
|
|
2019
1926
|
</QueryClientProvider>));
|
|
2020
1927
|
await sleep(10);
|
|
2021
|
-
window.dispatchEvent(new
|
|
1928
|
+
window.dispatchEvent(new Event('visibilitychange'));
|
|
2022
1929
|
await sleep(10);
|
|
2023
1930
|
expect(states.length).toBe(2);
|
|
2024
1931
|
expect(states[0]).toMatchObject({ data: undefined, isFetching: true });
|
|
@@ -2029,10 +1936,12 @@ describe('createQuery', () => {
|
|
|
2029
1936
|
const states = [];
|
|
2030
1937
|
let count = 0;
|
|
2031
1938
|
function Page() {
|
|
2032
|
-
const state = createQuery(
|
|
1939
|
+
const state = createQuery(() => ({
|
|
1940
|
+
queryKey: key,
|
|
1941
|
+
queryFn: () => count++,
|
|
2033
1942
|
staleTime: 0,
|
|
2034
1943
|
refetchOnWindowFocus: () => false,
|
|
2035
|
-
});
|
|
1944
|
+
}));
|
|
2036
1945
|
createRenderEffect(() => {
|
|
2037
1946
|
states.push({ ...state });
|
|
2038
1947
|
});
|
|
@@ -2042,7 +1951,7 @@ describe('createQuery', () => {
|
|
|
2042
1951
|
<Page />
|
|
2043
1952
|
</QueryClientProvider>));
|
|
2044
1953
|
await sleep(10);
|
|
2045
|
-
window.dispatchEvent(new
|
|
1954
|
+
window.dispatchEvent(new Event('visibilitychange'));
|
|
2046
1955
|
await sleep(10);
|
|
2047
1956
|
expect(states.length).toBe(2);
|
|
2048
1957
|
expect(states[0]).toMatchObject({ data: undefined, isFetching: true });
|
|
@@ -2053,10 +1962,12 @@ describe('createQuery', () => {
|
|
|
2053
1962
|
const states = [];
|
|
2054
1963
|
let count = 0;
|
|
2055
1964
|
function Page() {
|
|
2056
|
-
const state = createQuery(
|
|
1965
|
+
const state = createQuery(() => ({
|
|
1966
|
+
queryKey: key,
|
|
1967
|
+
queryFn: () => count++,
|
|
2057
1968
|
staleTime: Infinity,
|
|
2058
1969
|
refetchOnWindowFocus: true,
|
|
2059
|
-
});
|
|
1970
|
+
}));
|
|
2060
1971
|
createRenderEffect(() => {
|
|
2061
1972
|
states.push({ ...state });
|
|
2062
1973
|
});
|
|
@@ -2066,7 +1977,7 @@ describe('createQuery', () => {
|
|
|
2066
1977
|
<Page />
|
|
2067
1978
|
</QueryClientProvider>));
|
|
2068
1979
|
await sleep(10);
|
|
2069
|
-
window.dispatchEvent(new
|
|
1980
|
+
window.dispatchEvent(new Event('visibilitychange'));
|
|
2070
1981
|
await sleep(10);
|
|
2071
1982
|
expect(states.length).toBe(2);
|
|
2072
1983
|
expect(states[0]).toMatchObject({ data: undefined, isFetching: true });
|
|
@@ -2077,13 +1988,15 @@ describe('createQuery', () => {
|
|
|
2077
1988
|
const states = [];
|
|
2078
1989
|
let count = 0;
|
|
2079
1990
|
function Page() {
|
|
2080
|
-
const state = createQuery(
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
1991
|
+
const state = createQuery(() => ({
|
|
1992
|
+
queryKey: key,
|
|
1993
|
+
queryFn: async () => {
|
|
1994
|
+
await sleep(10);
|
|
1995
|
+
return count++;
|
|
1996
|
+
},
|
|
2084
1997
|
staleTime: Infinity,
|
|
2085
1998
|
refetchOnWindowFocus: 'always',
|
|
2086
|
-
});
|
|
1999
|
+
}));
|
|
2087
2000
|
createRenderEffect(() => {
|
|
2088
2001
|
states.push({ ...state });
|
|
2089
2002
|
});
|
|
@@ -2093,7 +2006,7 @@ describe('createQuery', () => {
|
|
|
2093
2006
|
<Page />
|
|
2094
2007
|
</QueryClientProvider>));
|
|
2095
2008
|
await sleep(20);
|
|
2096
|
-
window.dispatchEvent(new
|
|
2009
|
+
window.dispatchEvent(new Event('visibilitychange'));
|
|
2097
2010
|
await sleep(20);
|
|
2098
2011
|
await waitFor(() => expect(states.length).toBe(4));
|
|
2099
2012
|
expect(states[0]).toMatchObject({ data: undefined, isFetching: true });
|
|
@@ -2106,14 +2019,16 @@ describe('createQuery', () => {
|
|
|
2106
2019
|
const states = [];
|
|
2107
2020
|
let count = 0;
|
|
2108
2021
|
function Page() {
|
|
2109
|
-
const state = createQuery(
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2022
|
+
const state = createQuery(() => ({
|
|
2023
|
+
queryKey: key,
|
|
2024
|
+
queryFn: async () => {
|
|
2025
|
+
await sleep(10);
|
|
2026
|
+
return count++;
|
|
2027
|
+
},
|
|
2113
2028
|
staleTime: 0,
|
|
2114
2029
|
retry: 0,
|
|
2115
2030
|
refetchOnWindowFocus: (query) => (query.state.data || 0) < 1,
|
|
2116
|
-
});
|
|
2031
|
+
}));
|
|
2117
2032
|
createRenderEffect(() => {
|
|
2118
2033
|
states.push({ ...state });
|
|
2119
2034
|
});
|
|
@@ -2126,7 +2041,7 @@ describe('createQuery', () => {
|
|
|
2126
2041
|
expect(states.length).toBe(2);
|
|
2127
2042
|
expect(states[0]).toMatchObject({ data: undefined, isFetching: true });
|
|
2128
2043
|
expect(states[1]).toMatchObject({ data: 0, isFetching: false });
|
|
2129
|
-
window.dispatchEvent(new
|
|
2044
|
+
window.dispatchEvent(new Event('visibilitychange'));
|
|
2130
2045
|
await screen.findByText('data: 1');
|
|
2131
2046
|
// refetch should happen
|
|
2132
2047
|
expect(states.length).toBe(4);
|
|
@@ -2139,12 +2054,17 @@ describe('createQuery', () => {
|
|
|
2139
2054
|
it('should refetch fresh query when refetchOnMount is set to always', async () => {
|
|
2140
2055
|
const key = queryKey();
|
|
2141
2056
|
const states = [];
|
|
2142
|
-
await queryClient.prefetchQuery(
|
|
2057
|
+
await queryClient.prefetchQuery({
|
|
2058
|
+
queryKey: key,
|
|
2059
|
+
queryFn: () => 'prefetched',
|
|
2060
|
+
});
|
|
2143
2061
|
function Page() {
|
|
2144
|
-
const state = createQuery(
|
|
2062
|
+
const state = createQuery(() => ({
|
|
2063
|
+
queryKey: key,
|
|
2064
|
+
queryFn: () => 'data',
|
|
2145
2065
|
refetchOnMount: 'always',
|
|
2146
2066
|
staleTime: Infinity,
|
|
2147
|
-
});
|
|
2067
|
+
}));
|
|
2148
2068
|
createRenderEffect(() => {
|
|
2149
2069
|
states.push({ ...state });
|
|
2150
2070
|
});
|
|
@@ -2169,13 +2089,18 @@ describe('createQuery', () => {
|
|
|
2169
2089
|
it('should refetch stale query when refetchOnMount is set to true', async () => {
|
|
2170
2090
|
const key = queryKey();
|
|
2171
2091
|
const states = [];
|
|
2172
|
-
await queryClient.prefetchQuery(
|
|
2092
|
+
await queryClient.prefetchQuery({
|
|
2093
|
+
queryKey: key,
|
|
2094
|
+
queryFn: () => 'prefetched',
|
|
2095
|
+
});
|
|
2173
2096
|
await sleep(10);
|
|
2174
2097
|
function Page() {
|
|
2175
|
-
const state = createQuery(
|
|
2098
|
+
const state = createQuery(() => ({
|
|
2099
|
+
queryKey: key,
|
|
2100
|
+
queryFn: () => 'data',
|
|
2176
2101
|
refetchOnMount: true,
|
|
2177
2102
|
staleTime: 0,
|
|
2178
|
-
});
|
|
2103
|
+
}));
|
|
2179
2104
|
createRenderEffect(() => {
|
|
2180
2105
|
states.push({ ...state });
|
|
2181
2106
|
});
|
|
@@ -2200,12 +2125,16 @@ describe('createQuery', () => {
|
|
|
2200
2125
|
it('should set status to error if queryFn throws', async () => {
|
|
2201
2126
|
const key = queryKey();
|
|
2202
2127
|
function Page() {
|
|
2203
|
-
const state = createQuery(
|
|
2204
|
-
|
|
2205
|
-
|
|
2128
|
+
const state = createQuery(() => ({
|
|
2129
|
+
queryKey: key,
|
|
2130
|
+
queryFn: () => {
|
|
2131
|
+
return Promise.reject(new Error('Error test jaylen'));
|
|
2132
|
+
},
|
|
2133
|
+
retry: false,
|
|
2134
|
+
}));
|
|
2206
2135
|
return (<div>
|
|
2207
2136
|
<h1>{state.status}</h1>
|
|
2208
|
-
<h2>{state.error}</h2>
|
|
2137
|
+
<h2>{state.error?.message}</h2>
|
|
2209
2138
|
</div>);
|
|
2210
2139
|
}
|
|
2211
2140
|
render(() => (<QueryClientProvider client={queryClient}>
|
|
@@ -2214,13 +2143,18 @@ describe('createQuery', () => {
|
|
|
2214
2143
|
await waitFor(() => screen.getByText('error'));
|
|
2215
2144
|
await waitFor(() => screen.getByText('Error test jaylen'));
|
|
2216
2145
|
});
|
|
2217
|
-
it('should throw error if queryFn throws and
|
|
2146
|
+
it('should throw error if queryFn throws and throwErrors is in use', async () => {
|
|
2218
2147
|
const key = queryKey();
|
|
2219
2148
|
function Page() {
|
|
2220
|
-
const state = createQuery(
|
|
2149
|
+
const state = createQuery(() => ({
|
|
2150
|
+
queryKey: key,
|
|
2151
|
+
queryFn: () => Promise.reject(new Error('Error test jaylen')),
|
|
2152
|
+
retry: false,
|
|
2153
|
+
throwErrors: true,
|
|
2154
|
+
}));
|
|
2221
2155
|
return (<div>
|
|
2222
2156
|
<h1>{state.status}</h1>
|
|
2223
|
-
<h2>{state.error}</h2>
|
|
2157
|
+
<h2>{state.error?.message}</h2>
|
|
2224
2158
|
</div>);
|
|
2225
2159
|
}
|
|
2226
2160
|
render(() => (<QueryClientProvider client={queryClient}>
|
|
@@ -2230,13 +2164,15 @@ describe('createQuery', () => {
|
|
|
2230
2164
|
</QueryClientProvider>));
|
|
2231
2165
|
await waitFor(() => screen.getByText('error boundary'));
|
|
2232
2166
|
});
|
|
2233
|
-
it('should update with data if we observe no properties and
|
|
2167
|
+
it('should update with data if we observe no properties and throwErrors', async () => {
|
|
2234
2168
|
const key = queryKey();
|
|
2235
2169
|
let result;
|
|
2236
2170
|
function Page() {
|
|
2237
|
-
const query = createQuery(
|
|
2238
|
-
|
|
2239
|
-
|
|
2171
|
+
const query = createQuery(() => ({
|
|
2172
|
+
queryKey: key,
|
|
2173
|
+
queryFn: () => Promise.resolve('data'),
|
|
2174
|
+
throwErrors: true,
|
|
2175
|
+
}));
|
|
2240
2176
|
createEffect(() => {
|
|
2241
2177
|
result = query;
|
|
2242
2178
|
});
|
|
@@ -2251,13 +2187,15 @@ describe('createQuery', () => {
|
|
|
2251
2187
|
it('should set status to error instead of throwing when error should not be thrown', async () => {
|
|
2252
2188
|
const key = queryKey();
|
|
2253
2189
|
function Page() {
|
|
2254
|
-
const state = createQuery(
|
|
2190
|
+
const state = createQuery(() => ({
|
|
2191
|
+
queryKey: key,
|
|
2192
|
+
queryFn: () => Promise.reject(new Error('Local Error')),
|
|
2255
2193
|
retry: false,
|
|
2256
|
-
|
|
2257
|
-
});
|
|
2194
|
+
throwErrors: (err) => err.message !== 'Local Error',
|
|
2195
|
+
}));
|
|
2258
2196
|
return (<div>
|
|
2259
2197
|
<h1>{state.status}</h1>
|
|
2260
|
-
<h2>{state.error}</h2>
|
|
2198
|
+
<h2>{state.error?.message}</h2>
|
|
2261
2199
|
</div>);
|
|
2262
2200
|
}
|
|
2263
2201
|
render(() => (<QueryClientProvider client={queryClient}>
|
|
@@ -2271,10 +2209,12 @@ describe('createQuery', () => {
|
|
|
2271
2209
|
it('should throw error instead of setting status when error should be thrown', async () => {
|
|
2272
2210
|
const key = queryKey();
|
|
2273
2211
|
function Page() {
|
|
2274
|
-
const state = createQuery(
|
|
2212
|
+
const state = createQuery(() => ({
|
|
2213
|
+
queryKey: key,
|
|
2214
|
+
queryFn: () => Promise.reject(new Error('Remote Error')),
|
|
2275
2215
|
retry: false,
|
|
2276
|
-
|
|
2277
|
-
});
|
|
2216
|
+
throwErrors: (err) => err.message !== 'Local Error',
|
|
2217
|
+
}));
|
|
2278
2218
|
return (<div>
|
|
2279
2219
|
<h1>{state.status}</h1>
|
|
2280
2220
|
<h2>{state.error?.message ?? ''}</h2>
|
|
@@ -2296,18 +2236,20 @@ describe('createQuery', () => {
|
|
|
2296
2236
|
const key = queryKey();
|
|
2297
2237
|
let count = 0;
|
|
2298
2238
|
function Page() {
|
|
2299
|
-
const result = createQuery(
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2239
|
+
const result = createQuery(() => ({
|
|
2240
|
+
queryKey: key,
|
|
2241
|
+
queryFn: async () => {
|
|
2242
|
+
count++;
|
|
2243
|
+
await sleep(10);
|
|
2244
|
+
return Promise.reject(new Error('some error'));
|
|
2245
|
+
},
|
|
2304
2246
|
retry: 2,
|
|
2305
2247
|
retryDelay: 100,
|
|
2306
|
-
});
|
|
2248
|
+
}));
|
|
2307
2249
|
return (<div>
|
|
2308
|
-
<div>error: {result.error ?? 'null'}</div>
|
|
2250
|
+
<div>error: {result.error?.message ?? 'null'}</div>
|
|
2309
2251
|
<div>failureCount: {result.failureCount}</div>
|
|
2310
|
-
<div>failureReason: {result.failureReason}</div>
|
|
2252
|
+
<div>failureReason: {result.failureReason?.message}</div>
|
|
2311
2253
|
</div>);
|
|
2312
2254
|
}
|
|
2313
2255
|
function App() {
|
|
@@ -2333,18 +2275,20 @@ describe('createQuery', () => {
|
|
|
2333
2275
|
const key = queryKey();
|
|
2334
2276
|
let count = 0;
|
|
2335
2277
|
function Page() {
|
|
2336
|
-
const result = createQuery(
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2278
|
+
const result = createQuery(() => ({
|
|
2279
|
+
queryKey: key,
|
|
2280
|
+
queryFn: async () => {
|
|
2281
|
+
count++;
|
|
2282
|
+
await sleep(10);
|
|
2283
|
+
return Promise.reject(new Error('some error'));
|
|
2284
|
+
},
|
|
2341
2285
|
retry: 2,
|
|
2342
2286
|
retryDelay: 100,
|
|
2343
|
-
});
|
|
2287
|
+
}));
|
|
2344
2288
|
return (<div>
|
|
2345
|
-
<div>error: {result.error ?? 'null'}</div>
|
|
2289
|
+
<div>error: {result.error?.message ?? 'null'}</div>
|
|
2346
2290
|
<div>failureCount: {result.failureCount}</div>
|
|
2347
|
-
<div>failureReason: {result.failureReason}</div>
|
|
2291
|
+
<div>failureReason: {result.failureReason?.message}</div>
|
|
2348
2292
|
</div>);
|
|
2349
2293
|
}
|
|
2350
2294
|
function App() {
|
|
@@ -2352,7 +2296,7 @@ describe('createQuery', () => {
|
|
|
2352
2296
|
const toggle = () => setShow((s) => !s);
|
|
2353
2297
|
return (<div>
|
|
2354
2298
|
<button onClick={toggle}>{show() ? 'hide' : 'show'}</button>
|
|
2355
|
-
<button onClick={() => queryClient.cancelQueries({ queryKey: key
|
|
2299
|
+
<button onClick={() => queryClient.cancelQueries({ queryKey: key })}>
|
|
2356
2300
|
cancel
|
|
2357
2301
|
</button>
|
|
2358
2302
|
{show() && <Page />}
|
|
@@ -2374,12 +2318,17 @@ describe('createQuery', () => {
|
|
|
2374
2318
|
it('should always fetch if refetchOnMount is set to always', async () => {
|
|
2375
2319
|
const key = queryKey();
|
|
2376
2320
|
const states = [];
|
|
2377
|
-
await queryClient.prefetchQuery(
|
|
2321
|
+
await queryClient.prefetchQuery({
|
|
2322
|
+
queryKey: key,
|
|
2323
|
+
queryFn: () => 'prefetched',
|
|
2324
|
+
});
|
|
2378
2325
|
function Page() {
|
|
2379
|
-
const state = createQuery(
|
|
2326
|
+
const state = createQuery(() => ({
|
|
2327
|
+
queryKey: key,
|
|
2328
|
+
queryFn: () => 'data',
|
|
2380
2329
|
refetchOnMount: 'always',
|
|
2381
2330
|
staleTime: 50,
|
|
2382
|
-
});
|
|
2331
|
+
}));
|
|
2383
2332
|
createRenderEffect(() => {
|
|
2384
2333
|
states.push({ ...state });
|
|
2385
2334
|
});
|
|
@@ -2414,9 +2363,11 @@ describe('createQuery', () => {
|
|
|
2414
2363
|
const key = queryKey();
|
|
2415
2364
|
const states = [];
|
|
2416
2365
|
function Page() {
|
|
2417
|
-
const state = createQuery(
|
|
2366
|
+
const state = createQuery(() => ({
|
|
2367
|
+
queryKey: key,
|
|
2368
|
+
queryFn: () => 'data',
|
|
2418
2369
|
initialData: 'initial',
|
|
2419
|
-
});
|
|
2370
|
+
}));
|
|
2420
2371
|
createRenderEffect(() => {
|
|
2421
2372
|
states.push({ ...state });
|
|
2422
2373
|
});
|
|
@@ -2442,10 +2393,12 @@ describe('createQuery', () => {
|
|
|
2442
2393
|
const key = queryKey();
|
|
2443
2394
|
const states = [];
|
|
2444
2395
|
function Page() {
|
|
2445
|
-
const state = createQuery(
|
|
2396
|
+
const state = createQuery(() => ({
|
|
2397
|
+
queryKey: key,
|
|
2398
|
+
queryFn: () => 'data',
|
|
2446
2399
|
staleTime: 50,
|
|
2447
2400
|
initialData: 'initial',
|
|
2448
|
-
});
|
|
2401
|
+
}));
|
|
2449
2402
|
createRenderEffect(() => {
|
|
2450
2403
|
states.push({ ...state });
|
|
2451
2404
|
});
|
|
@@ -2472,11 +2425,13 @@ describe('createQuery', () => {
|
|
|
2472
2425
|
const states = [];
|
|
2473
2426
|
const oneSecondAgo = Date.now() - 1000;
|
|
2474
2427
|
function Page() {
|
|
2475
|
-
const state = createQuery(
|
|
2428
|
+
const state = createQuery(() => ({
|
|
2429
|
+
queryKey: key,
|
|
2430
|
+
queryFn: () => 'data',
|
|
2476
2431
|
staleTime: 50,
|
|
2477
2432
|
initialData: 'initial',
|
|
2478
2433
|
initialDataUpdatedAt: oneSecondAgo,
|
|
2479
|
-
});
|
|
2434
|
+
}));
|
|
2480
2435
|
createRenderEffect(() => {
|
|
2481
2436
|
states.push({ ...state });
|
|
2482
2437
|
});
|
|
@@ -2507,11 +2462,13 @@ describe('createQuery', () => {
|
|
|
2507
2462
|
const key = queryKey();
|
|
2508
2463
|
const states = [];
|
|
2509
2464
|
function Page() {
|
|
2510
|
-
const state = createQuery(
|
|
2465
|
+
const state = createQuery(() => ({
|
|
2466
|
+
queryKey: key,
|
|
2467
|
+
queryFn: () => 'data',
|
|
2511
2468
|
staleTime: 10 * 1000,
|
|
2512
2469
|
initialData: 'initial',
|
|
2513
2470
|
initialDataUpdatedAt: 0,
|
|
2514
|
-
});
|
|
2471
|
+
}));
|
|
2515
2472
|
createRenderEffect(() => {
|
|
2516
2473
|
states.push({ ...state });
|
|
2517
2474
|
});
|
|
@@ -2538,10 +2495,12 @@ describe('createQuery', () => {
|
|
|
2538
2495
|
const states = [];
|
|
2539
2496
|
function Page() {
|
|
2540
2497
|
const [count, setCount] = createSignal(0);
|
|
2541
|
-
const state = createQuery(() =>
|
|
2498
|
+
const state = createQuery(() => ({
|
|
2499
|
+
queryKey: [key, count()],
|
|
2500
|
+
queryFn: () => ({ count: 10 }),
|
|
2542
2501
|
staleTime: Infinity,
|
|
2543
2502
|
initialData: () => ({ count: count() }),
|
|
2544
|
-
});
|
|
2503
|
+
}));
|
|
2545
2504
|
createRenderEffect(() => {
|
|
2546
2505
|
states.push({ ...state });
|
|
2547
2506
|
});
|
|
@@ -2566,23 +2525,25 @@ describe('createQuery', () => {
|
|
|
2566
2525
|
const key = queryKey();
|
|
2567
2526
|
const queryFn = jest.fn();
|
|
2568
2527
|
queryFn.mockImplementation(() => {
|
|
2569
|
-
return Promise.reject('Error test Barrett');
|
|
2528
|
+
return Promise.reject(new Error('Error test Barrett'));
|
|
2570
2529
|
});
|
|
2571
2530
|
function Page() {
|
|
2572
|
-
const state = createQuery(
|
|
2531
|
+
const state = createQuery(() => ({
|
|
2532
|
+
queryKey: key,
|
|
2533
|
+
queryFn,
|
|
2573
2534
|
retry: 1,
|
|
2574
2535
|
retryDelay: 1,
|
|
2575
|
-
});
|
|
2536
|
+
}));
|
|
2576
2537
|
return (<div>
|
|
2577
2538
|
<h1>{state.status}</h1>
|
|
2578
2539
|
<h2>Failed {state.failureCount} times</h2>
|
|
2579
|
-
<h2>Failed because {state.failureReason}</h2>
|
|
2540
|
+
<h2>Failed because {state.failureReason?.message}</h2>
|
|
2580
2541
|
</div>);
|
|
2581
2542
|
}
|
|
2582
2543
|
render(() => (<QueryClientProvider client={queryClient}>
|
|
2583
2544
|
<Page />
|
|
2584
2545
|
</QueryClientProvider>));
|
|
2585
|
-
await waitFor(() => screen.getByText('
|
|
2546
|
+
await waitFor(() => screen.getByText('pending'));
|
|
2586
2547
|
await waitFor(() => screen.getByText('error'));
|
|
2587
2548
|
// query should fail `retry + 1` times, since first time isn't a "retry"
|
|
2588
2549
|
await waitFor(() => screen.getByText('Failed 2 times'));
|
|
@@ -2593,27 +2554,29 @@ describe('createQuery', () => {
|
|
|
2593
2554
|
const key = queryKey();
|
|
2594
2555
|
const queryFn = jest.fn();
|
|
2595
2556
|
queryFn.mockImplementationOnce(() => {
|
|
2596
|
-
return Promise.reject('Error test Tanner');
|
|
2557
|
+
return Promise.reject(new Error('Error test Tanner'));
|
|
2597
2558
|
});
|
|
2598
2559
|
queryFn.mockImplementation(() => {
|
|
2599
|
-
return Promise.reject('NoRetry');
|
|
2560
|
+
return Promise.reject(new Error('NoRetry'));
|
|
2600
2561
|
});
|
|
2601
2562
|
function Page() {
|
|
2602
|
-
const state = createQuery(
|
|
2563
|
+
const state = createQuery(() => ({
|
|
2564
|
+
queryKey: key,
|
|
2565
|
+
queryFn,
|
|
2603
2566
|
retryDelay: 1,
|
|
2604
|
-
retry: (_failureCount, err) => err !== 'NoRetry',
|
|
2605
|
-
});
|
|
2567
|
+
retry: (_failureCount, err) => err.message !== 'NoRetry',
|
|
2568
|
+
}));
|
|
2606
2569
|
return (<div>
|
|
2607
2570
|
<h1>{state.status}</h1>
|
|
2608
2571
|
<h2>Failed {state.failureCount} times</h2>
|
|
2609
|
-
<h2>Failed because {state.failureReason}</h2>
|
|
2610
|
-
<h2>{state.error}</h2>
|
|
2572
|
+
<h2>Failed because {state.failureReason?.message}</h2>
|
|
2573
|
+
<h2>{state.error?.message}</h2>
|
|
2611
2574
|
</div>);
|
|
2612
2575
|
}
|
|
2613
2576
|
render(() => (<QueryClientProvider client={queryClient}>
|
|
2614
2577
|
<Page />
|
|
2615
2578
|
</QueryClientProvider>));
|
|
2616
|
-
await waitFor(() => screen.getByText('
|
|
2579
|
+
await waitFor(() => screen.getByText('pending'));
|
|
2617
2580
|
await waitFor(() => screen.getByText('error'));
|
|
2618
2581
|
await waitFor(() => screen.getByText('Failed 2 times'));
|
|
2619
2582
|
await waitFor(() => screen.getByText('Failed because NoRetry'));
|
|
@@ -2627,10 +2590,12 @@ describe('createQuery', () => {
|
|
|
2627
2590
|
return Promise.reject({ delay: 50 });
|
|
2628
2591
|
});
|
|
2629
2592
|
function Page() {
|
|
2630
|
-
const state = createQuery(
|
|
2593
|
+
const state = createQuery(() => ({
|
|
2594
|
+
queryKey: key,
|
|
2595
|
+
queryFn,
|
|
2631
2596
|
retry: 1,
|
|
2632
2597
|
retryDelay: (_, error) => error.delay,
|
|
2633
|
-
});
|
|
2598
|
+
}));
|
|
2634
2599
|
return (<div>
|
|
2635
2600
|
<h1>{state.status}</h1>
|
|
2636
2601
|
<h2>Failed {state.failureCount} times</h2>
|
|
@@ -2653,13 +2618,15 @@ describe('createQuery', () => {
|
|
|
2653
2618
|
const visibilityMock = mockVisibilityState('hidden');
|
|
2654
2619
|
let count = 0;
|
|
2655
2620
|
function Page() {
|
|
2656
|
-
const query = createQuery(
|
|
2657
|
-
|
|
2658
|
-
|
|
2659
|
-
|
|
2621
|
+
const query = createQuery(() => ({
|
|
2622
|
+
queryKey: key,
|
|
2623
|
+
queryFn: () => {
|
|
2624
|
+
count++;
|
|
2625
|
+
return Promise.reject(`fetching error ${count}`);
|
|
2626
|
+
},
|
|
2660
2627
|
retry: 3,
|
|
2661
2628
|
retryDelay: 1,
|
|
2662
|
-
});
|
|
2629
|
+
}));
|
|
2663
2630
|
return (<div>
|
|
2664
2631
|
<div>error {String(query.error)}</div>
|
|
2665
2632
|
<div>status {query.status}</div>
|
|
@@ -2673,14 +2640,14 @@ describe('createQuery', () => {
|
|
|
2673
2640
|
// The query should display the first error result
|
|
2674
2641
|
await waitFor(() => screen.getByText('failureCount 1'));
|
|
2675
2642
|
await waitFor(() => screen.getByText('failureReason fetching error 1'));
|
|
2676
|
-
await waitFor(() => screen.getByText('status
|
|
2643
|
+
await waitFor(() => screen.getByText('status pending'));
|
|
2677
2644
|
await waitFor(() => screen.getByText('error null'));
|
|
2678
2645
|
// Check if the query really paused
|
|
2679
2646
|
await sleep(10);
|
|
2680
2647
|
await waitFor(() => screen.getByText('failureCount 1'));
|
|
2681
2648
|
await waitFor(() => screen.getByText('failureReason fetching error 1'));
|
|
2682
2649
|
visibilityMock.mockRestore();
|
|
2683
|
-
window.dispatchEvent(new
|
|
2650
|
+
window.dispatchEvent(new Event('visibilitychange'));
|
|
2684
2651
|
// Wait for the final result
|
|
2685
2652
|
await waitFor(() => screen.getByText('failureCount 4'));
|
|
2686
2653
|
await waitFor(() => screen.getByText('failureReason fetching error 4'));
|
|
@@ -2690,15 +2657,16 @@ describe('createQuery', () => {
|
|
|
2690
2657
|
await sleep(10);
|
|
2691
2658
|
await waitFor(() => screen.getByText('failureCount 4'));
|
|
2692
2659
|
await waitFor(() => screen.getByText('failureReason fetching error 4'));
|
|
2693
|
-
// Check if the error has been logged in the console
|
|
2694
|
-
expect(mockLogger.error).toHaveBeenCalledWith('fetching error 4');
|
|
2695
2660
|
});
|
|
2696
2661
|
it('should fetch on mount when a query was already created with setQueryData', async () => {
|
|
2697
2662
|
const key = queryKey();
|
|
2698
2663
|
const states = [];
|
|
2699
|
-
queryClient.setQueryData(key
|
|
2664
|
+
queryClient.setQueryData(key, 'prefetched');
|
|
2700
2665
|
function Page() {
|
|
2701
|
-
const state = createQuery(
|
|
2666
|
+
const state = createQuery(() => ({
|
|
2667
|
+
queryKey: key,
|
|
2668
|
+
queryFn: () => 'data',
|
|
2669
|
+
}));
|
|
2702
2670
|
createRenderEffect(() => {
|
|
2703
2671
|
states.push({ ...state });
|
|
2704
2672
|
});
|
|
@@ -2728,12 +2696,15 @@ describe('createQuery', () => {
|
|
|
2728
2696
|
// make page unfocused
|
|
2729
2697
|
const visibilityMock = mockVisibilityState('hidden');
|
|
2730
2698
|
// set data in cache to check if the hook query fn is actually called
|
|
2731
|
-
queryClient.setQueryData(key
|
|
2699
|
+
queryClient.setQueryData(key, 'prefetched');
|
|
2732
2700
|
function Page() {
|
|
2733
|
-
const state = createQuery(
|
|
2734
|
-
|
|
2735
|
-
|
|
2736
|
-
|
|
2701
|
+
const state = createQuery(() => ({
|
|
2702
|
+
queryKey: key,
|
|
2703
|
+
queryFn: async () => {
|
|
2704
|
+
await sleep(10);
|
|
2705
|
+
return 'data';
|
|
2706
|
+
},
|
|
2707
|
+
}));
|
|
2737
2708
|
createRenderEffect(() => {
|
|
2738
2709
|
states.push({ ...state });
|
|
2739
2710
|
});
|
|
@@ -2747,7 +2718,7 @@ describe('createQuery', () => {
|
|
|
2747
2718
|
await waitFor(() => expect(states.length).toBe(2));
|
|
2748
2719
|
// reset visibilityState to original value
|
|
2749
2720
|
visibilityMock.mockRestore();
|
|
2750
|
-
window.dispatchEvent(new
|
|
2721
|
+
window.dispatchEvent(new Event('visibilitychange'));
|
|
2751
2722
|
await waitFor(() => expect(states.length).toBe(4));
|
|
2752
2723
|
expect(states).toMatchObject([
|
|
2753
2724
|
{
|
|
@@ -2780,12 +2751,14 @@ describe('createQuery', () => {
|
|
|
2780
2751
|
queryFn.mockImplementation(() => 'data');
|
|
2781
2752
|
const prefetchQueryFn = jest.fn();
|
|
2782
2753
|
prefetchQueryFn.mockImplementation(() => 'not yet...');
|
|
2783
|
-
await queryClient.prefetchQuery(
|
|
2754
|
+
await queryClient.prefetchQuery({
|
|
2755
|
+
queryKey: key,
|
|
2756
|
+
queryFn: prefetchQueryFn,
|
|
2784
2757
|
staleTime: 10,
|
|
2785
2758
|
});
|
|
2786
2759
|
await sleep(11);
|
|
2787
2760
|
function Page() {
|
|
2788
|
-
const state = createQuery(key, queryFn);
|
|
2761
|
+
const state = createQuery(() => ({ queryKey: key, queryFn }));
|
|
2789
2762
|
createRenderEffect(() => {
|
|
2790
2763
|
states.push({ ...state });
|
|
2791
2764
|
});
|
|
@@ -2807,14 +2780,14 @@ describe('createQuery', () => {
|
|
|
2807
2780
|
await sleep(10);
|
|
2808
2781
|
return 'not yet...';
|
|
2809
2782
|
});
|
|
2810
|
-
await queryClient.prefetchQuery(
|
|
2783
|
+
await queryClient.prefetchQuery({
|
|
2784
|
+
queryKey: key,
|
|
2785
|
+
queryFn: prefetchQueryFn,
|
|
2811
2786
|
staleTime: 1000,
|
|
2812
2787
|
});
|
|
2813
2788
|
await sleep(0);
|
|
2814
2789
|
function Page() {
|
|
2815
|
-
createQuery(key, queryFn,
|
|
2816
|
-
staleTime: 1000,
|
|
2817
|
-
});
|
|
2790
|
+
createQuery(() => ({ queryKey: key, queryFn, staleTime: 1000 }));
|
|
2818
2791
|
return null;
|
|
2819
2792
|
}
|
|
2820
2793
|
render(() => (<QueryClientProvider client={queryClient}>
|
|
@@ -2829,15 +2802,19 @@ describe('createQuery', () => {
|
|
|
2829
2802
|
const key = queryKey();
|
|
2830
2803
|
function Page() {
|
|
2831
2804
|
let counter = 0;
|
|
2832
|
-
const query = createQuery(
|
|
2833
|
-
|
|
2834
|
-
|
|
2835
|
-
|
|
2836
|
-
|
|
2837
|
-
|
|
2838
|
-
|
|
2839
|
-
|
|
2840
|
-
|
|
2805
|
+
const query = createQuery(() => ({
|
|
2806
|
+
queryKey: key,
|
|
2807
|
+
queryFn: async () => {
|
|
2808
|
+
if (counter < 2) {
|
|
2809
|
+
counter++;
|
|
2810
|
+
throw new Error('error');
|
|
2811
|
+
}
|
|
2812
|
+
else {
|
|
2813
|
+
return 'data';
|
|
2814
|
+
}
|
|
2815
|
+
},
|
|
2816
|
+
retryDelay: 10,
|
|
2817
|
+
}));
|
|
2841
2818
|
return (<div>
|
|
2842
2819
|
<div>failureCount {query.failureCount}</div>
|
|
2843
2820
|
<div>failureReason {query.failureReason?.message ?? 'null'}</div>
|
|
@@ -2858,18 +2835,21 @@ describe('createQuery', () => {
|
|
|
2858
2835
|
function Page() {
|
|
2859
2836
|
const [enabled, setEnabled] = createSignal(false);
|
|
2860
2837
|
const [isPrefetched, setPrefetched] = createSignal(false);
|
|
2861
|
-
const query = createQuery(
|
|
2862
|
-
|
|
2863
|
-
|
|
2864
|
-
|
|
2865
|
-
|
|
2866
|
-
|
|
2867
|
-
return enabled();
|
|
2838
|
+
const query = createQuery(() => ({
|
|
2839
|
+
queryKey: key,
|
|
2840
|
+
queryFn: async () => {
|
|
2841
|
+
count++;
|
|
2842
|
+
await sleep(10);
|
|
2843
|
+
return count;
|
|
2868
2844
|
},
|
|
2869
|
-
|
|
2845
|
+
enabled: enabled(),
|
|
2846
|
+
}));
|
|
2870
2847
|
createEffect(() => {
|
|
2871
2848
|
async function prefetch() {
|
|
2872
|
-
await queryClient.prefetchQuery(
|
|
2849
|
+
await queryClient.prefetchQuery({
|
|
2850
|
+
queryKey: key,
|
|
2851
|
+
queryFn: () => Promise.resolve('prefetched data'),
|
|
2852
|
+
});
|
|
2873
2853
|
setPrefetched(true);
|
|
2874
2854
|
}
|
|
2875
2855
|
prefetch();
|
|
@@ -2893,11 +2873,11 @@ describe('createQuery', () => {
|
|
|
2893
2873
|
const key = queryKey();
|
|
2894
2874
|
function Page() {
|
|
2895
2875
|
const [shouldFetch, setShouldFetch] = createSignal(false);
|
|
2896
|
-
const query = createQuery(
|
|
2897
|
-
|
|
2898
|
-
|
|
2899
|
-
|
|
2900
|
-
});
|
|
2876
|
+
const query = createQuery(() => ({
|
|
2877
|
+
queryKey: key,
|
|
2878
|
+
queryFn: () => 'data',
|
|
2879
|
+
enabled: shouldFetch(),
|
|
2880
|
+
}));
|
|
2901
2881
|
return (<div>
|
|
2902
2882
|
<div>FetchStatus: {query.fetchStatus}</div>
|
|
2903
2883
|
<h2>Data: {query.data || 'no data'}</h2>
|
|
@@ -2920,27 +2900,37 @@ describe('createQuery', () => {
|
|
|
2920
2900
|
const key = queryKey();
|
|
2921
2901
|
const results = [];
|
|
2922
2902
|
function Page() {
|
|
2923
|
-
const result = createQuery(
|
|
2924
|
-
|
|
2925
|
-
|
|
2903
|
+
const result = createQuery(() => ({
|
|
2904
|
+
queryKey: key,
|
|
2905
|
+
queryFn: async () => {
|
|
2906
|
+
await sleep(10);
|
|
2907
|
+
return 'serverData';
|
|
2908
|
+
},
|
|
2909
|
+
initialData: 'initialData',
|
|
2910
|
+
}));
|
|
2926
2911
|
createRenderEffect(() => {
|
|
2927
2912
|
results.push({ ...result });
|
|
2928
2913
|
});
|
|
2929
|
-
return
|
|
2914
|
+
return <div>data: {result.data}</div>;
|
|
2930
2915
|
}
|
|
2931
2916
|
render(() => (<QueryClientProvider client={queryClient}>
|
|
2932
2917
|
<Page />
|
|
2933
2918
|
</QueryClientProvider>));
|
|
2934
|
-
await
|
|
2919
|
+
await waitFor(() => screen.getByText('data: initialData'));
|
|
2920
|
+
await waitFor(() => screen.getByText('data: serverData'));
|
|
2935
2921
|
expect(results.length).toBe(2);
|
|
2936
|
-
expect(results[0]).toMatchObject({ data: '
|
|
2922
|
+
expect(results[0]).toMatchObject({ data: 'initialData', isFetching: true });
|
|
2937
2923
|
expect(results[1]).toMatchObject({ data: 'serverData', isFetching: false });
|
|
2938
2924
|
});
|
|
2939
2925
|
it('should initialize state properly, when initialData is falsy', async () => {
|
|
2940
2926
|
const key = queryKey();
|
|
2941
2927
|
const results = [];
|
|
2942
2928
|
function Page() {
|
|
2943
|
-
const result = createQuery(
|
|
2929
|
+
const result = createQuery(() => ({
|
|
2930
|
+
queryKey: key,
|
|
2931
|
+
queryFn: () => 1,
|
|
2932
|
+
initialData: 0,
|
|
2933
|
+
}));
|
|
2944
2934
|
createRenderEffect(() => {
|
|
2945
2935
|
results.push({ ...result });
|
|
2946
2936
|
});
|
|
@@ -2960,14 +2950,12 @@ describe('createQuery', () => {
|
|
|
2960
2950
|
const results = [];
|
|
2961
2951
|
function Page() {
|
|
2962
2952
|
const [shouldFetch, setShouldFetch] = createSignal(true);
|
|
2963
|
-
const result = createQuery(
|
|
2964
|
-
|
|
2965
|
-
|
|
2966
|
-
|
|
2967
|
-
|
|
2968
|
-
|
|
2969
|
-
},
|
|
2970
|
-
});
|
|
2953
|
+
const result = createQuery(() => ({
|
|
2954
|
+
queryKey: key,
|
|
2955
|
+
queryFn: () => 'fetched data',
|
|
2956
|
+
enabled: shouldFetch(),
|
|
2957
|
+
initialData: shouldFetch() ? 'initial' : 'initial falsy',
|
|
2958
|
+
}));
|
|
2971
2959
|
createRenderEffect(() => {
|
|
2972
2960
|
results.push({ ...result });
|
|
2973
2961
|
});
|
|
@@ -2992,27 +2980,29 @@ describe('createQuery', () => {
|
|
|
2992
2980
|
const queryFn = jest.fn();
|
|
2993
2981
|
queryFn.mockImplementation(() => 'data');
|
|
2994
2982
|
function Page() {
|
|
2995
|
-
const { fetchStatus } = createQuery({
|
|
2983
|
+
const { fetchStatus } = createQuery(() => ({
|
|
2996
2984
|
queryKey: key,
|
|
2997
2985
|
queryFn,
|
|
2998
2986
|
enabled: false,
|
|
2999
|
-
});
|
|
2987
|
+
}));
|
|
3000
2988
|
return <div>fetchStatus: {fetchStatus}</div>;
|
|
3001
2989
|
}
|
|
3002
2990
|
render(() => (<QueryClientProvider client={queryClient}>
|
|
3003
2991
|
<Page />
|
|
3004
2992
|
</QueryClientProvider>));
|
|
3005
2993
|
expect(queryFn).not.toHaveBeenCalled();
|
|
3006
|
-
expect(queryCache.find(key
|
|
2994
|
+
expect(queryCache.find({ queryKey: key })).not.toBeUndefined();
|
|
3007
2995
|
screen.getByText('fetchStatus: idle');
|
|
3008
2996
|
});
|
|
3009
2997
|
// See https://github.com/tannerlinsley/react-query/issues/360
|
|
3010
|
-
it('should init to status:
|
|
2998
|
+
it('should init to status:pending, fetchStatus:idle when enabled is false', async () => {
|
|
3011
2999
|
const key = queryKey();
|
|
3012
3000
|
function Page() {
|
|
3013
|
-
const query = createQuery(
|
|
3001
|
+
const query = createQuery(() => ({
|
|
3002
|
+
queryKey: key,
|
|
3003
|
+
queryFn: () => 'data',
|
|
3014
3004
|
enabled: false,
|
|
3015
|
-
});
|
|
3005
|
+
}));
|
|
3016
3006
|
return (<div>
|
|
3017
3007
|
<div>
|
|
3018
3008
|
status: {query.status}, {query.fetchStatus}
|
|
@@ -3022,38 +3012,60 @@ describe('createQuery', () => {
|
|
|
3022
3012
|
render(() => (<QueryClientProvider client={queryClient}>
|
|
3023
3013
|
<Page />
|
|
3024
3014
|
</QueryClientProvider>));
|
|
3025
|
-
await waitFor(() => screen.getByText('status:
|
|
3015
|
+
await waitFor(() => screen.getByText('status: pending, idle'));
|
|
3026
3016
|
});
|
|
3027
|
-
it('should not schedule garbage collection, if
|
|
3017
|
+
it('should not schedule garbage collection, if gcTimeout is set to `Infinity`', async () => {
|
|
3028
3018
|
const key = queryKey();
|
|
3029
3019
|
function Page() {
|
|
3030
|
-
const query = createQuery(
|
|
3031
|
-
|
|
3032
|
-
|
|
3020
|
+
const query = createQuery(() => ({
|
|
3021
|
+
queryKey: key,
|
|
3022
|
+
queryFn: () => 'fetched data',
|
|
3023
|
+
gcTime: Infinity,
|
|
3024
|
+
}));
|
|
3025
|
+
return <div>{query.data}</div>;
|
|
3026
|
+
}
|
|
3027
|
+
const result = render(() => (<QueryClientProvider client={queryClient}>
|
|
3028
|
+
<Page />
|
|
3029
|
+
</QueryClientProvider>));
|
|
3030
|
+
await waitFor(() => screen.getByText('fetched data'));
|
|
3031
|
+
const setTimeoutSpy = jest.spyOn(window, 'setTimeout');
|
|
3032
|
+
result.unmount();
|
|
3033
|
+
expect(setTimeoutSpy).not.toHaveBeenCalled();
|
|
3034
|
+
});
|
|
3035
|
+
it('should schedule garbage collection, if gcTimeout is not set to `Infinity`', async () => {
|
|
3036
|
+
const key = queryKey();
|
|
3037
|
+
function Page() {
|
|
3038
|
+
const query = createQuery(() => ({
|
|
3039
|
+
queryKey: key,
|
|
3040
|
+
queryFn: () => 'fetched data',
|
|
3041
|
+
gcTime: 1000 * 60 * 10, //10 Minutes
|
|
3042
|
+
}));
|
|
3033
3043
|
return <div>{query.data}</div>;
|
|
3034
3044
|
}
|
|
3035
3045
|
const result = render(() => (<QueryClientProvider client={queryClient}>
|
|
3036
3046
|
<Page />
|
|
3037
3047
|
</QueryClientProvider>));
|
|
3038
3048
|
await waitFor(() => screen.getByText('fetched data'));
|
|
3049
|
+
const setTimeoutSpy = jest.spyOn(window, 'setTimeout');
|
|
3039
3050
|
result.unmount();
|
|
3040
|
-
|
|
3041
|
-
// @ts-expect-error
|
|
3042
|
-
expect(query.cacheTimeout).toBe(undefined);
|
|
3051
|
+
expect(setTimeoutSpy).toHaveBeenLastCalledWith(expect.any(Function), 1000 * 60 * 10);
|
|
3043
3052
|
});
|
|
3044
3053
|
it('should not cause memo churn when data does not change', async () => {
|
|
3045
3054
|
const key = queryKey();
|
|
3046
3055
|
const queryFn = jest.fn().mockReturnValue('data');
|
|
3047
3056
|
const memoFn = jest.fn();
|
|
3048
3057
|
function Page() {
|
|
3049
|
-
const result = createQuery(
|
|
3050
|
-
|
|
3051
|
-
|
|
3052
|
-
|
|
3053
|
-
|
|
3054
|
-
|
|
3055
|
-
|
|
3056
|
-
|
|
3058
|
+
const result = createQuery(() => ({
|
|
3059
|
+
queryKey: key,
|
|
3060
|
+
queryFn: async () => {
|
|
3061
|
+
await sleep(10);
|
|
3062
|
+
return (queryFn() || {
|
|
3063
|
+
data: {
|
|
3064
|
+
nested: true,
|
|
3065
|
+
},
|
|
3066
|
+
});
|
|
3067
|
+
},
|
|
3068
|
+
}));
|
|
3057
3069
|
createMemo(() => {
|
|
3058
3070
|
memoFn();
|
|
3059
3071
|
return result.data;
|
|
@@ -3067,7 +3079,7 @@ describe('createQuery', () => {
|
|
|
3067
3079
|
render(() => (<QueryClientProvider client={queryClient}>
|
|
3068
3080
|
<Page />
|
|
3069
3081
|
</QueryClientProvider>));
|
|
3070
|
-
await waitFor(() => screen.getByText('status
|
|
3082
|
+
await waitFor(() => screen.getByText('status pending'));
|
|
3071
3083
|
await waitFor(() => screen.getByText('status success'));
|
|
3072
3084
|
fireEvent.click(screen.getByText('refetch'));
|
|
3073
3085
|
await waitFor(() => screen.getByText('isFetching true'));
|
|
@@ -3080,11 +3092,11 @@ describe('createQuery', () => {
|
|
|
3080
3092
|
let count = 0;
|
|
3081
3093
|
function Page() {
|
|
3082
3094
|
const [int, setInt] = createSignal(200);
|
|
3083
|
-
const state = createQuery(
|
|
3084
|
-
|
|
3085
|
-
|
|
3086
|
-
|
|
3087
|
-
});
|
|
3095
|
+
const state = createQuery(() => ({
|
|
3096
|
+
queryKey: key,
|
|
3097
|
+
queryFn: () => count++,
|
|
3098
|
+
refetchInterval: int(),
|
|
3099
|
+
}));
|
|
3088
3100
|
createEffect(() => {
|
|
3089
3101
|
if (state.data === 2) {
|
|
3090
3102
|
setInt(0);
|
|
@@ -3105,12 +3117,14 @@ describe('createQuery', () => {
|
|
|
3105
3117
|
let count = 0;
|
|
3106
3118
|
const states = [];
|
|
3107
3119
|
function Page() {
|
|
3108
|
-
const state = createQuery(
|
|
3109
|
-
|
|
3110
|
-
|
|
3111
|
-
|
|
3120
|
+
const state = createQuery(() => ({
|
|
3121
|
+
queryKey: key,
|
|
3122
|
+
queryFn: async () => {
|
|
3123
|
+
await sleep(10);
|
|
3124
|
+
return count++;
|
|
3125
|
+
},
|
|
3112
3126
|
refetchInterval: (data = 0) => (data < 2 ? 10 : false),
|
|
3113
|
-
});
|
|
3127
|
+
}));
|
|
3114
3128
|
createRenderEffect(() => {
|
|
3115
3129
|
states.push({ ...state });
|
|
3116
3130
|
});
|
|
@@ -3128,7 +3142,7 @@ describe('createQuery', () => {
|
|
|
3128
3142
|
expect(states.length).toEqual(6);
|
|
3129
3143
|
expect(states).toMatchObject([
|
|
3130
3144
|
{
|
|
3131
|
-
status: '
|
|
3145
|
+
status: 'pending',
|
|
3132
3146
|
isFetching: true,
|
|
3133
3147
|
data: undefined,
|
|
3134
3148
|
},
|
|
@@ -3163,9 +3177,11 @@ describe('createQuery', () => {
|
|
|
3163
3177
|
const key = queryKey();
|
|
3164
3178
|
const states = [];
|
|
3165
3179
|
function Page() {
|
|
3166
|
-
const state = createQuery(
|
|
3180
|
+
const state = createQuery(() => ({
|
|
3181
|
+
queryKey: key,
|
|
3182
|
+
queryFn: () => 1,
|
|
3167
3183
|
refetchInterval: 0,
|
|
3168
|
-
});
|
|
3184
|
+
}));
|
|
3169
3185
|
createRenderEffect(() => {
|
|
3170
3186
|
states.push({ ...state });
|
|
3171
3187
|
});
|
|
@@ -3179,7 +3195,7 @@ describe('createQuery', () => {
|
|
|
3179
3195
|
expect(states.length).toEqual(2);
|
|
3180
3196
|
expect(states).toMatchObject([
|
|
3181
3197
|
{
|
|
3182
|
-
status: '
|
|
3198
|
+
status: 'pending',
|
|
3183
3199
|
isFetching: true,
|
|
3184
3200
|
data: undefined,
|
|
3185
3201
|
},
|
|
@@ -3192,7 +3208,10 @@ describe('createQuery', () => {
|
|
|
3192
3208
|
});
|
|
3193
3209
|
it('should accept an empty string as query key', async () => {
|
|
3194
3210
|
function Page() {
|
|
3195
|
-
const result = createQuery(() =>
|
|
3211
|
+
const result = createQuery(() => ({
|
|
3212
|
+
queryKey: [''],
|
|
3213
|
+
queryFn: (ctx) => ctx.queryKey,
|
|
3214
|
+
}));
|
|
3196
3215
|
return <>{JSON.stringify(result.data)}</>;
|
|
3197
3216
|
}
|
|
3198
3217
|
render(() => (<QueryClientProvider client={queryClient}>
|
|
@@ -3202,7 +3221,10 @@ describe('createQuery', () => {
|
|
|
3202
3221
|
});
|
|
3203
3222
|
it('should accept an object as query key', async () => {
|
|
3204
3223
|
function Page() {
|
|
3205
|
-
const result = createQuery(() =>
|
|
3224
|
+
const result = createQuery(() => ({
|
|
3225
|
+
queryKey: [{ a: 'a' }],
|
|
3226
|
+
queryFn: (ctx) => ctx.queryKey,
|
|
3227
|
+
}));
|
|
3206
3228
|
return <>{JSON.stringify(result.data)}</>;
|
|
3207
3229
|
}
|
|
3208
3230
|
render(() => (<QueryClientProvider client={queryClient}>
|
|
@@ -3214,16 +3236,16 @@ describe('createQuery', () => {
|
|
|
3214
3236
|
const key = queryKey();
|
|
3215
3237
|
const queryFn = jest.fn().mockReturnValue('data');
|
|
3216
3238
|
function Disabled() {
|
|
3217
|
-
createQuery(key, queryFn,
|
|
3239
|
+
createQuery(() => ({ queryKey: key, queryFn, enabled: false }));
|
|
3218
3240
|
return null;
|
|
3219
3241
|
}
|
|
3220
3242
|
function Page() {
|
|
3221
3243
|
const [enabled, setEnabled] = createSignal(false);
|
|
3222
|
-
const result = createQuery(
|
|
3223
|
-
|
|
3224
|
-
|
|
3225
|
-
|
|
3226
|
-
});
|
|
3244
|
+
const result = createQuery(() => ({
|
|
3245
|
+
queryKey: key,
|
|
3246
|
+
queryFn,
|
|
3247
|
+
enabled: enabled(),
|
|
3248
|
+
}));
|
|
3227
3249
|
return (<>
|
|
3228
3250
|
<Disabled />
|
|
3229
3251
|
<div>{result.data}</div>
|
|
@@ -3242,9 +3264,11 @@ describe('createQuery', () => {
|
|
|
3242
3264
|
const key1 = queryKey();
|
|
3243
3265
|
const states = [];
|
|
3244
3266
|
function Page() {
|
|
3245
|
-
const state = createQuery(
|
|
3267
|
+
const state = createQuery(() => ({
|
|
3268
|
+
queryKey: key1,
|
|
3269
|
+
queryFn: () => 'data',
|
|
3246
3270
|
placeholderData: 'placeholder',
|
|
3247
|
-
});
|
|
3271
|
+
}));
|
|
3248
3272
|
createRenderEffect(() => {
|
|
3249
3273
|
states.push({ ...state });
|
|
3250
3274
|
});
|
|
@@ -3275,12 +3299,12 @@ describe('createQuery', () => {
|
|
|
3275
3299
|
const states = [];
|
|
3276
3300
|
function Page() {
|
|
3277
3301
|
const [count, setCount] = createSignal(0);
|
|
3278
|
-
const state = createQuery(
|
|
3302
|
+
const state = createQuery(() => ({
|
|
3303
|
+
queryKey: key1,
|
|
3304
|
+
queryFn: () => 'data',
|
|
3279
3305
|
placeholderData: 'placeholder',
|
|
3280
|
-
|
|
3281
|
-
|
|
3282
|
-
},
|
|
3283
|
-
});
|
|
3306
|
+
enabled: count() === 0,
|
|
3307
|
+
}));
|
|
3284
3308
|
createRenderEffect(() => {
|
|
3285
3309
|
states.push({ state: { ...state }, count: count() });
|
|
3286
3310
|
});
|
|
@@ -3327,10 +3351,12 @@ describe('createQuery', () => {
|
|
|
3327
3351
|
const key1 = queryKey();
|
|
3328
3352
|
const states = [];
|
|
3329
3353
|
function Page() {
|
|
3330
|
-
const state = createQuery(
|
|
3354
|
+
const state = createQuery(() => ({
|
|
3355
|
+
queryKey: key1,
|
|
3356
|
+
queryFn: () => 1,
|
|
3331
3357
|
placeholderData: 23,
|
|
3332
3358
|
select: (data) => String(data * 2),
|
|
3333
|
-
});
|
|
3359
|
+
}));
|
|
3334
3360
|
createRenderEffect(() => {
|
|
3335
3361
|
states.push({ ...state });
|
|
3336
3362
|
});
|
|
@@ -3361,13 +3387,15 @@ describe('createQuery', () => {
|
|
|
3361
3387
|
const states = [];
|
|
3362
3388
|
let placeholderFunctionRunCount = 0;
|
|
3363
3389
|
function Page() {
|
|
3364
|
-
const state = createQuery(
|
|
3390
|
+
const state = createQuery(() => ({
|
|
3391
|
+
queryKey: key1,
|
|
3392
|
+
queryFn: () => 1,
|
|
3365
3393
|
placeholderData: () => {
|
|
3366
3394
|
placeholderFunctionRunCount++;
|
|
3367
3395
|
return 23;
|
|
3368
3396
|
},
|
|
3369
3397
|
select: (data) => String(data * 2),
|
|
3370
|
-
});
|
|
3398
|
+
}));
|
|
3371
3399
|
createRenderEffect(() => {
|
|
3372
3400
|
states.push({ ...state });
|
|
3373
3401
|
});
|
|
@@ -3394,40 +3422,6 @@ describe('createQuery', () => {
|
|
|
3394
3422
|
]);
|
|
3395
3423
|
expect(placeholderFunctionRunCount).toEqual(1);
|
|
3396
3424
|
});
|
|
3397
|
-
// React Specific implementation. Not really needed since solid functions are stable
|
|
3398
|
-
it.skip('select should only run when dependencies change if memoized', async () => {
|
|
3399
|
-
const key1 = queryKey();
|
|
3400
|
-
let selectRun = 0;
|
|
3401
|
-
function Page() {
|
|
3402
|
-
//@ts-expect-error skip this test
|
|
3403
|
-
const [count, inc] = NotReact.useReducer((prev) => prev + 1, 2);
|
|
3404
|
-
const state = createQuery(key1, async () => {
|
|
3405
|
-
await sleep(10);
|
|
3406
|
-
return 0;
|
|
3407
|
-
}, {
|
|
3408
|
-
//@ts-expect-error skip this test
|
|
3409
|
-
select: NotReact.useCallback((data) => {
|
|
3410
|
-
selectRun++;
|
|
3411
|
-
return `selected ${data + count}`;
|
|
3412
|
-
}, [count]),
|
|
3413
|
-
placeholderData: 99,
|
|
3414
|
-
});
|
|
3415
|
-
return (<div>
|
|
3416
|
-
<h2>Data: {state.data}</h2>
|
|
3417
|
-
<button onClick={inc}>inc: {count}</button>
|
|
3418
|
-
</div>);
|
|
3419
|
-
}
|
|
3420
|
-
render(() => (<QueryClientProvider client={queryClient}>
|
|
3421
|
-
<Page />
|
|
3422
|
-
</QueryClientProvider>));
|
|
3423
|
-
await waitFor(() => screen.getByText('Data: selected 101')); // 99 + 2
|
|
3424
|
-
expect(selectRun).toBe(1);
|
|
3425
|
-
await waitFor(() => screen.getByText('Data: selected 2')); // 0 + 2
|
|
3426
|
-
expect(selectRun).toBe(2);
|
|
3427
|
-
fireEvent.click(screen.getByRole('button', { name: /inc/i }));
|
|
3428
|
-
await waitFor(() => screen.getByText('Data: selected 3')); // 0 + 3
|
|
3429
|
-
expect(selectRun).toBe(3);
|
|
3430
|
-
});
|
|
3431
3425
|
it('select should always return the correct state', async () => {
|
|
3432
3426
|
const key1 = queryKey();
|
|
3433
3427
|
function Page() {
|
|
@@ -3439,16 +3433,18 @@ describe('createQuery', () => {
|
|
|
3439
3433
|
const forceUpdate = () => {
|
|
3440
3434
|
setForceValue((prev) => prev + 1);
|
|
3441
3435
|
};
|
|
3442
|
-
const state = createQuery(
|
|
3443
|
-
|
|
3444
|
-
|
|
3445
|
-
|
|
3436
|
+
const state = createQuery(() => ({
|
|
3437
|
+
queryKey: key1,
|
|
3438
|
+
queryFn: async () => {
|
|
3439
|
+
await sleep(10);
|
|
3440
|
+
return 0;
|
|
3441
|
+
},
|
|
3446
3442
|
get select() {
|
|
3447
3443
|
const currentCount = count();
|
|
3448
3444
|
return (data) => `selected ${data + currentCount}`;
|
|
3449
3445
|
},
|
|
3450
3446
|
placeholderData: 99,
|
|
3451
|
-
});
|
|
3447
|
+
}));
|
|
3452
3448
|
return (<div>
|
|
3453
3449
|
<h2>Data: {state.data}</h2>
|
|
3454
3450
|
<h2>forceValue: {forceValue()}</h2>
|
|
@@ -3473,12 +3469,14 @@ describe('createQuery', () => {
|
|
|
3473
3469
|
const states = [];
|
|
3474
3470
|
function Page() {
|
|
3475
3471
|
const [forceValue, setForceValue] = createSignal(1);
|
|
3476
|
-
const state = createQuery(
|
|
3477
|
-
|
|
3478
|
-
|
|
3479
|
-
|
|
3472
|
+
const state = createQuery(() => ({
|
|
3473
|
+
queryKey: key1,
|
|
3474
|
+
queryFn: async () => {
|
|
3475
|
+
await sleep(10);
|
|
3476
|
+
return [1, 2];
|
|
3477
|
+
},
|
|
3480
3478
|
select: (res) => res.map((x) => x + 1),
|
|
3481
|
-
});
|
|
3479
|
+
}));
|
|
3482
3480
|
createEffect(() => {
|
|
3483
3481
|
if (state.data) {
|
|
3484
3482
|
states.push(state.data);
|
|
@@ -3516,7 +3514,7 @@ describe('createQuery', () => {
|
|
|
3516
3514
|
return promise;
|
|
3517
3515
|
};
|
|
3518
3516
|
function Page() {
|
|
3519
|
-
const state = createQuery(key, queryFn);
|
|
3517
|
+
const state = createQuery(() => ({ queryKey: key, queryFn }));
|
|
3520
3518
|
return (<div>
|
|
3521
3519
|
<h1>Status: {state.status}</h1>
|
|
3522
3520
|
</div>);
|
|
@@ -3534,12 +3532,16 @@ describe('createQuery', () => {
|
|
|
3534
3532
|
const states = [];
|
|
3535
3533
|
const queryFn = async (ctx) => {
|
|
3536
3534
|
const [, limit] = ctx.queryKey;
|
|
3535
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
3537
3536
|
const value = limit % 2 && ctx.signal ? 'abort' : `data ${limit}`;
|
|
3538
3537
|
await sleep(25);
|
|
3539
3538
|
return value;
|
|
3540
3539
|
};
|
|
3541
3540
|
function Page(props) {
|
|
3542
|
-
const state = createQuery(() =>
|
|
3541
|
+
const state = createQuery(() => ({
|
|
3542
|
+
queryKey: [key, props.limit],
|
|
3543
|
+
queryFn,
|
|
3544
|
+
}));
|
|
3543
3545
|
states[props.limit] = state;
|
|
3544
3546
|
return (<div>
|
|
3545
3547
|
<h1>Status: {state.status}</h1>
|
|
@@ -3557,24 +3559,24 @@ describe('createQuery', () => {
|
|
|
3557
3559
|
await waitFor(() => screen.getByText('off'));
|
|
3558
3560
|
await sleep(20);
|
|
3559
3561
|
await waitFor(() => expect(states).toHaveLength(4));
|
|
3560
|
-
expect(queryCache.find([key
|
|
3562
|
+
expect(queryCache.find({ queryKey: [key, 0] })?.state).toMatchObject({
|
|
3561
3563
|
data: 'data 0',
|
|
3562
3564
|
status: 'success',
|
|
3563
3565
|
dataUpdateCount: 1,
|
|
3564
3566
|
});
|
|
3565
|
-
expect(queryCache.find([key
|
|
3567
|
+
expect(queryCache.find({ queryKey: [key, 1] })?.state).toMatchObject({
|
|
3566
3568
|
data: undefined,
|
|
3567
|
-
status: '
|
|
3569
|
+
status: 'pending',
|
|
3568
3570
|
fetchStatus: 'idle',
|
|
3569
3571
|
});
|
|
3570
|
-
expect(queryCache.find([key
|
|
3572
|
+
expect(queryCache.find({ queryKey: [key, 2] })?.state).toMatchObject({
|
|
3571
3573
|
data: 'data 2',
|
|
3572
3574
|
status: 'success',
|
|
3573
3575
|
dataUpdateCount: 1,
|
|
3574
3576
|
});
|
|
3575
|
-
expect(queryCache.find([key
|
|
3577
|
+
expect(queryCache.find({ queryKey: [key, 3] })?.state).toMatchObject({
|
|
3576
3578
|
data: undefined,
|
|
3577
|
-
status: '
|
|
3579
|
+
status: 'pending',
|
|
3578
3580
|
fetchStatus: 'idle',
|
|
3579
3581
|
});
|
|
3580
3582
|
});
|
|
@@ -3588,7 +3590,7 @@ describe('createQuery', () => {
|
|
|
3588
3590
|
function Page() {
|
|
3589
3591
|
const [id, setId] = createSignal(1);
|
|
3590
3592
|
const [hasChanged, setHasChanged] = createSignal(false);
|
|
3591
|
-
const state = createQuery(() => [key
|
|
3593
|
+
const state = createQuery(() => ({ queryKey: [key, id()], queryFn }));
|
|
3592
3594
|
createRenderEffect(() => {
|
|
3593
3595
|
states.push({ ...state });
|
|
3594
3596
|
});
|
|
@@ -3605,7 +3607,7 @@ describe('createQuery', () => {
|
|
|
3605
3607
|
expect(states.length).toBe(2);
|
|
3606
3608
|
// Load query 1
|
|
3607
3609
|
expect(states[0]).toMatchObject({
|
|
3608
|
-
status: '
|
|
3610
|
+
status: 'pending',
|
|
3609
3611
|
error: null,
|
|
3610
3612
|
});
|
|
3611
3613
|
// No rerenders - No state updates
|
|
@@ -3620,16 +3622,22 @@ describe('createQuery', () => {
|
|
|
3620
3622
|
const states = [];
|
|
3621
3623
|
let count = 0;
|
|
3622
3624
|
function Page() {
|
|
3623
|
-
const state = createQuery(
|
|
3624
|
-
|
|
3625
|
-
|
|
3626
|
-
|
|
3627
|
-
|
|
3625
|
+
const state = createQuery(() => ({
|
|
3626
|
+
queryKey: key,
|
|
3627
|
+
queryFn: async () => {
|
|
3628
|
+
await sleep(10);
|
|
3629
|
+
count++;
|
|
3630
|
+
return count;
|
|
3631
|
+
},
|
|
3632
|
+
staleTime: Infinity,
|
|
3633
|
+
}));
|
|
3628
3634
|
createRenderEffect(() => {
|
|
3629
3635
|
states.push({ ...state });
|
|
3630
3636
|
});
|
|
3631
3637
|
return (<div>
|
|
3632
|
-
<button onClick={() => queryClient.resetQueries(key
|
|
3638
|
+
<button onClick={() => queryClient.resetQueries({ queryKey: key })}>
|
|
3639
|
+
reset
|
|
3640
|
+
</button>
|
|
3633
3641
|
<div>data: {state.data ?? 'null'}</div>
|
|
3634
3642
|
<div>isFetching: {state.isFetching}</div>
|
|
3635
3643
|
</div>);
|
|
@@ -3643,29 +3651,27 @@ describe('createQuery', () => {
|
|
|
3643
3651
|
await waitFor(() => screen.getByText('data: 2'));
|
|
3644
3652
|
expect(count).toBe(2);
|
|
3645
3653
|
expect(states[0]).toMatchObject({
|
|
3646
|
-
|
|
3647
|
-
isLoading: true,
|
|
3654
|
+
isPending: true,
|
|
3648
3655
|
isFetching: true,
|
|
3649
3656
|
isSuccess: false,
|
|
3650
3657
|
isStale: true,
|
|
3651
3658
|
});
|
|
3652
3659
|
expect(states[1]).toMatchObject({
|
|
3653
3660
|
data: 1,
|
|
3654
|
-
|
|
3661
|
+
isPending: false,
|
|
3655
3662
|
isFetching: false,
|
|
3656
3663
|
isSuccess: true,
|
|
3657
3664
|
isStale: false,
|
|
3658
3665
|
});
|
|
3659
3666
|
expect(states[2]).toMatchObject({
|
|
3660
|
-
|
|
3661
|
-
isLoading: true,
|
|
3667
|
+
isPending: true,
|
|
3662
3668
|
isFetching: true,
|
|
3663
3669
|
isSuccess: false,
|
|
3664
3670
|
isStale: true,
|
|
3665
3671
|
});
|
|
3666
3672
|
expect(states[3]).toMatchObject({
|
|
3667
3673
|
data: 2,
|
|
3668
|
-
|
|
3674
|
+
isPending: false,
|
|
3669
3675
|
isFetching: false,
|
|
3670
3676
|
isSuccess: true,
|
|
3671
3677
|
isStale: false,
|
|
@@ -3676,18 +3682,26 @@ describe('createQuery', () => {
|
|
|
3676
3682
|
const states = [];
|
|
3677
3683
|
let count = 0;
|
|
3678
3684
|
function Page() {
|
|
3679
|
-
const state = createQuery(
|
|
3680
|
-
|
|
3681
|
-
|
|
3682
|
-
|
|
3683
|
-
|
|
3685
|
+
const state = createQuery(() => ({
|
|
3686
|
+
queryKey: key,
|
|
3687
|
+
queryFn: async () => {
|
|
3688
|
+
await sleep(10);
|
|
3689
|
+
count++;
|
|
3690
|
+
return count;
|
|
3691
|
+
},
|
|
3692
|
+
staleTime: Infinity,
|
|
3693
|
+
enabled: false,
|
|
3694
|
+
notifyOnChangeProps: 'all',
|
|
3695
|
+
}));
|
|
3684
3696
|
createRenderEffect(() => {
|
|
3685
3697
|
states.push({ ...state });
|
|
3686
3698
|
});
|
|
3687
3699
|
const { refetch } = state;
|
|
3688
3700
|
return (<div>
|
|
3689
3701
|
<button onClick={() => refetch()}>refetch</button>
|
|
3690
|
-
<button onClick={() => queryClient.resetQueries(key
|
|
3702
|
+
<button onClick={() => queryClient.resetQueries({ queryKey: key })}>
|
|
3703
|
+
reset
|
|
3704
|
+
</button>
|
|
3691
3705
|
<div>data: {state.data ?? 'null'}</div>
|
|
3692
3706
|
</div>);
|
|
3693
3707
|
}
|
|
@@ -3702,29 +3716,26 @@ describe('createQuery', () => {
|
|
|
3702
3716
|
await waitFor(() => expect(states.length).toBe(4));
|
|
3703
3717
|
expect(count).toBe(1);
|
|
3704
3718
|
expect(states[0]).toMatchObject({
|
|
3705
|
-
|
|
3706
|
-
isLoading: true,
|
|
3719
|
+
isPending: true,
|
|
3707
3720
|
isFetching: false,
|
|
3708
3721
|
isSuccess: false,
|
|
3709
3722
|
isStale: true,
|
|
3710
3723
|
});
|
|
3711
3724
|
expect(states[1]).toMatchObject({
|
|
3712
|
-
|
|
3713
|
-
isLoading: true,
|
|
3725
|
+
isPending: true,
|
|
3714
3726
|
isFetching: true,
|
|
3715
3727
|
isSuccess: false,
|
|
3716
3728
|
isStale: true,
|
|
3717
3729
|
});
|
|
3718
3730
|
expect(states[2]).toMatchObject({
|
|
3719
3731
|
data: 1,
|
|
3720
|
-
|
|
3732
|
+
isPending: false,
|
|
3721
3733
|
isFetching: false,
|
|
3722
3734
|
isSuccess: true,
|
|
3723
3735
|
isStale: false,
|
|
3724
3736
|
});
|
|
3725
3737
|
expect(states[3]).toMatchObject({
|
|
3726
|
-
|
|
3727
|
-
isLoading: true,
|
|
3738
|
+
isPending: true,
|
|
3728
3739
|
isFetching: false,
|
|
3729
3740
|
isSuccess: false,
|
|
3730
3741
|
isStale: true,
|
|
@@ -3739,7 +3750,11 @@ describe('createQuery', () => {
|
|
|
3739
3750
|
return JSON.stringify(x);
|
|
3740
3751
|
}
|
|
3741
3752
|
function Page() {
|
|
3742
|
-
const state = createQuery(
|
|
3753
|
+
const state = createQuery(() => ({
|
|
3754
|
+
queryKey: key,
|
|
3755
|
+
queryFn: () => 'test',
|
|
3756
|
+
queryKeyHashFn,
|
|
3757
|
+
}));
|
|
3743
3758
|
createEffect(on(() => state.status, () => {
|
|
3744
3759
|
renders++;
|
|
3745
3760
|
}));
|
|
@@ -3758,18 +3773,18 @@ describe('createQuery', () => {
|
|
|
3758
3773
|
return Promise.reject(new Error('Suspense Error Bingo'));
|
|
3759
3774
|
});
|
|
3760
3775
|
function Page(props) {
|
|
3761
|
-
const state = createQuery(() =>
|
|
3762
|
-
|
|
3763
|
-
|
|
3764
|
-
|
|
3776
|
+
const state = createQuery(() => ({
|
|
3777
|
+
queryKey: ['key'],
|
|
3778
|
+
queryFn,
|
|
3779
|
+
enabled: props.enabled,
|
|
3765
3780
|
retry: false,
|
|
3766
3781
|
retryOnMount: false,
|
|
3767
3782
|
refetchOnMount: false,
|
|
3768
3783
|
refetchOnWindowFocus: false,
|
|
3769
|
-
});
|
|
3784
|
+
}));
|
|
3770
3785
|
return (<Switch fallback={<div>rendered</div>}>
|
|
3771
|
-
<Match when={state.
|
|
3772
|
-
<div>status:
|
|
3786
|
+
<Match when={state.isPending}>
|
|
3787
|
+
<div>status: pending</div>
|
|
3773
3788
|
</Match>
|
|
3774
3789
|
<Match when={state.error instanceof Error}>
|
|
3775
3790
|
<div>error</div>
|
|
@@ -3790,7 +3805,7 @@ describe('createQuery', () => {
|
|
|
3790
3805
|
<App />
|
|
3791
3806
|
</QueryClientProvider>));
|
|
3792
3807
|
// initial state check
|
|
3793
|
-
screen.getByText('status:
|
|
3808
|
+
screen.getByText('status: pending');
|
|
3794
3809
|
// // render error state component
|
|
3795
3810
|
await waitFor(() => screen.getByText('error'));
|
|
3796
3811
|
expect(queryFn).toBeCalledTimes(1);
|
|
@@ -3804,23 +3819,25 @@ describe('createQuery', () => {
|
|
|
3804
3819
|
});
|
|
3805
3820
|
it('should refetch when query key changed when previous status is error', async () => {
|
|
3806
3821
|
function Page(props) {
|
|
3807
|
-
const state = createQuery(() =>
|
|
3808
|
-
|
|
3809
|
-
|
|
3810
|
-
|
|
3811
|
-
|
|
3812
|
-
|
|
3813
|
-
|
|
3814
|
-
|
|
3815
|
-
|
|
3822
|
+
const state = createQuery(() => ({
|
|
3823
|
+
queryKey: [props.id],
|
|
3824
|
+
queryFn: async () => {
|
|
3825
|
+
await sleep(10);
|
|
3826
|
+
if (props.id % 2 === 1) {
|
|
3827
|
+
return Promise.reject(new Error('Error'));
|
|
3828
|
+
}
|
|
3829
|
+
else {
|
|
3830
|
+
return 'data';
|
|
3831
|
+
}
|
|
3832
|
+
},
|
|
3816
3833
|
retry: false,
|
|
3817
3834
|
retryOnMount: false,
|
|
3818
3835
|
refetchOnMount: false,
|
|
3819
3836
|
refetchOnWindowFocus: false,
|
|
3820
|
-
});
|
|
3837
|
+
}));
|
|
3821
3838
|
return (<Switch fallback={<div>rendered</div>}>
|
|
3822
|
-
<Match when={state.
|
|
3823
|
-
<div>status:
|
|
3839
|
+
<Match when={state.isPending}>
|
|
3840
|
+
<div>status: pending</div>
|
|
3824
3841
|
</Match>
|
|
3825
3842
|
<Match when={state.error instanceof Error}>
|
|
3826
3843
|
<div>error</div>
|
|
@@ -3841,7 +3858,7 @@ describe('createQuery', () => {
|
|
|
3841
3858
|
<App />
|
|
3842
3859
|
</QueryClientProvider>));
|
|
3843
3860
|
// initial state check
|
|
3844
|
-
screen.getByText('status:
|
|
3861
|
+
screen.getByText('status: pending');
|
|
3845
3862
|
// render error state component
|
|
3846
3863
|
await waitFor(() => screen.getByText('error'));
|
|
3847
3864
|
// change to unmount query
|
|
@@ -3853,15 +3870,17 @@ describe('createQuery', () => {
|
|
|
3853
3870
|
});
|
|
3854
3871
|
it('should refetch when query key changed when switching between erroneous queries', async () => {
|
|
3855
3872
|
function Page(props) {
|
|
3856
|
-
const state = createQuery(() =>
|
|
3857
|
-
|
|
3858
|
-
|
|
3859
|
-
|
|
3873
|
+
const state = createQuery(() => ({
|
|
3874
|
+
queryKey: [props.id],
|
|
3875
|
+
queryFn: async () => {
|
|
3876
|
+
await sleep(10);
|
|
3877
|
+
return Promise.reject(new Error('Error'));
|
|
3878
|
+
},
|
|
3860
3879
|
retry: false,
|
|
3861
3880
|
retryOnMount: false,
|
|
3862
3881
|
refetchOnMount: false,
|
|
3863
3882
|
refetchOnWindowFocus: false,
|
|
3864
|
-
});
|
|
3883
|
+
}));
|
|
3865
3884
|
return (<Switch fallback={<div>rendered</div>}>
|
|
3866
3885
|
<Match when={state.isFetching}>
|
|
3867
3886
|
<div>status: fetching</div>
|
|
@@ -3897,28 +3916,30 @@ describe('createQuery', () => {
|
|
|
3897
3916
|
await waitFor(() => screen.getByText('status: fetching'));
|
|
3898
3917
|
await waitFor(() => screen.getByText('error'));
|
|
3899
3918
|
});
|
|
3900
|
-
it('should have no error in
|
|
3919
|
+
it('should have no error in pending state when refetching after error occurred', async () => {
|
|
3901
3920
|
const key = queryKey();
|
|
3902
3921
|
const states = [];
|
|
3903
3922
|
const error = new Error('oops');
|
|
3904
3923
|
let count = 0;
|
|
3905
3924
|
function Page() {
|
|
3906
|
-
const state = createQuery(
|
|
3907
|
-
|
|
3908
|
-
|
|
3909
|
-
|
|
3910
|
-
|
|
3911
|
-
|
|
3912
|
-
|
|
3913
|
-
|
|
3925
|
+
const state = createQuery(() => ({
|
|
3926
|
+
queryKey: key,
|
|
3927
|
+
queryFn: async () => {
|
|
3928
|
+
await sleep(10);
|
|
3929
|
+
if (count === 0) {
|
|
3930
|
+
count++;
|
|
3931
|
+
throw error;
|
|
3932
|
+
}
|
|
3933
|
+
return 5;
|
|
3934
|
+
},
|
|
3914
3935
|
retry: false,
|
|
3915
|
-
});
|
|
3936
|
+
}));
|
|
3916
3937
|
createRenderEffect(() => {
|
|
3917
3938
|
states.push({ ...state });
|
|
3918
3939
|
});
|
|
3919
3940
|
return (<Switch fallback={<div>data: {state.data}</div>}>
|
|
3920
|
-
<Match when={state.
|
|
3921
|
-
<div>status:
|
|
3941
|
+
<Match when={state.isPending}>
|
|
3942
|
+
<div>status: pending</div>
|
|
3922
3943
|
</Match>
|
|
3923
3944
|
<Match when={state.error instanceof Error}>
|
|
3924
3945
|
<div>
|
|
@@ -3936,7 +3957,7 @@ describe('createQuery', () => {
|
|
|
3936
3957
|
await waitFor(() => screen.getByText('data: 5'));
|
|
3937
3958
|
await waitFor(() => expect(states.length).toBe(4));
|
|
3938
3959
|
expect(states[0]).toMatchObject({
|
|
3939
|
-
status: '
|
|
3960
|
+
status: 'pending',
|
|
3940
3961
|
data: undefined,
|
|
3941
3962
|
error: null,
|
|
3942
3963
|
});
|
|
@@ -3946,7 +3967,7 @@ describe('createQuery', () => {
|
|
|
3946
3967
|
error,
|
|
3947
3968
|
});
|
|
3948
3969
|
expect(states[2]).toMatchObject({
|
|
3949
|
-
status: '
|
|
3970
|
+
status: 'pending',
|
|
3950
3971
|
data: undefined,
|
|
3951
3972
|
error: null,
|
|
3952
3973
|
});
|
|
@@ -3962,13 +3983,13 @@ describe('createQuery', () => {
|
|
|
3962
3983
|
const key = queryKey();
|
|
3963
3984
|
const states = [];
|
|
3964
3985
|
function Page() {
|
|
3965
|
-
const state = createQuery({
|
|
3986
|
+
const state = createQuery(() => ({
|
|
3966
3987
|
queryKey: key,
|
|
3967
3988
|
queryFn: async () => {
|
|
3968
3989
|
await sleep(10);
|
|
3969
3990
|
return 'data';
|
|
3970
3991
|
},
|
|
3971
|
-
});
|
|
3992
|
+
}));
|
|
3972
3993
|
createEffect(() => {
|
|
3973
3994
|
states.push(state.fetchStatus);
|
|
3974
3995
|
});
|
|
@@ -3982,7 +4003,7 @@ describe('createQuery', () => {
|
|
|
3982
4003
|
render(() => (<QueryClientProvider client={queryClient}>
|
|
3983
4004
|
<Page />
|
|
3984
4005
|
</QueryClientProvider>));
|
|
3985
|
-
await waitFor(() => screen.getByText('status:
|
|
4006
|
+
await waitFor(() => screen.getByText('status: pending, isPaused: true'));
|
|
3986
4007
|
onlineMock.mockReturnValue(true);
|
|
3987
4008
|
window.dispatchEvent(new Event('online'));
|
|
3988
4009
|
await waitFor(() => screen.getByText('status: success, isPaused: false'));
|
|
@@ -3996,14 +4017,14 @@ describe('createQuery', () => {
|
|
|
3996
4017
|
const key = queryKey();
|
|
3997
4018
|
let count = 0;
|
|
3998
4019
|
function Page() {
|
|
3999
|
-
const state = createQuery({
|
|
4020
|
+
const state = createQuery(() => ({
|
|
4000
4021
|
queryKey: key,
|
|
4001
4022
|
queryFn: async () => {
|
|
4002
4023
|
count++;
|
|
4003
4024
|
await sleep(10);
|
|
4004
4025
|
return 'data' + count;
|
|
4005
4026
|
},
|
|
4006
|
-
});
|
|
4027
|
+
}));
|
|
4007
4028
|
return (<div>
|
|
4008
4029
|
<div>
|
|
4009
4030
|
status: {state.status}, fetchStatus: {state.fetchStatus},
|
|
@@ -4011,7 +4032,7 @@ describe('createQuery', () => {
|
|
|
4011
4032
|
</div>
|
|
4012
4033
|
<div>failureReason: {state.failureReason ?? 'null'}</div>
|
|
4013
4034
|
<div>data: {state.data}</div>
|
|
4014
|
-
<button onClick={() => queryClient.invalidateQueries({ queryKey: key
|
|
4035
|
+
<button onClick={() => queryClient.invalidateQueries({ queryKey: key })}>
|
|
4015
4036
|
invalidate
|
|
4016
4037
|
</button>
|
|
4017
4038
|
</div>);
|
|
@@ -4039,20 +4060,20 @@ describe('createQuery', () => {
|
|
|
4039
4060
|
const key = queryKey();
|
|
4040
4061
|
let count = 0;
|
|
4041
4062
|
function Page() {
|
|
4042
|
-
const state = createQuery({
|
|
4063
|
+
const state = createQuery(() => ({
|
|
4043
4064
|
queryKey: key,
|
|
4044
4065
|
queryFn: async () => {
|
|
4045
4066
|
count++;
|
|
4046
4067
|
await sleep(10);
|
|
4047
4068
|
return 'data' + count;
|
|
4048
4069
|
},
|
|
4049
|
-
});
|
|
4070
|
+
}));
|
|
4050
4071
|
return (<div>
|
|
4051
4072
|
<div>
|
|
4052
4073
|
status: {state.status}, fetchStatus: {state.fetchStatus}
|
|
4053
4074
|
</div>
|
|
4054
4075
|
<div>data: {state.data}</div>
|
|
4055
|
-
<button onClick={() => queryClient.invalidateQueries({ queryKey: key
|
|
4076
|
+
<button onClick={() => queryClient.invalidateQueries({ queryKey: key })}>
|
|
4056
4077
|
invalidate
|
|
4057
4078
|
</button>
|
|
4058
4079
|
</div>);
|
|
@@ -4064,7 +4085,7 @@ describe('createQuery', () => {
|
|
|
4064
4085
|
const onlineMock = mockNavigatorOnLine(false);
|
|
4065
4086
|
fireEvent.click(screen.getByRole('button', { name: /invalidate/i }));
|
|
4066
4087
|
await waitFor(() => screen.getByText('status: success, fetchStatus: paused'));
|
|
4067
|
-
window.dispatchEvent(new
|
|
4088
|
+
window.dispatchEvent(new Event('visibilitychange'));
|
|
4068
4089
|
await sleep(15);
|
|
4069
4090
|
await waitFor(() => expect(screen.queryByText('data: data2')).not.toBeInTheDocument());
|
|
4070
4091
|
expect(count).toBe(1);
|
|
@@ -4074,20 +4095,20 @@ describe('createQuery', () => {
|
|
|
4074
4095
|
const key = queryKey();
|
|
4075
4096
|
let count = 0;
|
|
4076
4097
|
function Page() {
|
|
4077
|
-
const state = createQuery({
|
|
4098
|
+
const state = createQuery(() => ({
|
|
4078
4099
|
queryKey: key,
|
|
4079
4100
|
queryFn: async () => {
|
|
4080
4101
|
count++;
|
|
4081
4102
|
await sleep(10);
|
|
4082
4103
|
return 'data' + count;
|
|
4083
4104
|
},
|
|
4084
|
-
});
|
|
4105
|
+
}));
|
|
4085
4106
|
return (<div>
|
|
4086
4107
|
<div>
|
|
4087
4108
|
status: {state.status}, fetchStatus: {state.fetchStatus}
|
|
4088
4109
|
</div>
|
|
4089
4110
|
<div>data: {state.data}</div>
|
|
4090
|
-
<button onClick={() => queryClient.invalidateQueries({ queryKey: key
|
|
4111
|
+
<button onClick={() => queryClient.invalidateQueries({ queryKey: key })}>
|
|
4091
4112
|
invalidate
|
|
4092
4113
|
</button>
|
|
4093
4114
|
</div>);
|
|
@@ -4096,11 +4117,11 @@ describe('createQuery', () => {
|
|
|
4096
4117
|
render(() => (<QueryClientProvider client={queryClient}>
|
|
4097
4118
|
<Page />
|
|
4098
4119
|
</QueryClientProvider>));
|
|
4099
|
-
await waitFor(() => screen.getByText('status:
|
|
4120
|
+
await waitFor(() => screen.getByText('status: pending, fetchStatus: paused'));
|
|
4100
4121
|
fireEvent.click(screen.getByRole('button', { name: /invalidate/i }));
|
|
4101
4122
|
await sleep(15);
|
|
4102
4123
|
// invalidation should not trigger a refetch
|
|
4103
|
-
await waitFor(() => screen.getByText('status:
|
|
4124
|
+
await waitFor(() => screen.getByText('status: pending, fetchStatus: paused'));
|
|
4104
4125
|
expect(count).toBe(0);
|
|
4105
4126
|
onlineMock.mockRestore();
|
|
4106
4127
|
});
|
|
@@ -4108,7 +4129,7 @@ describe('createQuery', () => {
|
|
|
4108
4129
|
const key = queryKey();
|
|
4109
4130
|
let count = 0;
|
|
4110
4131
|
function Page() {
|
|
4111
|
-
const state = createQuery({
|
|
4132
|
+
const state = createQuery(() => ({
|
|
4112
4133
|
queryKey: key,
|
|
4113
4134
|
queryFn: async () => {
|
|
4114
4135
|
count++;
|
|
@@ -4116,13 +4137,13 @@ describe('createQuery', () => {
|
|
|
4116
4137
|
return 'data' + count;
|
|
4117
4138
|
},
|
|
4118
4139
|
initialData: 'initial',
|
|
4119
|
-
});
|
|
4140
|
+
}));
|
|
4120
4141
|
return (<div>
|
|
4121
4142
|
<div>
|
|
4122
4143
|
status: {state.status}, fetchStatus: {state.fetchStatus}
|
|
4123
4144
|
</div>
|
|
4124
4145
|
<div>data: {state.data}</div>
|
|
4125
|
-
<button onClick={() => queryClient.invalidateQueries({ queryKey: key
|
|
4146
|
+
<button onClick={() => queryClient.invalidateQueries({ queryKey: key })}>
|
|
4126
4147
|
invalidate
|
|
4127
4148
|
</button>
|
|
4128
4149
|
</div>);
|
|
@@ -4146,7 +4167,7 @@ describe('createQuery', () => {
|
|
|
4146
4167
|
const key = queryKey();
|
|
4147
4168
|
let count = 0;
|
|
4148
4169
|
function Page() {
|
|
4149
|
-
const state = createQuery({
|
|
4170
|
+
const state = createQuery(() => ({
|
|
4150
4171
|
queryKey: key,
|
|
4151
4172
|
queryFn: async () => {
|
|
4152
4173
|
count++;
|
|
@@ -4154,13 +4175,13 @@ describe('createQuery', () => {
|
|
|
4154
4175
|
return 'data' + count;
|
|
4155
4176
|
},
|
|
4156
4177
|
initialData: 'initial',
|
|
4157
|
-
});
|
|
4178
|
+
}));
|
|
4158
4179
|
return (<div>
|
|
4159
4180
|
<div>
|
|
4160
4181
|
status: {state.status}, fetchStatus: {state.fetchStatus}
|
|
4161
4182
|
</div>
|
|
4162
4183
|
<div>data: {state.data}</div>
|
|
4163
|
-
<button onClick={() => queryClient.invalidateQueries({ queryKey: key
|
|
4184
|
+
<button onClick={() => queryClient.invalidateQueries({ queryKey: key })}>
|
|
4164
4185
|
invalidate
|
|
4165
4186
|
</button>
|
|
4166
4187
|
</div>);
|
|
@@ -4178,7 +4199,7 @@ describe('createQuery', () => {
|
|
|
4178
4199
|
await sleep(15);
|
|
4179
4200
|
await waitFor(() => screen.getByText('status: success, fetchStatus: paused'));
|
|
4180
4201
|
// triggers a second pause
|
|
4181
|
-
window.dispatchEvent(new
|
|
4202
|
+
window.dispatchEvent(new Event('visibilitychange'));
|
|
4182
4203
|
onlineMock.mockReturnValue(true);
|
|
4183
4204
|
window.dispatchEvent(new Event('online'));
|
|
4184
4205
|
await waitFor(() => screen.getByText('status: success, fetchStatus: idle'));
|
|
@@ -4192,7 +4213,7 @@ describe('createQuery', () => {
|
|
|
4192
4213
|
const key = queryKey();
|
|
4193
4214
|
let count = 0;
|
|
4194
4215
|
function Page() {
|
|
4195
|
-
const state = createQuery({
|
|
4216
|
+
const state = createQuery(() => ({
|
|
4196
4217
|
queryKey: key,
|
|
4197
4218
|
queryFn: async () => {
|
|
4198
4219
|
count++;
|
|
@@ -4201,7 +4222,7 @@ describe('createQuery', () => {
|
|
|
4201
4222
|
},
|
|
4202
4223
|
retry: 2,
|
|
4203
4224
|
retryDelay: 10,
|
|
4204
|
-
});
|
|
4225
|
+
}));
|
|
4205
4226
|
return (<div>
|
|
4206
4227
|
<div>
|
|
4207
4228
|
status: {state.status}, fetchStatus: {state.fetchStatus},
|
|
@@ -4213,11 +4234,11 @@ describe('createQuery', () => {
|
|
|
4213
4234
|
render(() => (<QueryClientProvider client={queryClient}>
|
|
4214
4235
|
<Page />
|
|
4215
4236
|
</QueryClientProvider>));
|
|
4216
|
-
await waitFor(() => screen.getByText('status:
|
|
4237
|
+
await waitFor(() => screen.getByText('status: pending, fetchStatus: fetching, failureCount: 1'));
|
|
4217
4238
|
await waitFor(() => screen.getByText('failureReason: failed1'));
|
|
4218
4239
|
const onlineMock = mockNavigatorOnLine(false);
|
|
4219
4240
|
await sleep(20);
|
|
4220
|
-
await waitFor(() => screen.getByText('status:
|
|
4241
|
+
await waitFor(() => screen.getByText('status: pending, fetchStatus: paused, failureCount: 1'));
|
|
4221
4242
|
await waitFor(() => screen.getByText('failureReason: failed1'));
|
|
4222
4243
|
expect(count).toBe(1);
|
|
4223
4244
|
onlineMock.mockReturnValue(true);
|
|
@@ -4231,14 +4252,14 @@ describe('createQuery', () => {
|
|
|
4231
4252
|
const key = queryKey();
|
|
4232
4253
|
let count = 0;
|
|
4233
4254
|
function Component() {
|
|
4234
|
-
const state = createQuery({
|
|
4255
|
+
const state = createQuery(() => ({
|
|
4235
4256
|
queryKey: key,
|
|
4236
4257
|
queryFn: async () => {
|
|
4237
4258
|
count++;
|
|
4238
4259
|
await sleep(10);
|
|
4239
4260
|
return 'data' + count;
|
|
4240
4261
|
},
|
|
4241
|
-
});
|
|
4262
|
+
}));
|
|
4242
4263
|
return (<div>
|
|
4243
4264
|
<div>
|
|
4244
4265
|
status: {state.status}, fetchStatus: {state.fetchStatus}
|
|
@@ -4257,12 +4278,12 @@ describe('createQuery', () => {
|
|
|
4257
4278
|
render(() => (<QueryClientProvider client={queryClient}>
|
|
4258
4279
|
<Page />
|
|
4259
4280
|
</QueryClientProvider>));
|
|
4260
|
-
await waitFor(() => screen.getByText('status:
|
|
4281
|
+
await waitFor(() => screen.getByText('status: pending, fetchStatus: paused'));
|
|
4261
4282
|
fireEvent.click(screen.getByRole('button', { name: /hide/i }));
|
|
4262
4283
|
onlineMock.mockReturnValue(true);
|
|
4263
4284
|
window.dispatchEvent(new Event('online'));
|
|
4264
4285
|
await sleep(15);
|
|
4265
|
-
expect(queryClient.getQueryState(key
|
|
4286
|
+
expect(queryClient.getQueryState(key)).toMatchObject({
|
|
4266
4287
|
fetchStatus: 'idle',
|
|
4267
4288
|
status: 'success',
|
|
4268
4289
|
});
|
|
@@ -4273,7 +4294,7 @@ describe('createQuery', () => {
|
|
|
4273
4294
|
const key = queryKey();
|
|
4274
4295
|
let count = 0;
|
|
4275
4296
|
function Page() {
|
|
4276
|
-
const state = createQuery({
|
|
4297
|
+
const state = createQuery(() => ({
|
|
4277
4298
|
queryKey: key,
|
|
4278
4299
|
queryFn: async () => {
|
|
4279
4300
|
count++;
|
|
@@ -4281,9 +4302,9 @@ describe('createQuery', () => {
|
|
|
4281
4302
|
return 'data' + count;
|
|
4282
4303
|
},
|
|
4283
4304
|
refetchOnReconnect: false,
|
|
4284
|
-
});
|
|
4305
|
+
}));
|
|
4285
4306
|
return (<div>
|
|
4286
|
-
<button onClick={() => queryClient.cancelQueries({ queryKey: key
|
|
4307
|
+
<button onClick={() => queryClient.cancelQueries({ queryKey: key })}>
|
|
4287
4308
|
cancel
|
|
4288
4309
|
</button>
|
|
4289
4310
|
<div>
|
|
@@ -4296,14 +4317,14 @@ describe('createQuery', () => {
|
|
|
4296
4317
|
render(() => (<QueryClientProvider client={queryClient}>
|
|
4297
4318
|
<Page />
|
|
4298
4319
|
</QueryClientProvider>));
|
|
4299
|
-
await waitFor(() => screen.getByText('status:
|
|
4320
|
+
await waitFor(() => screen.getByText('status: pending, fetchStatus: paused'));
|
|
4300
4321
|
fireEvent.click(screen.getByRole('button', { name: /cancel/i }));
|
|
4301
|
-
await waitFor(() => screen.getByText('status:
|
|
4322
|
+
await waitFor(() => screen.getByText('status: pending, fetchStatus: idle'));
|
|
4302
4323
|
expect(count).toBe(0);
|
|
4303
4324
|
onlineMock.mockReturnValue(true);
|
|
4304
4325
|
window.dispatchEvent(new Event('online'));
|
|
4305
4326
|
await sleep(15);
|
|
4306
|
-
await waitFor(() => screen.getByText('status:
|
|
4327
|
+
await waitFor(() => screen.getByText('status: pending, fetchStatus: idle'));
|
|
4307
4328
|
expect(count).toBe(0);
|
|
4308
4329
|
onlineMock.mockRestore();
|
|
4309
4330
|
});
|
|
@@ -4311,14 +4332,14 @@ describe('createQuery', () => {
|
|
|
4311
4332
|
const key = queryKey();
|
|
4312
4333
|
let count = 0;
|
|
4313
4334
|
function Component() {
|
|
4314
|
-
const state = createQuery({
|
|
4335
|
+
const state = createQuery(() => ({
|
|
4315
4336
|
queryKey: key,
|
|
4316
|
-
queryFn: async ({ signal }) => {
|
|
4337
|
+
queryFn: async ({ signal: _signal }) => {
|
|
4317
4338
|
count++;
|
|
4318
4339
|
await sleep(10);
|
|
4319
|
-
return
|
|
4340
|
+
return `signal${count}`;
|
|
4320
4341
|
},
|
|
4321
|
-
});
|
|
4342
|
+
}));
|
|
4322
4343
|
return (<div>
|
|
4323
4344
|
<div>
|
|
4324
4345
|
status: {state.status}, fetchStatus: {state.fetchStatus}
|
|
@@ -4331,7 +4352,7 @@ describe('createQuery', () => {
|
|
|
4331
4352
|
return (<div>
|
|
4332
4353
|
{show() && <Component />}
|
|
4333
4354
|
<button onClick={() => setShow(false)}>hide</button>
|
|
4334
|
-
<button onClick={() => queryClient.invalidateQueries({ queryKey: key
|
|
4355
|
+
<button onClick={() => queryClient.invalidateQueries({ queryKey: key })}>
|
|
4335
4356
|
invalidate
|
|
4336
4357
|
</button>
|
|
4337
4358
|
</div>);
|
|
@@ -4348,7 +4369,7 @@ describe('createQuery', () => {
|
|
|
4348
4369
|
onlineMock.mockReturnValue(true);
|
|
4349
4370
|
window.dispatchEvent(new Event('online'));
|
|
4350
4371
|
await sleep(15);
|
|
4351
|
-
expect(queryClient.getQueryState(key
|
|
4372
|
+
expect(queryClient.getQueryState(key)).toMatchObject({
|
|
4352
4373
|
fetchStatus: 'idle',
|
|
4353
4374
|
status: 'success',
|
|
4354
4375
|
});
|
|
@@ -4362,7 +4383,7 @@ describe('createQuery', () => {
|
|
|
4362
4383
|
const key = queryKey();
|
|
4363
4384
|
let count = 0;
|
|
4364
4385
|
function Page() {
|
|
4365
|
-
const state = createQuery({
|
|
4386
|
+
const state = createQuery(() => ({
|
|
4366
4387
|
queryKey: key,
|
|
4367
4388
|
queryFn: async () => {
|
|
4368
4389
|
count++;
|
|
@@ -4370,7 +4391,7 @@ describe('createQuery', () => {
|
|
|
4370
4391
|
return 'data ' + count;
|
|
4371
4392
|
},
|
|
4372
4393
|
networkMode: 'always',
|
|
4373
|
-
});
|
|
4394
|
+
}));
|
|
4374
4395
|
return (<div>
|
|
4375
4396
|
<div>
|
|
4376
4397
|
status: {state.status}, isPaused: {String(state.isPaused)}
|
|
@@ -4392,7 +4413,7 @@ describe('createQuery', () => {
|
|
|
4392
4413
|
const key = queryKey();
|
|
4393
4414
|
let count = 0;
|
|
4394
4415
|
function Page() {
|
|
4395
|
-
const state = createQuery({
|
|
4416
|
+
const state = createQuery(() => ({
|
|
4396
4417
|
queryKey: key,
|
|
4397
4418
|
queryFn: async () => {
|
|
4398
4419
|
count++;
|
|
@@ -4402,7 +4423,7 @@ describe('createQuery', () => {
|
|
|
4402
4423
|
networkMode: 'always',
|
|
4403
4424
|
retry: 1,
|
|
4404
4425
|
retryDelay: 5,
|
|
4405
|
-
});
|
|
4426
|
+
}));
|
|
4406
4427
|
return (<div>
|
|
4407
4428
|
<div>
|
|
4408
4429
|
status: {state.status}, isPaused: {String(state.isPaused)}
|
|
@@ -4429,7 +4450,7 @@ describe('createQuery', () => {
|
|
|
4429
4450
|
const key = queryKey();
|
|
4430
4451
|
let count = 0;
|
|
4431
4452
|
function Page() {
|
|
4432
|
-
const state = createQuery({
|
|
4453
|
+
const state = createQuery(() => ({
|
|
4433
4454
|
queryKey: key,
|
|
4434
4455
|
queryFn: async () => {
|
|
4435
4456
|
count++;
|
|
@@ -4439,7 +4460,7 @@ describe('createQuery', () => {
|
|
|
4439
4460
|
retry: 2,
|
|
4440
4461
|
retryDelay: 1,
|
|
4441
4462
|
networkMode: 'offlineFirst',
|
|
4442
|
-
});
|
|
4463
|
+
}));
|
|
4443
4464
|
return (<div>
|
|
4444
4465
|
<div>
|
|
4445
4466
|
status: {state.status}, fetchStatus: {state.fetchStatus},
|
|
@@ -4451,7 +4472,7 @@ describe('createQuery', () => {
|
|
|
4451
4472
|
render(() => (<QueryClientProvider client={queryClient}>
|
|
4452
4473
|
<Page />
|
|
4453
4474
|
</QueryClientProvider>));
|
|
4454
|
-
await waitFor(() => screen.getByText('status:
|
|
4475
|
+
await waitFor(() => screen.getByText('status: pending, fetchStatus: paused, failureCount: 1'));
|
|
4455
4476
|
await waitFor(() => screen.getByText('failureReason: failed1'));
|
|
4456
4477
|
expect(count).toBe(1);
|
|
4457
4478
|
onlineMock.mockReturnValue(true);
|
|
@@ -4470,16 +4491,18 @@ describe('createQuery', () => {
|
|
|
4470
4491
|
throw error;
|
|
4471
4492
|
};
|
|
4472
4493
|
function Page() {
|
|
4473
|
-
const state = createQuery(
|
|
4494
|
+
const state = createQuery(() => ({
|
|
4495
|
+
queryKey: key,
|
|
4496
|
+
queryFn,
|
|
4474
4497
|
retry: false,
|
|
4475
4498
|
retryOnMount: false,
|
|
4476
|
-
});
|
|
4499
|
+
}));
|
|
4477
4500
|
createRenderEffect(() => {
|
|
4478
4501
|
states.push({ ...state });
|
|
4479
4502
|
});
|
|
4480
4503
|
return <></>;
|
|
4481
4504
|
}
|
|
4482
|
-
await queryClient.prefetchQuery(key
|
|
4505
|
+
await queryClient.prefetchQuery({ queryKey: key, queryFn });
|
|
4483
4506
|
render(() => (<QueryClientProvider client={queryClient}>
|
|
4484
4507
|
<Page />
|
|
4485
4508
|
</QueryClientProvider>));
|
|
@@ -4493,10 +4516,14 @@ describe('createQuery', () => {
|
|
|
4493
4516
|
const key = queryKey();
|
|
4494
4517
|
const onSuccess = jest.fn();
|
|
4495
4518
|
function Page() {
|
|
4496
|
-
const state = createQuery(
|
|
4519
|
+
const state = createQuery(() => ({
|
|
4520
|
+
queryKey: key,
|
|
4521
|
+
queryFn: () => 'data',
|
|
4522
|
+
onSuccess,
|
|
4523
|
+
}));
|
|
4497
4524
|
return (<div>
|
|
4498
4525
|
<div>data: {state.data}</div>
|
|
4499
|
-
<button onClick={() => queryClient.setQueryData(key
|
|
4526
|
+
<button onClick={() => queryClient.setQueryData(key, 'newData')}>
|
|
4500
4527
|
setQueryData
|
|
4501
4528
|
</button>
|
|
4502
4529
|
</div>);
|
|
@@ -4513,11 +4540,16 @@ describe('createQuery', () => {
|
|
|
4513
4540
|
it('setQueryData - should respect updatedAt', async () => {
|
|
4514
4541
|
const key = queryKey();
|
|
4515
4542
|
function Page() {
|
|
4516
|
-
const state = createQuery(
|
|
4543
|
+
const state = createQuery(() => ({
|
|
4544
|
+
queryKey: key,
|
|
4545
|
+
queryFn: () => 'data',
|
|
4546
|
+
}));
|
|
4517
4547
|
return (<div>
|
|
4518
4548
|
<div>data: {state.data}</div>
|
|
4519
4549
|
<div>dataUpdatedAt: {state.dataUpdatedAt}</div>
|
|
4520
|
-
<button onClick={() => queryClient.setQueryData(key
|
|
4550
|
+
<button onClick={() => queryClient.setQueryData(key, 'newData', {
|
|
4551
|
+
updatedAt: 100,
|
|
4552
|
+
})}>
|
|
4521
4553
|
setQueryData
|
|
4522
4554
|
</button>
|
|
4523
4555
|
</div>);
|
|
@@ -4536,11 +4568,13 @@ describe('createQuery', () => {
|
|
|
4536
4568
|
const key = queryKey();
|
|
4537
4569
|
const error = new Error('oops');
|
|
4538
4570
|
function Page() {
|
|
4539
|
-
const state = createQuery(
|
|
4540
|
-
|
|
4541
|
-
|
|
4571
|
+
const state = createQuery(() => ({
|
|
4572
|
+
queryKey: key,
|
|
4573
|
+
queryFn: async () => {
|
|
4574
|
+
throw error;
|
|
4575
|
+
},
|
|
4542
4576
|
retry: false,
|
|
4543
|
-
});
|
|
4577
|
+
}));
|
|
4544
4578
|
return (<div>
|
|
4545
4579
|
<button onClick={() => state.refetch()}>refetch</button>
|
|
4546
4580
|
<span>data: {state.errorUpdateCount}</span>
|
|
@@ -4556,4 +4590,18 @@ describe('createQuery', () => {
|
|
|
4556
4590
|
fireEvent.click(fetchBtn);
|
|
4557
4591
|
await waitFor(() => screen.getByText('data: 3'));
|
|
4558
4592
|
});
|
|
4593
|
+
it('should use provided custom queryClient', async () => {
|
|
4594
|
+
const key = queryKey();
|
|
4595
|
+
const queryFn = () => {
|
|
4596
|
+
return Promise.resolve('custom client');
|
|
4597
|
+
};
|
|
4598
|
+
function Page() {
|
|
4599
|
+
const state = createQuery(() => ({ queryKey: key, queryFn }), () => queryClient);
|
|
4600
|
+
return (<div>
|
|
4601
|
+
<h1>Status: {state.data}</h1>
|
|
4602
|
+
</div>);
|
|
4603
|
+
}
|
|
4604
|
+
render(() => <Page />);
|
|
4605
|
+
await waitFor(() => screen.getByText('Status: custom client'));
|
|
4606
|
+
});
|
|
4559
4607
|
});
|