@@ -72,6 +72,33 @@ describe('ReactTestUtils.act()', () => {
7272
7373 runActTests ( 'legacy mode' , renderLegacy , unmountLegacy , rerenderLegacy ) ;
7474
75+ // and then in blocking mode
76+ if ( __EXPERIMENTAL__ ) {
77+ let blockingRoot = null ;
78+ const renderBatched = ( el , dom ) => {
79+ blockingRoot = ReactDOM . unstable_createBlockingRoot ( dom ) ;
80+ blockingRoot . render ( el ) ;
81+ } ;
82+
83+ const unmountBatched = dom => {
84+ if ( blockingRoot !== null ) {
85+ blockingRoot . unmount ( ) ;
86+ blockingRoot = null ;
87+ }
88+ } ;
89+
90+ const rerenderBatched = el => {
91+ blockingRoot . render ( el ) ;
92+ } ;
93+
94+ runActTests (
95+ 'blocking mode' ,
96+ renderBatched ,
97+ unmountBatched ,
98+ rerenderBatched ,
99+ ) ;
100+ }
101+
75102 describe ( 'unacted effects' , ( ) => {
76103 function App ( ) {
77104 React . useEffect ( ( ) => { } , [ ] ) ;
@@ -97,6 +124,19 @@ describe('ReactTestUtils.act()', () => {
97124 ] ) ;
98125 } ) ;
99126
127+ // @gate experimental
128+ it ( 'warns in blocking mode' , ( ) => {
129+ expect ( ( ) => {
130+ const root = ReactDOM . unstable_createBlockingRoot (
131+ document . createElement ( 'div' ) ,
132+ ) ;
133+ root . render ( < App /> ) ;
134+ Scheduler . unstable_flushAll ( ) ;
135+ } ) . toErrorDev ( [
136+ 'An update to App ran an effect, but was not wrapped in act(...)' ,
137+ ] ) ;
138+ } ) ;
139+
100140 // @gate experimental
101141 it ( 'warns in concurrent mode' , ( ) => {
102142 expect ( ( ) => {
@@ -691,10 +731,14 @@ function runActTests(label, render, unmount, rerender) {
691731
692732 it ( 'triggers fallbacks if available' , async ( ) => {
693733 if ( label !== 'legacy mode' ) {
694- // FIXME: Support for Concurrent Root intentionally removed
695- // from the public version of `act`. It will be added back in
696- // a future major version, Concurrent Root officially released.
697- // Consider skipping all non-Legacy tests in this suite until then.
734+ // FIXME: Support for Blocking* and Concurrent Mode were
735+ // intentionally removed from the public version of `act`. It will
736+ // be added back in a future major version, before Blocking and and
737+ // Concurrent Mode are officially released. Consider disabling all
738+ // non-Legacy tests in this suite until then.
739+ //
740+ // *Blocking Mode actually does happen to work, though
741+ // not "officially" since it's an unreleased feature.
698742 return ;
699743 }
700744
@@ -750,8 +794,10 @@ function runActTests(label, render, unmount, rerender) {
750794 // In Concurrent Mode, refresh transitions delay indefinitely.
751795 expect ( document . querySelector ( '[data-test-id=spinner]' ) ) . toBeNull ( ) ;
752796 } else {
753- // In Legacy Mode, all fallbacks are forced to display,
754- // even during a refresh transition.
797+ // In Legacy Mode and Blocking Mode, all fallbacks are forced to
798+ // display, even during a refresh transition.
799+ // TODO: Consider delaying indefinitely in Blocking Mode, to match
800+ // Concurrent Mode semantics.
755801 expect (
756802 document . querySelector ( '[data-test-id=spinner]' ) ,
757803 ) . not . toBeNull ( ) ;
0 commit comments