Convert ReactFreshIntegration-test to createRoot (#28073)
Convert ReactFreshIntegration-test to createRoot
Jan Kassens committed
Jan 25, 2024 at 15:07 UTC
772475457354c7c417bee4caf15311d28c9b3a2c
1 file changed
+175
-174
packages/react-refresh/src/__tests__/ReactFreshIntegration-test.js
+175
-174
@@ -12,9 +12,11 @@
12
'use strict';
13
14
let React;
15
-let ReactDOM;
15
+let ReactDOMClient;
16
let ReactFreshRuntime;
17
+let Scheduler;
18
let act;
19
+let assertLog;
20
21
const babel = require('@babel/core');
22
const freshPlugin = require('react-refresh/babel');
@@ -22,6 +24,7 @@ const ts = require('typescript');
24
25
describe('ReactFreshIntegration', () => {
26
let container;
27
+ let root;
28
let exportsObj;
29
30
beforeEach(() => {
@@ -30,17 +33,19 @@ describe('ReactFreshIntegration', () => {
33
React = require('react');
34
ReactFreshRuntime = require('react-refresh/runtime');
35
ReactFreshRuntime.injectIntoGlobalHook(global);
33
- ReactDOM = require('react-dom');
34
- act = React.unstable_act;
36
+ ReactDOMClient = require('react-dom/client');
37
+ Scheduler = require('scheduler/unstable_mock');
38
+ ({act, assertLog} = require('internal-test-utils'));
39
container = document.createElement('div');
40
document.body.appendChild(container);
41
+ root = ReactDOMClient.createRoot(container);
42
exportsObj = undefined;
43
}
44
});
45
46
afterEach(() => {
47
if (__DEV__) {
43
- ReactDOM.unmountComponentAtNode(container);
48
+ root.unmount();
49
// Ensure we don't leak memory by holding onto dead roots.
50
expect(ReactFreshRuntime._getMountedRootCount()).toBe(0);
51
document.body.removeChild(container);
@@ -82,11 +87,12 @@ describe('ReactFreshIntegration', () => {
87
new Function(
88
'global',
89
'React',
90
+ 'Scheduler',
91
'exports',
92
'$RefreshReg$',
93
'$RefreshSig$',
94
compiled,
89
- )(global, React, exportsObj, $RefreshReg$, $RefreshSig$);
95
+ )(global, React, Scheduler, exportsObj, $RefreshReg$, $RefreshSig$);
96
// Module systems will register exports as a fallback.
97
// This is useful for cases when e.g. a class is exported,
98
// and we don't want to propagate the update beyond this module.
@@ -115,16 +121,16 @@ describe('ReactFreshIntegration', () => {
121
],
122
['TypeScript syntax', executeTypescript, testTypeScript],
123
])('%s', (language, execute, test) => {
118
- function render(source) {
124
+ async function render(source) {
125
const Component = execute(source);
120
- act(() => {
121
- ReactDOM.render(<Component />, container);
126
+ await act(() => {
127
+ root.render(<Component />);
128
});
129
// Module initialization shouldn't be counted as a hot update.
130
expect(ReactFreshRuntime.performReactRefresh()).toBe(null);
131
}
132
127
- function patch(source) {
133
+ async function patch(source) {
134
const prevExports = exportsObj;
135
execute(source);
136
const nextExports = exportsObj;
@@ -142,11 +148,11 @@ describe('ReactFreshIntegration', () => {
148
// This makes adding/removing/renaming exports re-render references to them.
149
// Here, we'll just force a re-render using the newer type to emulate this.
150
const NextComponent = nextExports.default;
145
- act(() => {
146
- ReactDOM.render(<NextComponent />, container);
151
+ await act(() => {
152
+ root.render(<NextComponent />);
153
});
154
}
149
- act(() => {
155
+ await act(() => {
156
const result = ReactFreshRuntime.performReactRefresh();
157
if (!didExportsChange) {
158
// Normally we expect that some components got updated in our tests.
@@ -164,9 +170,9 @@ describe('ReactFreshIntegration', () => {
170
});
171
172
function testJavaScript(render, patch) {
167
- it('reloads function declarations', () => {
173
+ it('reloads function declarations', async () => {
174
if (__DEV__) {
169
- render(`
175
+ await render(`
176
function Parent() {
177
return <Child prop="A" />;
178
};
@@ -179,7 +185,7 @@ describe('ReactFreshIntegration', () => {
185
`);
186
const el = container.firstChild;
187
expect(el.textContent).toBe('A1');
182
- patch(`
188
+ await patch(`
189
function Parent() {
190
return <Child prop="B" />;
191
};
@@ -195,9 +201,9 @@ describe('ReactFreshIntegration', () => {
201
}
202
});
203
198
- it('reloads arrow functions', () => {
204
+ it('reloads arrow functions', async () => {
205
if (__DEV__) {
200
- render(`
206
+ await render(`
207
const Parent = () => {
208
return <Child prop="A" />;
209
};
@@ -210,7 +216,7 @@ describe('ReactFreshIntegration', () => {
216
`);
217
const el = container.firstChild;
218
expect(el.textContent).toBe('A1');
213
- patch(`
219
+ await patch(`
220
const Parent = () => {
221
return <Child prop="B" />;
222
};
@@ -226,9 +232,9 @@ describe('ReactFreshIntegration', () => {
232
}
233
});
234
229
- it('reloads a combination of memo and forwardRef', () => {
235
+ it('reloads a combination of memo and forwardRef', async () => {
236
if (__DEV__) {
231
- render(`
237
+ await render(`
238
const {memo} = React;
239
240
const Parent = memo(React.forwardRef(function (props, ref) {
@@ -243,7 +249,7 @@ describe('ReactFreshIntegration', () => {
249
`);
250
const el = container.firstChild;
251
expect(el.textContent).toBe('A1');
246
- patch(`
252
+ await patch(`
253
const {memo} = React;
254
255
const Parent = memo(React.forwardRef(function (props, ref) {
@@ -261,9 +267,9 @@ describe('ReactFreshIntegration', () => {
267
}
268
});
269
264
- it('reloads default export with named memo', () => {
270
+ it('reloads default export with named memo', async () => {
271
if (__DEV__) {
266
- render(`
272
+ await render(`
273
const {memo} = React;
274
275
const Child = React.memo(({prop}) => {
@@ -276,7 +282,7 @@ describe('ReactFreshIntegration', () => {
282
`);
283
const el = container.firstChild;
284
expect(el.textContent).toBe('A1');
279
- patch(`
285
+ await patch(`
286
const {memo} = React;
287
288
const Child = React.memo(({prop}) => {
@@ -292,9 +298,9 @@ describe('ReactFreshIntegration', () => {
298
}
299
});
300
295
- it('reloads HOCs if they return functions', () => {
301
+ it('reloads HOCs if they return functions', async () => {
302
if (__DEV__) {
297
- render(`
303
+ await render(`
304
function hoc(letter) {
305
return function() {
306
return <h1>{letter}1</h1>;
@@ -309,7 +315,7 @@ describe('ReactFreshIntegration', () => {
315
`);
316
const el = container.firstChild;
317
expect(el.textContent).toBe('A1');
312
- patch(`
318
+ await patch(`
319
function hoc(letter) {
320
return function() {
321
return <h1>{letter}2</h1>;
@@ -327,9 +333,9 @@ describe('ReactFreshIntegration', () => {
333
}
334
});
335
330
- it('resets state when renaming a state variable', () => {
336
+ it('resets state when renaming a state variable', async () => {
337
if (__DEV__) {
332
- render(`
338
+ await render(`
339
const {useState} = React;
340
const S = 1;
341
@@ -341,7 +347,7 @@ describe('ReactFreshIntegration', () => {
347
const el = container.firstChild;
348
expect(el.textContent).toBe('A1');
349
344
- patch(`
350
+ await patch(`
351
const {useState} = React;
352
const S = 2;
353
@@ -354,7 +360,7 @@ describe('ReactFreshIntegration', () => {
360
expect(container.firstChild).toBe(el);
361
expect(el.textContent).toBe('B1');
362
357
- patch(`
363
+ await patch(`
364
const {useState} = React;
365
const S = 3;
366
@@ -370,9 +376,9 @@ describe('ReactFreshIntegration', () => {
376
}
377
});
378
373
- it('resets state when renaming a state variable in a HOC', () => {
379
+ it('resets state when renaming a state variable in a HOC', async () => {
380
if (__DEV__) {
375
- render(`
381
+ await render(`
382
const {useState} = React;
383
const S = 1;
384
@@ -390,7 +396,7 @@ describe('ReactFreshIntegration', () => {
396
const el = container.firstChild;
397
expect(el.textContent).toBe('A1');
398
393
- patch(`
399
+ await patch(`
400
const {useState} = React;
401
const S = 2;
402
@@ -409,7 +415,7 @@ describe('ReactFreshIntegration', () => {
415
expect(container.firstChild).toBe(el);
416
expect(el.textContent).toBe('B1');
417
412
- patch(`
418
+ await patch(`
419
const {useState} = React;
420
const S = 3;
421
@@ -431,9 +437,9 @@ describe('ReactFreshIntegration', () => {
437
}
438
});
439
434
- it('resets state when renaming a state variable in a HOC with indirection', () => {
440
+ it('resets state when renaming a state variable in a HOC with indirection', async () => {
441
if (__DEV__) {
436
- render(`
442
+ await render(`
443
const {useState} = React;
444
const S = 1;
445
@@ -453,7 +459,7 @@ describe('ReactFreshIntegration', () => {
459
const el = container.firstChild;
460
expect(el.textContent).toBe('A1');
461
456
- patch(`
462
+ await patch(`
463
const {useState} = React;
464
const S = 2;
465
@@ -474,7 +480,7 @@ describe('ReactFreshIntegration', () => {
480
expect(container.firstChild).toBe(el);
481
expect(el.textContent).toBe('B1');
482
477
- patch(`
483
+ await patch(`
484
const {useState} = React;
485
const S = 3;
486
@@ -498,9 +504,9 @@ describe('ReactFreshIntegration', () => {
504
}
505
});
506
501
- it('resets state when renaming a state variable inside a HOC with direct call', () => {
507
+ it('resets state when renaming a state variable inside a HOC with direct call', async () => {
508
if (__DEV__) {
503
- render(`
509
+ await render(`
510
const {useState} = React;
511
const S = 1;
512
@@ -518,7 +524,7 @@ describe('ReactFreshIntegration', () => {
524
const el = container.firstChild;
525
expect(el.textContent).toBe('A1');
526
521
- patch(`
527
+ await patch(`
528
const {useState} = React;
529
const S = 2;
530
@@ -537,7 +543,7 @@ describe('ReactFreshIntegration', () => {
543
expect(container.firstChild).toBe(el);
544
expect(el.textContent).toBe('B1');
545
540
- patch(`
546
+ await patch(`
547
const {useState} = React;
548
const S = 3;
549
@@ -559,9 +565,9 @@ describe('ReactFreshIntegration', () => {
565
}
566
});
567
562
- it('does not crash when changing Hook order inside a HOC with direct call', () => {
568
+ it('does not crash when changing Hook order inside a HOC with direct call', async () => {
569
if (__DEV__) {
564
- render(`
570
+ await render(`
571
const {useEffect} = React;
572
573
function hocWithDirectCall(Wrapped) {
@@ -578,7 +584,7 @@ describe('ReactFreshIntegration', () => {
584
const el = container.firstChild;
585
expect(el.textContent).toBe('A');
586
581
- patch(`
587
+ await patch(`
588
const {useEffect} = React;
589
590
function hocWithDirectCall(Wrapped) {
@@ -600,9 +606,9 @@ describe('ReactFreshIntegration', () => {
606
}
607
});
608
603
- it('does not crash when changing Hook order inside a memo-ed HOC with direct call', () => {
609
+ it('does not crash when changing Hook order inside a memo-ed HOC with direct call', async () => {
610
if (__DEV__) {
605
- render(`
611
+ await render(`
612
const {useEffect, memo} = React;
613
614
function hocWithDirectCall(Wrapped) {
@@ -619,7 +625,7 @@ describe('ReactFreshIntegration', () => {
625
const el = container.firstChild;
626
expect(el.textContent).toBe('A');
627
622
- patch(`
628
+ await patch(`
629
const {useEffect, memo} = React;
630
631
function hocWithDirectCall(Wrapped) {
@@ -641,9 +647,9 @@ describe('ReactFreshIntegration', () => {
647
}
648
});
649
644
- it('does not crash when changing Hook order inside a memo+forwardRef-ed HOC with direct call', () => {
650
+ it('does not crash when changing Hook order inside a memo+forwardRef-ed HOC with direct call', async () => {
651
if (__DEV__) {
646
- render(`
652
+ await render(`
653
const {useEffect, memo, forwardRef} = React;
654
655
function hocWithDirectCall(Wrapped) {
@@ -660,7 +666,7 @@ describe('ReactFreshIntegration', () => {
666
const el = container.firstChild;
667
expect(el.textContent).toBe('A');
668
663
- patch(`
669
+ await patch(`
670
const {useEffect, memo, forwardRef} = React;
671
672
function hocWithDirectCall(Wrapped) {
@@ -682,9 +688,9 @@ describe('ReactFreshIntegration', () => {
688
}
689
});
690
685
- it('does not crash when changing Hook order inside a HOC returning an object', () => {
691
+ it('does not crash when changing Hook order inside a HOC returning an object', async () => {
692
if (__DEV__) {
687
- render(`
693
+ await render(`
694
const {useEffect} = React;
695
696
function hocWithDirectCall(Wrapped) {
@@ -699,7 +705,7 @@ describe('ReactFreshIntegration', () => {
705
const el = container.firstChild;
706
expect(el.textContent).toBe('A');
707
702
- patch(`
708
+ await patch(`
709
const {useEffect} = React;
710
711
function hocWithDirectCall(Wrapped) {
@@ -719,9 +725,9 @@ describe('ReactFreshIntegration', () => {
725
}
726
});
727
722
- it('resets effects while preserving state', () => {
728
+ it('resets effects while preserving state', async () => {
729
if (__DEV__) {
724
- render(`
730
+ await render(`
731
const {useState} = React;
732
733
export default function App() {
@@ -733,41 +739,39 @@ describe('ReactFreshIntegration', () => {
739
expect(el.textContent).toBe('A0');
740
741
// Add an effect.
736
- patch(`
742
+ await patch(`
743
const {useState} = React;
744
745
export default function App() {
746
const [value, setValue] = useState(0);
747
React.useEffect(() => {
742
- const id = setInterval(() => {
743
- setValue(v => v + 1);
744
- }, 1000);
745
- return () => clearInterval(id);
748
+ Scheduler.log('B mount');
749
+ setValue(1)
750
+ return () => {
751
+ Scheduler.log('B unmount');
752
+ };
753
}, []);
754
return <h1>B{value}</h1>;
755
}
756
`);
757
+
758
// We added an effect, thereby changing Hook order.
759
// This causes a remount.
760
expect(container.firstChild).not.toBe(el);
761
el = container.firstChild;
754
- expect(el.textContent).toBe('B0');
755
-
756
- act(() => {
757
- jest.advanceTimersByTime(1000);
758
- });
762
expect(el.textContent).toBe('B1');
763
+ assertLog(['B mount']);
764
761
- patch(`
765
+ await patch(`
766
const {useState} = React;
767
768
export default function App() {
769
const [value, setValue] = useState(0);
770
React.useEffect(() => {
767
- const id = setInterval(() => {
768
- setValue(v => v + 10);
769
- }, 1000);
770
- return () => clearInterval(id);
771
+ Scheduler.log('C mount');
772
+ return () => {
773
+ Scheduler.log('C unmount');
774
+ };
775
}, []);
776
return <h1>C{value}</h1>;
777
}
@@ -776,14 +780,10 @@ describe('ReactFreshIntegration', () => {
780
expect(container.firstChild).toBe(el);
781
expect(el.textContent).toBe('C1');
782
779
- // Effects are always reset, so timer was reinstalled.
780
- // The new version increments by 10 rather than 1.
781
- act(() => {
782
- jest.advanceTimersByTime(1000);
783
- });
784
- expect(el.textContent).toBe('C11');
783
+ // Effects are always reset, so effect B was unmounted and C was mounted.
784
+ assertLog(['B unmount', 'C mount']);
785
786
- patch(`
786
+ await patch(`
787
const {useState} = React;
788
789
export default function App() {
@@ -796,12 +796,13 @@ describe('ReactFreshIntegration', () => {
796
expect(container.firstChild).not.toBe(el);
797
el = container.firstChild;
798
expect(el.textContent).toBe('D0');
799
+ assertLog(['C unmount']);
800
}
801
});
802
802
- it('does not get confused when custom hooks are reordered', () => {
803
+ it('does not get confused when custom hooks are reordered', async () => {
804
if (__DEV__) {
804
- render(`
805
+ await render(`
806
function useFancyState(initialState) {
807
return React.useState(initialState);
808
}
@@ -817,7 +818,7 @@ describe('ReactFreshIntegration', () => {
818
let el = container.firstChild;
819
expect(el.textContent).toBe('AXY');
820
820
- patch(`
821
+ await patch(`
822
function useFancyState(initialState) {
823
return React.useState(initialState);
824
}
@@ -834,7 +835,7 @@ describe('ReactFreshIntegration', () => {
835
expect(container.firstChild).toBe(el);
836
expect(el.textContent).toBe('BXY');
837
837
- patch(`
838
+ await patch(`
839
function useFancyState(initialState) {
840
return React.useState(initialState);
841
}
@@ -855,9 +856,9 @@ describe('ReactFreshIntegration', () => {
856
}
857
});
858
858
- it('does not get confused when component is called early', () => {
859
+ it('does not get confused when component is called early', async () => {
860
if (__DEV__) {
860
- render(`
861
+ await render(`
862
// This isn't really a valid pattern but it's close enough
863
// to simulate what happens when you call ReactDOM.render
864
// in the same file. We want to ensure this doesn't confuse
@@ -881,7 +882,7 @@ describe('ReactFreshIntegration', () => {
882
let el = container.firstChild;
883
expect(el.textContent).toBe('AXY');
884
884
- patch(`
885
+ await patch(`
886
// This isn't really a valid pattern but it's close enough
887
// to simulate what happens when you call ReactDOM.render
888
// in the same file. We want to ensure this doesn't confuse
@@ -906,7 +907,7 @@ describe('ReactFreshIntegration', () => {
907
expect(container.firstChild).toBe(el);
908
expect(el.textContent).toBe('BXY');
909
909
- patch(`
910
+ await patch(`
911
// This isn't really a valid pattern but it's close enough
912
// to simulate what happens when you call ReactDOM.render
913
// in the same file. We want to ensure this doesn't confuse
@@ -935,10 +936,10 @@ describe('ReactFreshIntegration', () => {
936
}
937
});
938
938
- it('does not get confused by Hooks defined inline', () => {
939
+ it('does not get confused by Hooks defined inline', async () => {
940
// This is not a recommended pattern but at least it shouldn't break.
941
if (__DEV__) {
941
- render(`
942
+ await render(`
943
const App = () => {
944
const useFancyState = (initialState) => {
945
const result = React.useState(initialState);
@@ -954,7 +955,7 @@ describe('ReactFreshIntegration', () => {
955
let el = container.firstChild;
956
expect(el.textContent).toBe('AX1Y1');
957
957
- patch(`
958
+ await patch(`
959
const App = () => {
960
const useFancyState = (initialState) => {
961
const result = React.useState(initialState);
@@ -978,9 +979,9 @@ describe('ReactFreshIntegration', () => {
979
}
980
});
981
981
- it('remounts component if custom hook it uses changes order', () => {
982
+ it('remounts component if custom hook it uses changes order', async () => {
983
if (__DEV__) {
983
- render(`
984
+ await render(`
985
const App = () => {
986
const [x, setX] = useFancyState('X');
987
const [y, setY] = useFancyState('Y');
@@ -1001,7 +1002,7 @@ describe('ReactFreshIntegration', () => {
1002
let el = container.firstChild;
1003
expect(el.textContent).toBe('AXY');
1004
1004
- patch(`
1005
+ await patch(`
1006
const App = () => {
1007
const [x, setX] = useFancyState('X');
1008
const [y, setY] = useFancyState('Y');
@@ -1024,7 +1025,7 @@ describe('ReactFreshIntegration', () => {
1025
expect(container.firstChild).toBe(el);
1026
expect(el.textContent).toBe('BXY');
1027
1027
- patch(`
1028
+ await patch(`
1029
const App = () => {
1030
const [x, setX] = useFancyState('X');
1031
const [y, setY] = useFancyState('Y');
@@ -1049,7 +1050,7 @@ describe('ReactFreshIntegration', () => {
1050
el = container.firstChild;
1051
expect(el.textContent).toBe('CXY');
1052
1052
- patch(`
1053
+ await patch(`
1054
const App = () => {
1055
const [x, setX] = useFancyState('X');
1056
const [y, setY] = useFancyState('Y');
@@ -1075,9 +1076,9 @@ describe('ReactFreshIntegration', () => {
1076
}
1077
});
1078
1078
- it('does not lose the inferred arrow names', () => {
1079
+ it('does not lose the inferred arrow names', async () => {
1080
if (__DEV__) {
1080
- render(`
1081
+ await render(`
1082
const Parent = () => {
1083
return <Child/>;
1084
};
@@ -1097,9 +1098,9 @@ describe('ReactFreshIntegration', () => {
1098
}
1099
});
1100
1100
- it('does not lose the inferred function names', () => {
1101
+ it('does not lose the inferred function names', async () => {
1102
if (__DEV__) {
1102
- render(`
1103
+ await render(`
1104
var Parent = function() {
1105
return <Child/>;
1106
};
@@ -1119,9 +1120,9 @@ describe('ReactFreshIntegration', () => {
1120
}
1121
});
1122
1122
- it('resets state on every edit with @refresh reset annotation', () => {
1123
+ it('resets state on every edit with @refresh reset annotation', async () => {
1124
if (__DEV__) {
1124
- render(`
1125
+ await render(`
1126
const {useState} = React;
1127
const S = 1;
1128
@@ -1133,7 +1134,7 @@ describe('ReactFreshIntegration', () => {
1134
let el = container.firstChild;
1135
expect(el.textContent).toBe('A1');
1136
1136
- patch(`
1137
+ await patch(`
1138
const {useState} = React;
1139
const S = 2;
1140
@@ -1146,7 +1147,7 @@ describe('ReactFreshIntegration', () => {
1147
expect(container.firstChild).toBe(el);
1148
expect(el.textContent).toBe('B1');
1149
1149
- patch(`
1150
+ await patch(`
1151
const {useState} = React;
1152
const S = 3;
1153
@@ -1162,7 +1163,7 @@ describe('ReactFreshIntegration', () => {
1163
el = container.firstChild;
1164
expect(el.textContent).toBe('C3');
1165
1165
- patch(`
1166
+ await patch(`
1167
const {useState} = React;
1168
const S = 4;
1169
@@ -1179,7 +1180,7 @@ describe('ReactFreshIntegration', () => {
1180
el = container.firstChild;
1181
expect(el.textContent).toBe('D4');
1182
1182
- patch(`
1183
+ await patch(`
1184
const {useState} = React;
1185
const S = 5;
1186
@@ -1193,7 +1194,7 @@ describe('ReactFreshIntegration', () => {
1194
expect(container.firstChild).toBe(el);
1195
expect(el.textContent).toBe('E4');
1196
1196
- patch(`
1197
+ await patch(`
1198
const {useState} = React;
1199
const S = 6;
1200
@@ -1206,7 +1207,7 @@ describe('ReactFreshIntegration', () => {
1207
expect(container.firstChild).toBe(el);
1208
expect(el.textContent).toBe('F4');
1209
1209
- patch(`
1210
+ await patch(`
1211
const {useState} = React;
1212
const S = 7;
1213
@@ -1227,9 +1228,9 @@ describe('ReactFreshIntegration', () => {
1228
1229
// This is best effort for simple cases.
1230
// We won't attempt to resolve identifiers.
1230
- it('resets state when useState initial state is edited', () => {
1231
+ it('resets state when useState initial state is edited', async () => {
1232
if (__DEV__) {
1232
- render(`
1233
+ await render(`
1234
const {useState} = React;
1235
1236
export default function App() {
@@ -1240,7 +1241,7 @@ describe('ReactFreshIntegration', () => {
1241
let el = container.firstChild;
1242
expect(el.textContent).toBe('A1');
1243
1243
- patch(`
1244
+ await patch(`
1245
const {useState} = React;
1246
1247
export default function App() {
@@ -1252,7 +1253,7 @@ describe('ReactFreshIntegration', () => {
1253
expect(container.firstChild).toBe(el);
1254
expect(el.textContent).toBe('B1');
1255
1255
- patch(`
1256
+ await patch(`
1257
const {useState} = React;
1258
1259
export default function App() {
@@ -1269,9 +1270,9 @@ describe('ReactFreshIntegration', () => {
1270
1271
// This is best effort for simple cases.
1272
// We won't attempt to resolve identifiers.
1272
- it('resets state when useReducer initial state is edited', () => {
1273
+ it('resets state when useReducer initial state is edited', async () => {
1274
if (__DEV__) {
1274
- render(`
1275
+ await render(`
1276
const {useReducer} = React;
1277
1278
export default function App() {
@@ -1282,7 +1283,7 @@ describe('ReactFreshIntegration', () => {
1283
let el = container.firstChild;
1284
expect(el.textContent).toBe('A1');
1285
1285
- patch(`
1286
+ await patch(`
1287
const {useReducer} = React;
1288
1289
export default function App() {
@@ -1294,7 +1295,7 @@ describe('ReactFreshIntegration', () => {
1295
expect(container.firstChild).toBe(el);
1296
expect(el.textContent).toBe('B1');
1297
1297
- patch(`
1298
+ await patch(`
1299
const {useReducer} = React;
1300
1301
export default function App() {
@@ -1309,16 +1310,16 @@ describe('ReactFreshIntegration', () => {
1310
}
1311
});
1312
1312
- it('remounts when switching export from function to class', () => {
1313
+ it('remounts when switching export from function to class', async () => {
1314
if (__DEV__) {
1314
- render(`
1315
+ await render(`
1316
export default function App() {
1317
return <h1>A1</h1>;
1318
}
1319
`);
1320
let el = container.firstChild;
1321
expect(el.textContent).toBe('A1');
1321
- patch(`
1322
+ await patch(`
1323
export default function App() {
1324
return <h1>A2</h1>;
1325
}
@@ -1327,7 +1328,7 @@ describe('ReactFreshIntegration', () => {
1328
expect(container.firstChild).toBe(el);
1329
expect(el.textContent).toBe('A2');
1330
1330
- patch(`
1331
+ await patch(`
1332
export default class App extends React.Component {
1333
render() {
1334
return <h1>B1</h1>
@@ -1338,7 +1339,7 @@ describe('ReactFreshIntegration', () => {
1339
expect(container.firstChild).not.toBe(el);
1340
el = container.firstChild;
1341
expect(el.textContent).toBe('B1');
1341
- patch(`
1342
+ await patch(`
1343
export default class App extends React.Component {
1344
render() {
1345
return <h1>B2</h1>
@@ -1350,7 +1351,7 @@ describe('ReactFreshIntegration', () => {
1351
el = container.firstChild;
1352
expect(el.textContent).toBe('B2');
1353
1353
- patch(`
1354
+ await patch(`
1355
export default function App() {
1356
return <h1>C1</h1>;
1357
}
@@ -1359,7 +1360,7 @@ describe('ReactFreshIntegration', () => {
1360
expect(container.firstChild).not.toBe(el);
1361
el = container.firstChild;
1362
expect(el.textContent).toBe('C1');
1362
- patch(`
1363
+ await patch(`
1364
export default function App() {
1365
return <h1>C2</h1>;
1366
}
@@ -1367,14 +1368,14 @@ describe('ReactFreshIntegration', () => {
1368
expect(container.firstChild).toBe(el);
1369
expect(el.textContent).toBe('C2');
1370
1370
- patch(`
1371
+ await patch(`
1372
export default function App() {
1373
return <h1>D1</h1>;
1374
}
1375
`);
1376
el = container.firstChild;
1377
expect(el.textContent).toBe('D1');
1377
- patch(`
1378
+ await patch(`
1379
export default function App() {
1380
return <h1>D2</h1>;
1381
}
@@ -1385,9 +1386,9 @@ describe('ReactFreshIntegration', () => {
1386
}
1387
});
1388
1388
- it('remounts when switching export from class to function', () => {
1389
+ it('remounts when switching export from class to function', async () => {
1390
if (__DEV__) {
1390
- render(`
1391
+ await render(`
1392
export default class App extends React.Component {
1393
render() {
1394
return <h1>A1</h1>
@@ -1396,7 +1397,7 @@ describe('ReactFreshIntegration', () => {
1397
`);
1398
let el = container.firstChild;
1399
expect(el.textContent).toBe('A1');
1399
- patch(`
1400
+ await patch(`
1401
export default class App extends React.Component {
1402
render() {
1403
return <h1>A2</h1>
@@ -1408,7 +1409,7 @@ describe('ReactFreshIntegration', () => {
1409
el = container.firstChild;
1410
expect(el.textContent).toBe('A2');
1411
1411
- patch(`
1412
+ await patch(`
1413
export default function App() {
1414
return <h1>B1</h1>;
1415
}
@@ -1417,7 +1418,7 @@ describe('ReactFreshIntegration', () => {
1418
expect(container.firstChild).not.toBe(el);
1419
el = container.firstChild;
1420
expect(el.textContent).toBe('B1');
1420
- patch(`
1421
+ await patch(`
1422
export default function App() {
1423
return <h1>B2</h1>;
1424
}
@@ -1426,7 +1427,7 @@ describe('ReactFreshIntegration', () => {
1427
expect(container.firstChild).toBe(el);
1428
expect(el.textContent).toBe('B2');
1429
1429
- patch(`
1430
+ await patch(`
1431
export default class App extends React.Component {
1432
render() {
1433
return <h1>C1</h1>
@@ -1440,16 +1441,16 @@ describe('ReactFreshIntegration', () => {
1441
}
1442
});
1443
1443
- it('remounts when wrapping export in a HOC', () => {
1444
+ it('remounts when wrapping export in a HOC', async () => {
1445
if (__DEV__) {
1445
- render(`
1446
+ await render(`
1447
export default function App() {
1448
return <h1>A1</h1>;
1449
}
1450
`);
1451
let el = container.firstChild;
1452
expect(el.textContent).toBe('A1');
1452
- patch(`
1453
+ await patch(`
1454
export default function App() {
1455
return <h1>A2</h1>;
1456
}
@@ -1458,7 +1459,7 @@ describe('ReactFreshIntegration', () => {
1459
expect(container.firstChild).toBe(el);
1460
expect(el.textContent).toBe('A2');
1461
1461
- patch(`
1462
+ await patch(`
1463
function hoc(Inner) {
1464
return function Wrapper() {
1465
return <Inner />;
@@ -1475,7 +1476,7 @@ describe('ReactFreshIntegration', () => {
1476
expect(container.firstChild).not.toBe(el);
1477
el = container.firstChild;
1478
expect(el.textContent).toBe('B1');
1478
- patch(`
1479
+ await patch(`
1480
function hoc(Inner) {
1481
return function Wrapper() {
1482
return <Inner />;
@@ -1492,7 +1493,7 @@ describe('ReactFreshIntegration', () => {
1493
expect(container.firstChild).toBe(el);
1494
expect(el.textContent).toBe('B2');
1495
1495
- patch(`
1496
+ await patch(`
1497
export default function App() {
1498
return <h1>C1</h1>;
1499
}
@@ -1501,7 +1502,7 @@ describe('ReactFreshIntegration', () => {
1502
expect(container.firstChild).not.toBe(el);
1503
el = container.firstChild;
1504
expect(el.textContent).toBe('C1');
1504
- patch(`
1505
+ await patch(`
1506
export default function App() {
1507
return <h1>C2</h1>;
1508
}
@@ -1511,16 +1512,16 @@ describe('ReactFreshIntegration', () => {
1512
}
1513
});
1514
1514
- it('remounts when wrapping export in memo()', () => {
1515
+ it('remounts when wrapping export in memo()', async () => {
1516
if (__DEV__) {
1516
- render(`
1517
+ await render(`
1518
export default function App() {
1519
return <h1>A1</h1>;
1520
}
1521
`);
1522
let el = container.firstChild;
1523
expect(el.textContent).toBe('A1');
1523
- patch(`
1524
+ await patch(`
1525
export default function App() {
1526
return <h1>A2</h1>;
1527
}
@@ -1529,7 +1530,7 @@ describe('ReactFreshIntegration', () => {
1530
expect(container.firstChild).toBe(el);
1531
expect(el.textContent).toBe('A2');
1532
1532
- patch(`
1533
+ await patch(`
1534
function App() {
1535
return <h1>B1</h1>;
1536
}
@@ -1540,7 +1541,7 @@ describe('ReactFreshIntegration', () => {
1541
expect(container.firstChild).not.toBe(el);
1542
el = container.firstChild;
1543
expect(el.textContent).toBe('B1');
1543
- patch(`
1544
+ await patch(`
1545
function App() {
1546
return <h1>B2</h1>;
1547
}
@@ -1551,7 +1552,7 @@ describe('ReactFreshIntegration', () => {
1552
expect(container.firstChild).toBe(el);
1553
expect(el.textContent).toBe('B2');
1554
1554
- patch(`
1555
+ await patch(`
1556
export default function App() {
1557
return <h1>C1</h1>;
1558
}
@@ -1560,7 +1561,7 @@ describe('ReactFreshIntegration', () => {
1561
expect(container.firstChild).not.toBe(el);
1562
el = container.firstChild;
1563
expect(el.textContent).toBe('C1');
1563
- patch(`
1564
+ await patch(`
1565
export default function App() {
1566
return <h1>C2</h1>;
1567
}
@@ -1570,16 +1571,16 @@ describe('ReactFreshIntegration', () => {
1571
}
1572
});
1573
1573
- it('remounts when wrapping export in forwardRef()', () => {
1574
+ it('remounts when wrapping export in forwardRef()', async () => {
1575
if (__DEV__) {
1575
- render(`
1576
+ await render(`
1577
export default function App() {
1578
return <h1>A1</h1>;
1579
}
1580
`);
1581
let el = container.firstChild;
1582
expect(el.textContent).toBe('A1');
1582
- patch(`
1583
+ await patch(`
1584
export default function App() {
1585
return <h1>A2</h1>;
1586
}
@@ -1588,7 +1589,7 @@ describe('ReactFreshIntegration', () => {
1589
expect(container.firstChild).toBe(el);
1590
expect(el.textContent).toBe('A2');
1591
1591
- patch(`
1592
+ await patch(`
1593
function App() {
1594
return <h1>B1</h1>;
1595
}
@@ -1599,7 +1600,7 @@ describe('ReactFreshIntegration', () => {
1600
expect(container.firstChild).not.toBe(el);
1601
el = container.firstChild;
1602
expect(el.textContent).toBe('B1');
1602
- patch(`
1603
+ await patch(`
1604
function App() {
1605
return <h1>B2</h1>;
1606
}
@@ -1610,7 +1611,7 @@ describe('ReactFreshIntegration', () => {
1611
expect(container.firstChild).toBe(el);
1612
expect(el.textContent).toBe('B2');
1613
1613
- patch(`
1614
+ await patch(`
1615
export default function App() {
1616
return <h1>C1</h1>;
1617
}
@@ -1619,7 +1620,7 @@ describe('ReactFreshIntegration', () => {
1620
expect(container.firstChild).not.toBe(el);
1621
el = container.firstChild;
1622
expect(el.textContent).toBe('C1');
1622
- patch(`
1623
+ await patch(`
1624
export default function App() {
1625
return <h1>C2</h1>;
1626
}
@@ -1630,10 +1631,10 @@ describe('ReactFreshIntegration', () => {
1631
});
1632
1633
if (!require('shared/ReactFeatureFlags').disableModulePatternComponents) {
1633
- it('remounts deprecated factory components', () => {
1634
+ it('remounts deprecated factory components', async () => {
1635
if (__DEV__) {
1635
- expect(() => {
1636
- render(`
1636
+ await expect(async () => {
1637
+ await render(`
1638
function Parent() {
1639
return {
1640
render() {
@@ -1654,7 +1655,7 @@ describe('ReactFreshIntegration', () => {
1655
);
1656
const el = container.firstChild;
1657
expect(el.textContent).toBe('A1');
1657
- patch(`
1658
+ await patch(`
1659
function Parent() {
1660
return {
1661
render() {
@@ -1686,14 +1687,14 @@ describe('ReactFreshIntegration', () => {
1687
delete global.FakeModuleSystem;
1688
});
1689
1689
- it('remounts component if custom hook it uses changes order on first edit', () => {
1690
+ it('remounts component if custom hook it uses changes order on first edit', async () => {
1691
// This test verifies that remounting works even if calls to custom Hooks
1692
// were transformed with an inline requires transform, like we have on RN.
1693
// Inline requires make it harder to compare previous and next signatures
1694
// because useFancyState inline require always resolves to the newest version.
1695
// We're not actually using inline requires in the test, but it has similar semantics.
1696
if (__DEV__) {
1696
- render(`
1697
+ await render(`
1698
const FakeModuleSystem = global.FakeModuleSystem;
1699
1700
FakeModuleSystem.useFancyState = function(initialState) {
@@ -1711,7 +1712,7 @@ describe('ReactFreshIntegration', () => {
1712
let el = container.firstChild;
1713
expect(el.textContent).toBe('AXY');
1714
1714
- patch(`
1715
+ await patch(`
1716
const FakeModuleSystem = global.FakeModuleSystem;
1717
1718
FakeModuleSystem.useFancyState = function(initialState) {
@@ -1733,7 +1734,7 @@ describe('ReactFreshIntegration', () => {
1734
el = container.firstChild;
1735
expect(el.textContent).toBe('BXY');
1736
1736
- patch(`
1737
+ await patch(`
1738
const FakeModuleSystem = global.FakeModuleSystem;
1739
1740
FakeModuleSystem.useFancyState = function(initialState) {
@@ -1756,9 +1757,9 @@ describe('ReactFreshIntegration', () => {
1757
}
1758
});
1759
1759
- it('remounts component if custom hook it uses changes order on second edit', () => {
1760
+ it('remounts component if custom hook it uses changes order on second edit', async () => {
1761
if (__DEV__) {
1761
- render(`
1762
+ await render(`
1763
const FakeModuleSystem = global.FakeModuleSystem;
1764
1765
FakeModuleSystem.useFancyState = function(initialState) {
@@ -1776,7 +1777,7 @@ describe('ReactFreshIntegration', () => {
1777
let el = container.firstChild;
1778
expect(el.textContent).toBe('AXY');
1779
1779
- patch(`
1780
+ await patch(`
1781
const FakeModuleSystem = global.FakeModuleSystem;
1782
1783
FakeModuleSystem.useFancyState = function(initialState) {
@@ -1794,7 +1795,7 @@ describe('ReactFreshIntegration', () => {
1795
expect(container.firstChild).toBe(el);
1796
expect(el.textContent).toBe('BXY');
1797
1797
- patch(`
1798
+ await patch(`
1799
const FakeModuleSystem = global.FakeModuleSystem;
1800
1801
FakeModuleSystem.useFancyState = function(initialState) {
@@ -1816,7 +1817,7 @@ describe('ReactFreshIntegration', () => {
1817
el = container.firstChild;
1818
expect(el.textContent).toBe('CXY');
1819
1819
- patch(`
1820
+ await patch(`
1821
const FakeModuleSystem = global.FakeModuleSystem;
1822
1823
FakeModuleSystem.useFancyState = function(initialState) {
@@ -1839,9 +1840,9 @@ describe('ReactFreshIntegration', () => {
1840
}
1841
});
1842
1842
- it('recovers if evaluating Hook list throws', () => {
1843
+ it('recovers if evaluating Hook list throws', async () => {
1844
if (__DEV__) {
1844
- render(`
1845
+ await render(`
1846
let FakeModuleSystem = null;
1847
1848
global.FakeModuleSystem.useFancyState = function(initialState) {
@@ -1860,7 +1861,7 @@ describe('ReactFreshIntegration', () => {
1861
let el = container.firstChild;
1862
expect(el.textContent).toBe('AXY');
1863
1863
- patch(`
1864
+ await patch(`
1865
let FakeModuleSystem = null;
1866
1867
global.FakeModuleSystem.useFancyState = function(initialState) {
@@ -1885,9 +1886,9 @@ describe('ReactFreshIntegration', () => {
1886
}
1887
});
1888
1888
- it('remounts component if custom hook it uses changes order behind an indirection', () => {
1889
+ it('remounts component if custom hook it uses changes order behind an indirection', async () => {
1890
if (__DEV__) {
1890
- render(`
1891
+ await render(`
1892
const FakeModuleSystem = global.FakeModuleSystem;
1893
1894
FakeModuleSystem.useFancyState = function(initialState) {
@@ -1913,7 +1914,7 @@ describe('ReactFreshIntegration', () => {
1914
let el = container.firstChild;
1915
expect(el.textContent).toBe('AXY');
1916
1916
- patch(`
1917
+ await patch(`
1918
const FakeModuleSystem = global.FakeModuleSystem;
1919
1920
FakeModuleSystem.useFancyState = function(initialState) {
@@ -1944,7 +1945,7 @@ describe('ReactFreshIntegration', () => {
1945
el = container.firstChild;
1946
expect(el.textContent).toBe('BXY');
1947
1947
- patch(`
1948
+ await patch(`
1949
const FakeModuleSystem = global.FakeModuleSystem;
1950
1951
FakeModuleSystem.useFancyState = function(initialState) {
@@ -1978,9 +1979,9 @@ describe('ReactFreshIntegration', () => {
1979
}
1980
1981
function testTypeScript(render, patch) {
1981
- it('reloads component exported in typescript namespace', () => {
1982
+ it('reloads component exported in typescript namespace', async () => {
1983
if (__DEV__) {
1983
- render(`
1984
+ await render(`
1985
namespace Foo {
1986
export namespace Bar {
1987
export const Child = ({prop}) => {
@@ -1995,7 +1996,7 @@ describe('ReactFreshIntegration', () => {
1996
`);
1997
const el = container.firstChild;
1998
expect(el.textContent).toBe('A1');
1998
- patch(`
1999
+ await patch(`
2000
namespace Foo {
2001
export namespace Bar {
2002
export const Child = ({prop}) => {