@@ -17,7 +17,7 @@ let React;
17
17
let ReactDOMFizzServer ;
18
18
let Suspense ;
19
19
20
- describe ( 'ReactDOMFizzServer ' , ( ) => {
20
+ describe ( 'ReactDOMFizzServerBrowser ' , ( ) => {
21
21
beforeEach ( ( ) => {
22
22
jest . resetModules ( ) ;
23
23
React = require ( 'react' ) ;
@@ -209,6 +209,113 @@ describe('ReactDOMFizzServer', () => {
209
209
] ) ;
210
210
} ) ;
211
211
212
+ it ( 'should reject if aborting before the shell is complete' , async ( ) => {
213
+ const errors = [ ] ;
214
+ const controller = new AbortController ( ) ;
215
+ const promise = ReactDOMFizzServer . renderToReadableStream (
216
+ < div >
217
+ < InfiniteSuspend />
218
+ </ div > ,
219
+ {
220
+ signal : controller . signal ,
221
+ onError ( x ) {
222
+ errors . push ( x . message ) ;
223
+ } ,
224
+ } ,
225
+ ) ;
226
+
227
+ await jest . runAllTimers ( ) ;
228
+
229
+ const theReason = new Error ( 'aborted for reasons' ) ;
230
+ // @TODO this is a hack to work around lack of support for abortSignal.reason in node
231
+ // The abort call itself should set this property but since we are testing in node we
232
+ // set it here manually
233
+ controller . signal . reason = theReason ;
234
+ controller . abort ( theReason ) ;
235
+
236
+ let caughtError = null ;
237
+ try {
238
+ await promise ;
239
+ } catch ( error ) {
240
+ caughtError = error ;
241
+ }
242
+ expect ( caughtError ) . toBe ( theReason ) ;
243
+ expect ( errors ) . toEqual ( [ 'aborted for reasons' ] ) ;
244
+ } ) ;
245
+
246
+ it ( 'should be able to abort before something suspends' , async ( ) => {
247
+ const errors = [ ] ;
248
+ const controller = new AbortController ( ) ;
249
+ function App ( ) {
250
+ controller . abort ( ) ;
251
+ return (
252
+ < Suspense fallback = { < div > Loading</ div > } >
253
+ < InfiniteSuspend />
254
+ </ Suspense >
255
+ ) ;
256
+ }
257
+ const streamPromise = ReactDOMFizzServer . renderToReadableStream (
258
+ < div >
259
+ < App />
260
+ </ div > ,
261
+ {
262
+ signal : controller . signal ,
263
+ onError ( x ) {
264
+ errors . push ( x . message ) ;
265
+ } ,
266
+ } ,
267
+ ) ;
268
+
269
+ let caughtError = null ;
270
+ try {
271
+ await streamPromise ;
272
+ } catch ( error ) {
273
+ caughtError = error ;
274
+ }
275
+ expect ( caughtError . message ) . toBe (
276
+ 'The render was aborted by the server without a reason.' ,
277
+ ) ;
278
+ expect ( errors ) . toEqual ( [
279
+ 'The render was aborted by the server without a reason.' ,
280
+ ] ) ;
281
+ } ) ;
282
+
283
+ it ( 'should reject if passing an already aborted signal' , async ( ) => {
284
+ const errors = [ ] ;
285
+ const controller = new AbortController ( ) ;
286
+ const theReason = new Error ( 'aborted for reasons' ) ;
287
+ // @TODO this is a hack to work around lack of support for abortSignal.reason in node
288
+ // The abort call itself should set this property but since we are testing in node we
289
+ // set it here manually
290
+ controller . signal . reason = theReason ;
291
+ controller . abort ( theReason ) ;
292
+
293
+ const promise = ReactDOMFizzServer . renderToReadableStream (
294
+ < div >
295
+ < Suspense fallback = { < div > Loading</ div > } >
296
+ < InfiniteSuspend />
297
+ </ Suspense >
298
+ </ div > ,
299
+ {
300
+ signal : controller . signal ,
301
+ onError ( x ) {
302
+ errors . push ( x . message ) ;
303
+ } ,
304
+ } ,
305
+ ) ;
306
+
307
+ // Technically we could still continue rendering the shell but currently the
308
+ // semantics mean that we also abort any pending CPU work.
309
+ let caughtError = null ;
310
+ try {
311
+ await promise ;
312
+ } catch ( error ) {
313
+ caughtError = error ;
314
+ }
315
+ expect ( caughtError ) . toBe ( theReason ) ;
316
+ expect ( errors ) . toEqual ( [ 'aborted for reasons' ] ) ;
317
+ } ) ;
318
+
212
319
it ( 'should not continue rendering after the reader cancels' , async ( ) => {
213
320
let hasLoaded = false ;
214
321
let resolve ;
@@ -226,7 +333,7 @@ describe('ReactDOMFizzServer', () => {
226
333
const stream = await ReactDOMFizzServer . renderToReadableStream (
227
334
< div >
228
335
< Suspense fallback = { < div > Loading</ div > } >
229
- < Wait /> / >
336
+ < Wait />
230
337
</ Suspense >
231
338
</ div > ,
232
339
{
@@ -296,7 +403,7 @@ describe('ReactDOMFizzServer', () => {
296
403
expect ( result ) . toMatchInlineSnapshot ( `"<div>${ str2049 } </div>"` ) ;
297
404
} ) ;
298
405
299
- it ( 'Supports custom abort reasons with a string' , async ( ) => {
406
+ it ( 'supports custom abort reasons with a string' , async ( ) => {
300
407
const promise = new Promise ( r => { } ) ;
301
408
function Wait ( ) {
302
409
throw promise ;
@@ -337,7 +444,7 @@ describe('ReactDOMFizzServer', () => {
337
444
expect ( errors ) . toEqual ( [ 'foobar' , 'foobar' ] ) ;
338
445
} ) ;
339
446
340
- it ( 'Supports custom abort reasons with an Error' , async ( ) => {
447
+ it ( 'supports custom abort reasons with an Error' , async ( ) => {
341
448
const promise = new Promise ( r => { } ) ;
342
449
function Wait ( ) {
343
450
throw promise ;
0 commit comments