@@ -3,9 +3,10 @@ import React from "react"
3
3
import { render , fireEvent , cleanup , waitForElement } from "react-testing-library"
4
4
import Async , { createInstance } from "./"
5
5
6
- const abortController = { abort : ( ) => { } }
7
- window . AbortController = jest . fn ( ) . mockImplementation ( ( ) => abortController )
6
+ const abortCtrl = { abort : jest . fn ( ) }
7
+ window . AbortController = jest . fn ( ) . mockImplementation ( ( ) => abortCtrl )
8
8
9
+ beforeEach ( abortCtrl . abort . mockClear )
9
10
afterEach ( cleanup )
10
11
11
12
const resolveIn = ms => value => new Promise ( resolve => setTimeout ( resolve , ms , value ) )
@@ -23,7 +24,7 @@ describe("Async", () => {
23
24
test ( "calls promiseFn with props" , ( ) => {
24
25
const promiseFn = jest . fn ( ) . mockReturnValue ( Promise . resolve ( ) )
25
26
render ( < Async promiseFn = { promiseFn } anotherProp = "123" /> )
26
- expect ( promiseFn ) . toHaveBeenCalledWith ( { promiseFn, anotherProp : "123" } , abortController )
27
+ expect ( promiseFn ) . toHaveBeenCalledWith ( { promiseFn, anotherProp : "123" } , abortCtrl )
27
28
} )
28
29
29
30
test ( "passes resolved data to children as render prop" , async ( ) => {
@@ -99,6 +100,7 @@ describe("Async", () => {
99
100
expect ( promiseFn ) . toHaveBeenCalledTimes ( 1 )
100
101
fireEvent . click ( getByText ( "reload" ) )
101
102
expect ( promiseFn ) . toHaveBeenCalledTimes ( 2 )
103
+ expect ( abortCtrl . abort ) . toHaveBeenCalledTimes ( 1 )
102
104
} )
103
105
104
106
test ( "re-runs the promise when the value of 'watch' changes" , ( ) => {
@@ -121,11 +123,13 @@ describe("Async", () => {
121
123
expect ( promiseFn ) . toHaveBeenCalledTimes ( 1 )
122
124
fireEvent . click ( getByText ( "increment" ) )
123
125
expect ( promiseFn ) . toHaveBeenCalledTimes ( 2 )
126
+ expect ( abortCtrl . abort ) . toHaveBeenCalledTimes ( 1 )
124
127
fireEvent . click ( getByText ( "increment" ) )
125
128
expect ( promiseFn ) . toHaveBeenCalledTimes ( 3 )
129
+ expect ( abortCtrl . abort ) . toHaveBeenCalledTimes ( 2 )
126
130
} )
127
131
128
- test ( "runs deferFn only when explicitly invoked, passing arguments and props " , ( ) => {
132
+ test ( "runs deferFn only when explicitly invoked, passing arguments, props and AbortController " , ( ) => {
129
133
let counter = 1
130
134
const deferFn = jest . fn ( ) . mockReturnValue ( resolveTo ( ) )
131
135
const { getByText } = render (
@@ -135,21 +139,12 @@ describe("Async", () => {
135
139
} }
136
140
</ Async >
137
141
)
142
+ const props = { deferFn, foo : "bar" }
138
143
expect ( deferFn ) . not . toHaveBeenCalled ( )
139
144
fireEvent . click ( getByText ( "run" ) )
140
- expect ( deferFn ) . toHaveBeenCalledWith (
141
- "go" ,
142
- 1 ,
143
- expect . objectContaining ( { deferFn, foo : "bar" } ) ,
144
- abortController
145
- )
145
+ expect ( deferFn ) . toHaveBeenCalledWith ( "go" , 1 , expect . objectContaining ( props ) , abortCtrl )
146
146
fireEvent . click ( getByText ( "run" ) )
147
- expect ( deferFn ) . toHaveBeenCalledWith (
148
- "go" ,
149
- 2 ,
150
- expect . objectContaining ( { deferFn, foo : "bar" } ) ,
151
- abortController
152
- )
147
+ expect ( deferFn ) . toHaveBeenCalledWith ( "go" , 2 , expect . objectContaining ( props ) , abortCtrl )
153
148
} )
154
149
155
150
test ( "reload uses the arguments of the previous run" , ( ) => {
@@ -169,26 +164,11 @@ describe("Async", () => {
169
164
)
170
165
expect ( deferFn ) . not . toHaveBeenCalled ( )
171
166
fireEvent . click ( getByText ( "run" ) )
172
- expect ( deferFn ) . toHaveBeenCalledWith (
173
- "go" ,
174
- 1 ,
175
- expect . objectContaining ( { deferFn } ) ,
176
- abortController
177
- )
167
+ expect ( deferFn ) . toHaveBeenCalledWith ( "go" , 1 , expect . objectContaining ( { deferFn } ) , abortCtrl )
178
168
fireEvent . click ( getByText ( "run" ) )
179
- expect ( deferFn ) . toHaveBeenCalledWith (
180
- "go" ,
181
- 2 ,
182
- expect . objectContaining ( { deferFn } ) ,
183
- abortController
184
- )
169
+ expect ( deferFn ) . toHaveBeenCalledWith ( "go" , 2 , expect . objectContaining ( { deferFn } ) , abortCtrl )
185
170
fireEvent . click ( getByText ( "reload" ) )
186
- expect ( deferFn ) . toHaveBeenCalledWith (
187
- "go" ,
188
- 2 ,
189
- expect . objectContaining ( { deferFn } ) ,
190
- abortController
191
- )
171
+ expect ( deferFn ) . toHaveBeenCalledWith ( "go" , 2 , expect . objectContaining ( { deferFn } ) , abortCtrl )
192
172
} )
193
173
194
174
test ( "only accepts the last invocation of the promise" , async ( ) => {
@@ -236,6 +216,7 @@ describe("Async", () => {
236
216
unmount ( )
237
217
await Promise . resolve ( )
238
218
expect ( onResolve ) . not . toHaveBeenCalled ( )
219
+ expect ( abortCtrl . abort ) . toHaveBeenCalledTimes ( 1 )
239
220
} )
240
221
241
222
test ( "cancels and restarts the promise when promiseFn changes" , async ( ) => {
@@ -247,6 +228,17 @@ describe("Async", () => {
247
228
await Promise . resolve ( )
248
229
expect ( onResolve ) . not . toHaveBeenCalledWith ( "one" )
249
230
expect ( onResolve ) . toHaveBeenCalledWith ( "two" )
231
+ expect ( abortCtrl . abort ) . toHaveBeenCalledTimes ( 1 )
232
+ } )
233
+
234
+ test ( "cancels the promise when promiseFn is unset" , async ( ) => {
235
+ const promiseFn = jest . fn ( ) . mockReturnValue ( Promise . resolve ( "one" ) )
236
+ const onResolve = jest . fn ( )
237
+ const { rerender } = render ( < Async promiseFn = { promiseFn } onResolve = { onResolve } /> )
238
+ rerender ( < Async onResolve = { onResolve } /> )
239
+ await Promise . resolve ( )
240
+ expect ( onResolve ) . not . toHaveBeenCalledWith ( "one" )
241
+ expect ( abortCtrl . abort ) . toHaveBeenCalledTimes ( 1 )
250
242
} )
251
243
252
244
test ( "does not run promiseFn on mount when initialValue is provided" , ( ) => {
0 commit comments