1
- import { describe , expect , it , vi } from 'vitest'
1
+ import { afterEach , beforeEach , describe , expect , it , vi } from 'vitest'
2
2
import {
3
3
ErrorBoundary ,
4
4
createEffect ,
5
5
createRenderEffect ,
6
6
createSignal ,
7
7
} from 'solid-js'
8
- import { fireEvent , render , waitFor } from '@solidjs/testing-library'
8
+ import { fireEvent , render } from '@solidjs/testing-library'
9
9
import { MutationCache , QueryCache , QueryClientProvider , useMutation } from '..'
10
10
import {
11
11
createQueryClient ,
@@ -17,6 +17,14 @@ import {
17
17
import type { UseMutationResult } from '../types'
18
18
19
19
describe ( 'useMutation' , ( ) => {
20
+ beforeEach ( ( ) => {
21
+ vi . useFakeTimers ( )
22
+ } )
23
+
24
+ afterEach ( ( ) => {
25
+ vi . useRealTimers ( )
26
+ } )
27
+
20
28
const queryCache = new QueryCache ( )
21
29
const mutationCache = new MutationCache ( )
22
30
const queryClient = createQueryClient ( { queryCache, mutationCache } )
@@ -46,15 +54,14 @@ describe('useMutation', () => {
46
54
47
55
fireEvent . click ( rendered . getByRole ( 'button' , { name : / m u t a t e / i } ) )
48
56
49
- await waitFor ( ( ) => {
57
+ await vi . waitFor ( ( ) => {
50
58
expect ( rendered . getByRole ( 'heading' ) . textContent ) . toBe ( 'mutation' )
51
59
} )
52
60
53
61
fireEvent . click ( rendered . getByRole ( 'button' , { name : / r e s e t / i } ) )
54
62
55
- await waitFor ( ( ) => {
56
- expect ( rendered . getByRole ( 'heading' ) . textContent ) . toBe ( 'empty' )
57
- } )
63
+ await vi . waitFor ( ( ) => { } )
64
+ expect ( rendered . getByRole ( 'heading' ) . textContent ) . toBe ( 'empty' )
58
65
} )
59
66
60
67
it ( 'should be able to reset `error`' , async ( ) => {
@@ -86,21 +93,19 @@ describe('useMutation', () => {
86
93
</ QueryClientProvider >
87
94
) )
88
95
89
- await waitFor ( ( ) => {
90
- expect ( rendered . queryByRole ( 'heading' ) ) . toBeNull ( )
91
- } )
96
+ expect ( rendered . queryByRole ( 'heading' ) ) . toBeNull ( )
92
97
93
98
fireEvent . click ( rendered . getByRole ( 'button' , { name : / m u t a t e / i } ) )
94
99
95
- await waitFor ( ( ) => {
100
+ await vi . waitFor ( ( ) => {
96
101
expect ( rendered . getByRole ( 'heading' ) . textContent ) . toBe (
97
102
'Expected mock error. All is well!' ,
98
103
)
99
104
} )
100
105
101
106
fireEvent . click ( rendered . getByRole ( 'button' , { name : / r e s e t / i } ) )
102
107
103
- await waitFor ( ( ) => {
108
+ await vi . waitFor ( ( ) => {
104
109
expect ( rendered . queryByRole ( 'heading' ) ) . toBeNull ( )
105
110
} )
106
111
@@ -150,19 +155,19 @@ describe('useMutation', () => {
150
155
fireEvent . click ( rendered . getByRole ( 'button' , { name : / m u t a t e / i } ) )
151
156
fireEvent . click ( rendered . getByRole ( 'button' , { name : / m u t a t e / i } ) )
152
157
153
- await waitFor ( ( ) => {
158
+ await vi . waitFor ( ( ) => {
154
159
expect ( rendered . getByRole ( 'heading' ) . textContent ) . toBe ( '3' )
155
160
} )
156
161
157
- await waitFor ( ( ) => {
162
+ await vi . waitFor ( ( ) => {
158
163
expect ( onSuccessMock ) . toHaveBeenCalledTimes ( 3 )
159
164
} )
160
165
161
166
expect ( onSuccessMock ) . toHaveBeenCalledWith ( 1 )
162
167
expect ( onSuccessMock ) . toHaveBeenCalledWith ( 2 )
163
168
expect ( onSuccessMock ) . toHaveBeenCalledWith ( 3 )
164
169
165
- await waitFor ( ( ) => {
170
+ await vi . waitFor ( ( ) => {
166
171
expect ( onSettledMock ) . toHaveBeenCalledTimes ( 3 )
167
172
} )
168
173
@@ -177,14 +182,11 @@ describe('useMutation', () => {
177
182
178
183
const mutateFn = vi . fn < ( value : Value ) => Promise < Value > > ( )
179
184
180
- mutateFn . mockImplementationOnce ( ( ) => {
181
- return Promise . reject ( new Error ( 'Error test Jonas' ) )
182
- } )
185
+ mutateFn . mockImplementationOnce ( ( ) =>
186
+ Promise . reject ( new Error ( 'Error test Jonas' ) ) ,
187
+ )
183
188
184
- mutateFn . mockImplementation ( async ( value ) => {
185
- await sleep ( 10 )
186
- return Promise . resolve ( value )
187
- } )
189
+ mutateFn . mockImplementation ( ( value ) => sleep ( 10 ) . then ( ( ) => value ) )
188
190
189
191
function Page ( ) {
190
192
const mutation = useMutation ( ( ) => ( {
@@ -215,20 +217,22 @@ describe('useMutation', () => {
215
217
</ QueryClientProvider >
216
218
) )
217
219
218
- await waitFor ( ( ) => rendered . getByText ( 'Data' ) )
220
+ rendered . getByText ( 'Data' )
219
221
220
222
fireEvent . click ( rendered . getByRole ( 'button' , { name : / m u t a t e / i } ) )
221
- await waitFor ( ( ) => rendered . getByText ( 'Data' ) )
222
- await waitFor ( ( ) => rendered . getByText ( 'Status error' ) )
223
- await waitFor ( ( ) => rendered . getByText ( 'Failed 1 times' ) )
224
- await waitFor ( ( ) => rendered . getByText ( 'Failed because Error test Jonas' ) )
223
+ rendered . getByText ( 'Data' )
224
+ await vi . waitFor ( ( ) => rendered . getByText ( 'Status error' ) )
225
+ await vi . waitFor ( ( ) => rendered . getByText ( 'Failed 1 times' ) )
226
+ await vi . waitFor ( ( ) =>
227
+ rendered . getByText ( 'Failed because Error test Jonas' ) ,
228
+ )
225
229
226
230
fireEvent . click ( rendered . getByRole ( 'button' , { name : / m u t a t e / i } ) )
227
- await waitFor ( ( ) => rendered . getByText ( 'Status pending' ) )
228
- await waitFor ( ( ) => rendered . getByText ( 'Status success' ) )
229
- await waitFor ( ( ) => rendered . getByText ( 'Data 2' ) )
230
- await waitFor ( ( ) => rendered . getByText ( 'Failed 0 times' ) )
231
- await waitFor ( ( ) => rendered . getByText ( 'Failed because null' ) )
231
+ await vi . waitFor ( ( ) => rendered . getByText ( 'Status pending' ) )
232
+ await vi . waitFor ( ( ) => rendered . getByText ( 'Status success' ) )
233
+ await vi . waitFor ( ( ) => rendered . getByText ( 'Data 2' ) )
234
+ await vi . waitFor ( ( ) => rendered . getByText ( 'Failed 0 times' ) )
235
+ await vi . waitFor ( ( ) => rendered . getByText ( 'Failed because null' ) )
232
236
} )
233
237
234
238
it ( 'should be able to call `onError` and `onSettled` after each failed mutate' , async ( ) => {
@@ -280,11 +284,11 @@ describe('useMutation', () => {
280
284
fireEvent . click ( rendered . getByRole ( 'button' , { name : / m u t a t e / i } ) )
281
285
fireEvent . click ( rendered . getByRole ( 'button' , { name : / m u t a t e / i } ) )
282
286
283
- await waitFor ( ( ) => {
287
+ await vi . waitFor ( ( ) => {
284
288
expect ( rendered . getByRole ( 'heading' ) . textContent ) . toBe ( '3' )
285
289
} )
286
290
287
- await waitFor ( ( ) => {
291
+ await vi . waitFor ( ( ) => {
288
292
expect ( onErrorMock ) . toHaveBeenCalledTimes ( 3 )
289
293
} )
290
294
expect ( onErrorMock ) . toHaveBeenCalledWith (
@@ -297,7 +301,7 @@ describe('useMutation', () => {
297
301
'Expected mock error. All is well! 3' ,
298
302
)
299
303
300
- await waitFor ( ( ) => {
304
+ await vi . waitFor ( ( ) => {
301
305
expect ( onSettledMock ) . toHaveBeenCalledTimes ( 3 )
302
306
} )
303
307
expect ( onSettledMock ) . toHaveBeenCalledWith (
@@ -351,7 +355,7 @@ describe('useMutation', () => {
351
355
</ QueryClientProvider >
352
356
) )
353
357
354
- await sleep ( 100 )
358
+ await vi . advanceTimersByTimeAsync ( 10 )
355
359
356
360
expect ( callbacks ) . toEqual ( [
357
361
'useMutation.onSuccess' ,
@@ -367,7 +371,7 @@ describe('useMutation', () => {
367
371
368
372
function Page ( ) {
369
373
const mutation = useMutation ( ( ) => ( {
370
- mutationFn : async ( _text : string ) => Promise . reject ( new Error ( 'oops' ) ) ,
374
+ mutationFn : ( _text : string ) => Promise . reject ( new Error ( 'oops' ) ) ,
371
375
372
376
onError : ( ) => {
373
377
callbacks . push ( 'useMutation.onError' )
@@ -404,7 +408,7 @@ describe('useMutation', () => {
404
408
</ QueryClientProvider >
405
409
) )
406
410
407
- await sleep ( 100 )
411
+ await vi . advanceTimersByTimeAsync ( 10 )
408
412
409
413
expect ( callbacks ) . toEqual ( [
410
414
'useMutation.onError' ,
@@ -419,10 +423,7 @@ describe('useMutation', () => {
419
423
const key = queryKey ( )
420
424
421
425
queryClient . setMutationDefaults ( key , {
422
- mutationFn : async ( text : string ) => {
423
- await sleep ( 10 )
424
- return text
425
- } ,
426
+ mutationFn : ( text : string ) => sleep ( 10 ) . then ( ( ) => text ) ,
426
427
} )
427
428
428
429
const states : Array < UseMutationResult < any , any , any , any > > = [ ]
@@ -452,7 +453,7 @@ describe('useMutation', () => {
452
453
</ QueryClientProvider >
453
454
) )
454
455
455
- await sleep ( 100 )
456
+ await vi . advanceTimersByTimeAsync ( 20 )
456
457
457
458
expect ( states . length ) . toBe ( 3 )
458
459
expect ( states [ 0 ] ) . toMatchObject ( { data : undefined , isPending : false } )
@@ -489,7 +490,7 @@ describe('useMutation', () => {
489
490
</ QueryClientProvider >
490
491
) )
491
492
492
- await sleep ( 100 )
493
+ await vi . advanceTimersByTimeAsync ( 20 )
493
494
494
495
expect ( count ) . toBe ( 2 )
495
496
} )
@@ -529,34 +530,27 @@ describe('useMutation', () => {
529
530
</ QueryClientProvider >
530
531
) )
531
532
532
- await waitFor ( ( ) => {
533
- expect (
534
- rendered . getByText ( 'error: null, status: idle, isPaused: false' ) ,
535
- ) . toBeInTheDocument ( )
536
- } )
533
+ expect (
534
+ rendered . getByText ( 'error: null, status: idle, isPaused: false' ) ,
535
+ ) . toBeInTheDocument ( )
537
536
538
537
window . dispatchEvent ( new Event ( 'offline' ) )
539
538
540
539
fireEvent . click ( rendered . getByRole ( 'button' , { name : / m u t a t e / i } ) )
541
540
542
- await waitFor ( ( ) => {
543
- expect (
544
- rendered . getByText ( 'error: null, status: pending, isPaused: true' ) ,
545
- ) . toBeInTheDocument ( )
546
- } )
541
+ expect (
542
+ rendered . getByText ( 'error: null, status: pending, isPaused: true' ) ,
543
+ ) . toBeInTheDocument ( )
547
544
548
545
expect ( count ) . toBe ( 0 )
549
546
550
547
onlineMock . mockRestore ( )
551
548
window . dispatchEvent ( new Event ( 'online' ) )
552
549
553
- await sleep ( 100 )
554
-
555
- await waitFor ( ( ) => {
556
- expect (
557
- rendered . getByText ( 'error: oops, status: error, isPaused: false' ) ,
558
- ) . toBeInTheDocument ( )
559
- } )
550
+ await vi . advanceTimersByTimeAsync ( 5 )
551
+ expect (
552
+ rendered . getByText ( 'error: oops, status: error, isPaused: false' ) ,
553
+ ) . toBeInTheDocument ( )
560
554
561
555
expect ( count ) . toBe ( 2 )
562
556
} )
@@ -607,6 +601,7 @@ describe('useMutation', () => {
607
601
onlineMock . mockRestore ( )
608
602
window . dispatchEvent ( new Event ( 'online' ) )
609
603
604
+ await vi . advanceTimersByTimeAsync ( 10 )
610
605
await rendered . findByText ( 'data: 1, status: success, isPaused: false' )
611
606
612
607
expect ( onMutate ) . toHaveBeenCalledTimes ( 1 )
@@ -661,6 +656,7 @@ describe('useMutation', () => {
661
656
onlineMock . mockReturnValue ( true )
662
657
window . dispatchEvent ( new Event ( 'online' ) )
663
658
659
+ await vi . advanceTimersByTimeAsync ( 10 )
664
660
await rendered . findByText ( 'data: 1, status: success, isPaused: false' )
665
661
666
662
onlineMock . mockRestore ( )
@@ -707,7 +703,7 @@ describe('useMutation', () => {
707
703
</ QueryClientProvider >
708
704
) )
709
705
710
- await sleep ( 50 )
706
+ await vi . advanceTimersByTimeAsync ( 16 )
711
707
712
708
expect ( states . length ) . toBe ( 4 )
713
709
expect ( states [ 0 ] ) . toMatchObject ( {
@@ -738,7 +734,7 @@ describe('useMutation', () => {
738
734
onlineMock . mockRestore ( )
739
735
window . dispatchEvent ( new Event ( 'online' ) )
740
736
741
- await sleep ( 50 )
737
+ await vi . advanceTimersByTimeAsync ( 1 )
742
738
743
739
expect ( states . length ) . toBe ( 6 )
744
740
expect ( states [ 4 ] ) . toMatchObject ( {
@@ -818,7 +814,7 @@ describe('useMutation', () => {
818
814
819
815
fireEvent . click ( rendered . getByText ( 'mutate' ) )
820
816
821
- await waitFor ( ( ) => {
817
+ await vi . waitFor ( ( ) => {
822
818
expect ( rendered . queryByText ( 'error' ) ) . not . toBeNull ( )
823
819
} )
824
820
@@ -868,13 +864,13 @@ describe('useMutation', () => {
868
864
869
865
// first error goes to component
870
866
fireEvent . click ( rendered . getByText ( 'mutate' ) )
871
- await waitFor ( ( ) => {
867
+ await vi . waitFor ( ( ) => {
872
868
expect ( rendered . queryByText ( 'mock error' ) ) . not . toBeNull ( )
873
869
} )
874
870
875
871
// second error goes to boundary
876
872
fireEvent . click ( rendered . getByText ( 'mutate' ) )
877
- await waitFor ( ( ) => {
873
+ await vi . waitFor ( ( ) => {
878
874
expect ( rendered . queryByText ( 'error boundary' ) ) . not . toBeNull ( )
879
875
} )
880
876
@@ -930,7 +926,7 @@ describe('useMutation', () => {
930
926
fireEvent . click ( rendered . getByText ( 'succeed' ) )
931
927
fireEvent . click ( rendered . getByText ( 'error' ) )
932
928
933
- await waitFor ( ( ) => {
929
+ await vi . waitFor ( ( ) => {
934
930
expect ( rendered . queryByText ( 'successTest' ) ) . not . toBeNull ( )
935
931
expect ( rendered . queryByText ( 'errorTest' ) ) . not . toBeNull ( )
936
932
} )
@@ -1003,7 +999,7 @@ describe('useMutation', () => {
1003
999
fireEvent . click ( rendered . getByRole ( 'button' , { name : / m u t a t e / i } ) )
1004
1000
fireEvent . click ( rendered . getByRole ( 'button' , { name : / h i d e / i } ) )
1005
1001
1006
- await waitFor ( ( ) => {
1002
+ await vi . waitFor ( ( ) => {
1007
1003
expect (
1008
1004
queryClient . getMutationCache ( ) . findAll ( { mutationKey : mutationKey } ) ,
1009
1005
) . toHaveLength ( 0 )
@@ -1065,6 +1061,7 @@ describe('useMutation', () => {
1065
1061
fireEvent . click ( rendered . getByRole ( 'button' , { name : / m u t a t e / i } ) )
1066
1062
fireEvent . click ( rendered . getByRole ( 'button' , { name : / m u t a t e / i } ) )
1067
1063
1064
+ await vi . advanceTimersByTimeAsync ( 10 )
1068
1065
await rendered . findByText ( 'data: result2, status: success' )
1069
1066
1070
1067
expect ( count ) . toBe ( 2 )
@@ -1114,6 +1111,7 @@ describe('useMutation', () => {
1114
1111
1115
1112
rendered . getByRole ( 'button' , { name : / m u t a t e / i } ) . click ( )
1116
1113
1114
+ await vi . advanceTimersByTimeAsync ( 10 )
1117
1115
await rendered . findByText ( 'status: error' )
1118
1116
1119
1117
expect ( onError ) . toHaveBeenCalledWith ( error , 'todo' , undefined )
@@ -1154,6 +1152,7 @@ describe('useMutation', () => {
1154
1152
1155
1153
rendered . getByRole ( 'button' , { name : / m u t a t e / i } ) . click ( )
1156
1154
1155
+ await vi . advanceTimersByTimeAsync ( 10 )
1157
1156
await rendered . findByText ( 'error: mutateFnError, status: error' )
1158
1157
} )
1159
1158
@@ -1194,6 +1193,7 @@ describe('useMutation', () => {
1194
1193
1195
1194
rendered . getByRole ( 'button' , { name : / m u t a t e / i } ) . click ( )
1196
1195
1196
+ await vi . advanceTimersByTimeAsync ( 10 )
1197
1197
await rendered . findByText ( 'error: mutateFnError, status: error' )
1198
1198
1199
1199
expect ( onError ) . toHaveBeenCalledWith ( mutateFnError , 'todo' , undefined )
0 commit comments