@@ -8127,6 +8127,256 @@ describe('ReactDOMFizzServer', () => {
8127
8127
expect ( document . body . textContent ) . toBe ( 'HelloWorld' ) ;
8128
8128
} ) ;
8129
8129
8130
+ it ( 'can abort synchronously during render' , async ( ) => {
8131
+ function Sibling ( ) {
8132
+ return < p > sibling</ p > ;
8133
+ }
8134
+
8135
+ function App ( ) {
8136
+ return (
8137
+ < div >
8138
+ < Suspense fallback = { < p > loading 1...</ p > } >
8139
+ < ComponentThatAborts />
8140
+ < Sibling />
8141
+ </ Suspense >
8142
+ < Suspense fallback = { < p > loading 2...</ p > } >
8143
+ < Sibling />
8144
+ </ Suspense >
8145
+ < div >
8146
+ < Suspense fallback = { < p > loading 3...</ p > } >
8147
+ < div >
8148
+ < Sibling />
8149
+ </ div >
8150
+ </ Suspense >
8151
+ </ div >
8152
+ </ div >
8153
+ ) ;
8154
+ }
8155
+
8156
+ const abortRef = { current : null } ;
8157
+ function ComponentThatAborts ( ) {
8158
+ abortRef . current ( ) ;
8159
+ return < p > hello world</ p > ;
8160
+ }
8161
+
8162
+ let finished = false ;
8163
+ await act ( ( ) => {
8164
+ const { pipe, abort} = renderToPipeableStream ( < App /> ) ;
8165
+ abortRef . current = abort ;
8166
+ writable . on ( 'finish' , ( ) => {
8167
+ finished = true ;
8168
+ } ) ;
8169
+ pipe ( writable ) ;
8170
+ } ) ;
8171
+
8172
+ assertConsoleErrorDev ( [
8173
+ 'The render was aborted by the server without a reason.' ,
8174
+ 'The render was aborted by the server without a reason.' ,
8175
+ 'The render was aborted by the server without a reason.' ,
8176
+ ] ) ;
8177
+
8178
+ expect ( finished ) . toBe ( true ) ;
8179
+ expect ( getVisibleChildren ( container ) ) . toEqual (
8180
+ < div >
8181
+ < p > loading 1...</ p >
8182
+ < p > loading 2...</ p >
8183
+ < div >
8184
+ < p > loading 3...</ p >
8185
+ </ div >
8186
+ </ div > ,
8187
+ ) ;
8188
+ } ) ;
8189
+
8190
+ it ( 'can abort during render in a lazy initializer for a component' , async ( ) => {
8191
+ function Sibling ( ) {
8192
+ return < p > sibling</ p > ;
8193
+ }
8194
+
8195
+ function App ( ) {
8196
+ return (
8197
+ < div >
8198
+ < Suspense fallback = { < p > loading 1...</ p > } >
8199
+ < LazyAbort />
8200
+ < Sibling />
8201
+ </ Suspense >
8202
+ < Suspense fallback = { < p > loading 2...</ p > } >
8203
+ < Sibling />
8204
+ </ Suspense >
8205
+ < div >
8206
+ < Suspense fallback = { < p > loading 3...</ p > } >
8207
+ < div >
8208
+ < Sibling />
8209
+ </ div >
8210
+ </ Suspense >
8211
+ </ div >
8212
+ </ div >
8213
+ ) ;
8214
+ }
8215
+
8216
+ const abortRef = { current : null } ;
8217
+ const LazyAbort = React . lazy ( ( ) => {
8218
+ abortRef . current ( ) ;
8219
+ return {
8220
+ then ( cb ) {
8221
+ cb ( { default : 'div' } ) ;
8222
+ } ,
8223
+ } ;
8224
+ } ) ;
8225
+
8226
+ let finished = false ;
8227
+ await act ( ( ) => {
8228
+ const { pipe, abort} = renderToPipeableStream ( < App /> ) ;
8229
+ abortRef . current = abort ;
8230
+ writable . on ( 'finish' , ( ) => {
8231
+ finished = true ;
8232
+ } ) ;
8233
+ pipe ( writable ) ;
8234
+ } ) ;
8235
+
8236
+ assertConsoleErrorDev ( [
8237
+ 'The render was aborted by the server without a reason.' ,
8238
+ 'The render was aborted by the server without a reason.' ,
8239
+ 'The render was aborted by the server without a reason.' ,
8240
+ ] ) ;
8241
+
8242
+ expect ( finished ) . toBe ( true ) ;
8243
+ expect ( getVisibleChildren ( container ) ) . toEqual (
8244
+ < div >
8245
+ < p > loading 1...</ p >
8246
+ < p > loading 2...</ p >
8247
+ < div >
8248
+ < p > loading 3...</ p >
8249
+ </ div >
8250
+ </ div > ,
8251
+ ) ;
8252
+ } ) ;
8253
+
8254
+ it ( 'can abort during render in a lazy initializer for an element' , async ( ) => {
8255
+ function Sibling ( ) {
8256
+ return < p > sibling</ p > ;
8257
+ }
8258
+
8259
+ function App ( ) {
8260
+ return (
8261
+ < div >
8262
+ < Suspense fallback = { < p > loading 1...</ p > } >
8263
+ { lazyAbort }
8264
+ < Sibling />
8265
+ </ Suspense >
8266
+ < Suspense fallback = { < p > loading 2...</ p > } >
8267
+ < Sibling />
8268
+ </ Suspense >
8269
+ < div >
8270
+ < Suspense fallback = { < p > loading 3...</ p > } >
8271
+ < div >
8272
+ < Sibling />
8273
+ </ div >
8274
+ </ Suspense >
8275
+ </ div >
8276
+ </ div >
8277
+ ) ;
8278
+ }
8279
+
8280
+ const abortRef = { current : null } ;
8281
+ const lazyAbort = React . lazy ( ( ) => {
8282
+ abortRef . current ( ) ;
8283
+ return {
8284
+ then ( cb ) {
8285
+ cb ( { default : 'hello world' } ) ;
8286
+ } ,
8287
+ } ;
8288
+ } ) ;
8289
+
8290
+ let finished = false ;
8291
+ await act ( ( ) => {
8292
+ const { pipe, abort} = renderToPipeableStream ( < App /> ) ;
8293
+ abortRef . current = abort ;
8294
+ writable . on ( 'finish' , ( ) => {
8295
+ finished = true ;
8296
+ } ) ;
8297
+ pipe ( writable ) ;
8298
+ } ) ;
8299
+
8300
+ assertConsoleErrorDev ( [
8301
+ 'The render was aborted by the server without a reason.' ,
8302
+ 'The render was aborted by the server without a reason.' ,
8303
+ 'The render was aborted by the server without a reason.' ,
8304
+ ] ) ;
8305
+
8306
+ expect ( finished ) . toBe ( true ) ;
8307
+ expect ( getVisibleChildren ( container ) ) . toEqual (
8308
+ < div >
8309
+ < p > loading 1...</ p >
8310
+ < p > loading 2...</ p >
8311
+ < div >
8312
+ < p > loading 3...</ p >
8313
+ </ div >
8314
+ </ div > ,
8315
+ ) ;
8316
+ } ) ;
8317
+
8318
+ it ( 'can abort during a synchronous thenable resolution' , async ( ) => {
8319
+ function Sibling ( ) {
8320
+ return < p > sibling</ p > ;
8321
+ }
8322
+
8323
+ function App ( ) {
8324
+ return (
8325
+ < div >
8326
+ < Suspense fallback = { < p > loading 1...</ p > } >
8327
+ { thenable }
8328
+ < Sibling />
8329
+ </ Suspense >
8330
+ < Suspense fallback = { < p > loading 2...</ p > } >
8331
+ < Sibling />
8332
+ </ Suspense >
8333
+ < div >
8334
+ < Suspense fallback = { < p > loading 3...</ p > } >
8335
+ < div >
8336
+ < Sibling />
8337
+ </ div >
8338
+ </ Suspense >
8339
+ </ div >
8340
+ </ div >
8341
+ ) ;
8342
+ }
8343
+
8344
+ const abortRef = { current : null } ;
8345
+ const thenable = {
8346
+ then ( cb ) {
8347
+ abortRef . current ( ) ;
8348
+ cb ( thenable . value ) ;
8349
+ } ,
8350
+ } ;
8351
+
8352
+ let finished = false ;
8353
+ await act ( ( ) => {
8354
+ const { pipe, abort} = renderToPipeableStream ( < App /> ) ;
8355
+ abortRef . current = abort ;
8356
+ writable . on ( 'finish' , ( ) => {
8357
+ finished = true ;
8358
+ } ) ;
8359
+ pipe ( writable ) ;
8360
+ } ) ;
8361
+
8362
+ assertConsoleErrorDev ( [
8363
+ 'The render was aborted by the server without a reason.' ,
8364
+ 'The render was aborted by the server without a reason.' ,
8365
+ 'The render was aborted by the server without a reason.' ,
8366
+ ] ) ;
8367
+
8368
+ expect ( finished ) . toBe ( true ) ;
8369
+ expect ( getVisibleChildren ( container ) ) . toEqual (
8370
+ < div >
8371
+ < p > loading 1...</ p >
8372
+ < p > loading 2...</ p >
8373
+ < div >
8374
+ < p > loading 3...</ p >
8375
+ </ div >
8376
+ </ div > ,
8377
+ ) ;
8378
+ } ) ;
8379
+
8130
8380
it ( 'should warn for using generators as children props' , async ( ) => {
8131
8381
function * getChildren ( ) {
8132
8382
yield < h1 key = "1" > Hello</ h1 > ;
0 commit comments