@@ -11,6 +11,7 @@ let React;
11
11
let ReactDOM ;
12
12
let ReactTestUtils ;
13
13
let act ;
14
+ let container ;
14
15
15
16
jest . useRealTimers ( ) ;
16
17
@@ -29,6 +30,12 @@ describe('ReactTestUtils.act()', () => {
29
30
ReactDOM = require ( 'react-dom' ) ;
30
31
ReactTestUtils = require ( 'react-dom/test-utils' ) ;
31
32
act = ReactTestUtils . act ;
33
+ container = document . createElement ( 'div' ) ;
34
+ document . body . appendChild ( container ) ;
35
+ } ) ;
36
+ afterEach ( ( ) => {
37
+ ReactDOM . unmountComponentAtNode ( container ) ;
38
+ document . body . removeChild ( container ) ;
32
39
} ) ;
33
40
34
41
describe ( 'sync' , ( ) => {
@@ -66,9 +73,6 @@ describe('ReactTestUtils.act()', () => {
66
73
) ;
67
74
}
68
75
69
- const container = document . createElement ( 'div' ) ;
70
- // attach to body so events works
71
- document . body . appendChild ( container ) ;
72
76
let calledCounter = 0 ;
73
77
act ( ( ) => {
74
78
ReactDOM . render (
@@ -96,8 +100,6 @@ describe('ReactTestUtils.act()', () => {
96
100
act ( click ) ;
97
101
expect ( calledCounter ) . toBe ( 5 ) ;
98
102
expect ( button . innerHTML ) . toBe ( '5' ) ;
99
-
100
- document . body . removeChild ( container ) ;
101
103
} ) ;
102
104
103
105
it ( 'should flush effects recursively' , ( ) => {
@@ -111,7 +113,6 @@ describe('ReactTestUtils.act()', () => {
111
113
return ctr ;
112
114
}
113
115
114
- const container = document . createElement ( 'div' ) ;
115
116
act ( ( ) => {
116
117
ReactDOM . render ( < App /> , container ) ;
117
118
} ) ;
@@ -130,8 +131,6 @@ describe('ReactTestUtils.act()', () => {
130
131
</ button >
131
132
) ;
132
133
}
133
- const container = document . createElement ( 'div' ) ;
134
- document . body . appendChild ( container ) ;
135
134
let button ;
136
135
act ( ( ) => {
137
136
ReactDOM . render ( < App /> , container ) ;
@@ -142,7 +141,6 @@ describe('ReactTestUtils.act()', () => {
142
141
expect ( ( ) => setValue ( 1 ) ) . toWarnDev ( [
143
142
'An update to App inside a test was not wrapped in act(...).' ,
144
143
] ) ;
145
- document . body . removeChild ( container ) ;
146
144
} ) ;
147
145
describe ( 'fake timers' , ( ) => {
148
146
beforeEach ( ( ) => {
@@ -162,7 +160,6 @@ describe('ReactTestUtils.act()', () => {
162
160
} , [ ] ) ;
163
161
return toggle ;
164
162
}
165
- const container = document . createElement ( 'div' ) ;
166
163
167
164
act ( ( ) => {
168
165
ReactDOM . render ( < App /> , container ) ;
@@ -184,7 +181,6 @@ describe('ReactTestUtils.act()', () => {
184
181
} , [ ] ) ;
185
182
return toggle ;
186
183
}
187
- const container = document . createElement ( 'div' ) ;
188
184
189
185
act ( ( ) => {
190
186
ReactDOM . render ( < App /> , container ) ;
@@ -220,6 +216,33 @@ describe('ReactTestUtils.act()', () => {
220
216
// all 5 ticks present and accounted for
221
217
expect ( el . innerHTML ) . toBe ( '5' ) ;
222
218
} ) ;
219
+ it ( 'flushes immediate re-renders with act' , ( ) => {
220
+ function App ( ) {
221
+ let [ ctr , setCtr ] = React . useState ( 0 ) ;
222
+ React . useEffect ( ( ) => {
223
+ if ( ctr === 0 ) {
224
+ setCtr ( 1 ) ;
225
+ }
226
+ const timeout = setTimeout ( ( ) => setCtr ( 2 ) , 1000 ) ;
227
+ return ( ) => clearTimeout ( timeout ) ;
228
+ } ) ;
229
+ return ctr ;
230
+ }
231
+
232
+ act ( ( ) => {
233
+ ReactDOM . render ( < App /> , container ) ;
234
+ // Since the effects won't be flushed yet, this does not advance the timer
235
+ jest . runAllTimers ( ) ;
236
+ } ) ;
237
+
238
+ expect ( container . innerHTML ) . toBe ( '1' ) ;
239
+
240
+ act ( ( ) => {
241
+ jest . runAllTimers ( ) ;
242
+ } ) ;
243
+
244
+ expect ( container . innerHTML ) . toBe ( '2' ) ;
245
+ } ) ;
223
246
} ) ;
224
247
225
248
it ( 'warns if you return a value inside act' , ( ) => {
0 commit comments