act() tests - Reuse and properly unmount containers (#14974)
Philipp Spiess committed
Apr 13, 2019 at 00:53 UTC
a30e7d992e04caeb90be89cad3cdb60eeb2d7ba7
1 file changed
+34
-11
packages/react-dom/src/__tests__/ReactTestUtilsAct-test.js
+34
-11
@@ -11,6 +11,7 @@ let React;
11
let ReactDOM;
12
let ReactTestUtils;
13
let act;
14
+let container;
15
16
jest.useRealTimers();
17
@@ -29,6 +30,12 @@ describe('ReactTestUtils.act()', () => {
30
ReactDOM = require('react-dom');
31
ReactTestUtils = require('react-dom/test-utils');
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);
39
});
40
41
describe('sync', () => {
@@ -66,9 +73,6 @@ describe('ReactTestUtils.act()', () => {
73
);
74
}
75
69
- const container = document.createElement('div');
70
- // attach to body so events works
71
- document.body.appendChild(container);
76
let calledCounter = 0;
77
act(() => {
78
ReactDOM.render(
@@ -96,8 +100,6 @@ describe('ReactTestUtils.act()', () => {
100
act(click);
101
expect(calledCounter).toBe(5);
102
expect(button.innerHTML).toBe('5');
99
-
100
- document.body.removeChild(container);
103
});
104
105
it('should flush effects recursively', () => {
@@ -111,7 +113,6 @@ describe('ReactTestUtils.act()', () => {
113
return ctr;
114
}
115
114
- const container = document.createElement('div');
116
act(() => {
117
ReactDOM.render(<App />, container);
118
});
@@ -130,8 +131,6 @@ describe('ReactTestUtils.act()', () => {
131
</button>
132
);
133
}
133
- const container = document.createElement('div');
134
- document.body.appendChild(container);
134
let button;
135
act(() => {
136
ReactDOM.render(<App />, container);
@@ -142,7 +141,6 @@ describe('ReactTestUtils.act()', () => {
141
expect(() => setValue(1)).toWarnDev([
142
'An update to App inside a test was not wrapped in act(...).',
143
]);
145
- document.body.removeChild(container);
144
});
145
describe('fake timers', () => {
146
beforeEach(() => {
@@ -162,7 +160,6 @@ describe('ReactTestUtils.act()', () => {
160
}, []);
161
return toggle;
162
}
165
- const container = document.createElement('div');
163
164
act(() => {
165
ReactDOM.render(<App />, container);
@@ -184,7 +181,6 @@ describe('ReactTestUtils.act()', () => {
181
}, []);
182
return toggle;
183
}
187
- const container = document.createElement('div');
184
185
act(() => {
186
ReactDOM.render(<App />, container);
@@ -220,6 +216,33 @@ describe('ReactTestUtils.act()', () => {
216
// all 5 ticks present and accounted for
217
expect(el.innerHTML).toBe('5');
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
+ });
246
});
247
248
it('warns if you return a value inside act', () => {