@@ -2294,4 +2294,51 @@ describe('ReactSuspenseWithNoopRenderer', () => {
22942294 expect ( ReactNoop . getChildren ( ) ) . toEqual ( [ span ( 'D' ) ] ) ;
22952295 } ) ;
22962296 } ) ;
2297+
2298+ it ( "suspended commit remains suspended even if there's another update at same expiration" , async ( ) => {
2299+ // Regression test
2300+ function App ( { text} ) {
2301+ return (
2302+ < Suspense fallback = "Outer fallback" >
2303+ < AsyncText ms = { 2000 } text = { text } />
2304+ </ Suspense >
2305+ ) ;
2306+ }
2307+
2308+ const root = ReactNoop . createRoot ( ) ;
2309+ await ReactNoop . act ( async ( ) => {
2310+ root . render ( < App text = "Initial" /> ) ;
2311+ } ) ;
2312+
2313+ // Resolve initial render
2314+ await ReactNoop . act ( async ( ) => {
2315+ Scheduler . advanceTime ( 2000 ) ;
2316+ await advanceTimers ( 2000 ) ;
2317+ } ) ;
2318+ expect ( Scheduler ) . toHaveYielded ( [
2319+ 'Suspend! [Initial]' ,
2320+ 'Promise resolved [Initial]' ,
2321+ 'Initial' ,
2322+ ] ) ;
2323+ expect ( root ) . toMatchRenderedOutput ( < span prop = "Initial" /> ) ;
2324+
2325+ // Suspend B. Since showing a fallback would hide content that's already
2326+ // visible, it should suspend for a bit without committing.
2327+ await ReactNoop . act ( async ( ) => {
2328+ root . render ( < App text = "First update" /> ) ;
2329+
2330+ expect ( Scheduler ) . toFlushAndYield ( [ 'Suspend! [First update]' ] ) ;
2331+ // Should not display a fallback
2332+ expect ( root ) . toMatchRenderedOutput ( < span prop = "Initial" /> ) ;
2333+ } ) ;
2334+
2335+ // Suspend A. This should also suspend for a JND.
2336+ await ReactNoop . act ( async ( ) => {
2337+ root . render ( < App text = "Second update" /> ) ;
2338+
2339+ expect ( Scheduler ) . toFlushAndYield ( [ 'Suspend! [Second update]' ] ) ;
2340+ // Should not display a fallback
2341+ expect ( root ) . toMatchRenderedOutput ( < span prop = "Initial" /> ) ;
2342+ } ) ;
2343+ } ) ;
22972344} ) ;
0 commit comments