Convert ReactBrowserEventEmitter to createRoot (#28253)
pretty boring
Ricky committed
Feb 6, 2024 at 10:43 UTC
5446b098a8ba23b8d1bd39e552bff9b09b52c334
1 file changed
+153
-78
packages/react-dom/src/__tests__/ReactBrowserEventEmitter-test.js
+153
-78
@@ -10,8 +10,9 @@
10
'use strict';
11
12
let React;
13
-let ReactDOM;
13
+let ReactDOMClient;
14
let ReactTestUtils;
15
+let act;
16
17
let idCallOrder;
18
const recordID = function (id) {
@@ -34,6 +35,7 @@ let PARENT;
35
let CHILD;
36
let BUTTON;
37
38
+let renderTree;
39
let putListener;
40
let deleteAllListeners;
41
@@ -47,9 +49,9 @@ describe('ReactBrowserEventEmitter', () => {
49
LISTENER.mockClear();
50
51
React = require('react');
50
- ReactDOM = require('react-dom');
52
+ ReactDOMClient = require('react-dom/client');
53
ReactTestUtils = require('react-dom/test-utils');
52
-
54
+ act = require('internal-test-utils').act;
55
container = document.createElement('div');
56
document.body.appendChild(container);
57
@@ -68,21 +70,26 @@ describe('ReactBrowserEventEmitter', () => {
70
}
71
}
72
71
- function renderTree() {
72
- ReactDOM.render(
73
- <div ref={c => (GRANDPARENT = c)} {...GRANDPARENT_PROPS}>
74
- <div ref={c => (PARENT = c)} {...PARENT_PROPS}>
75
- <ChildWrapper {...CHILD_PROPS} />
76
- <button disabled={true} ref={c => (BUTTON = c)} {...BUTTON_PROPS} />
77
- </div>
78
- </div>,
79
- container,
80
- );
81
- }
82
-
83
- renderTree();
73
+ const root = ReactDOMClient.createRoot(container);
74
+
75
+ renderTree = async function () {
76
+ await act(() => {
77
+ root.render(
78
+ <div ref={c => (GRANDPARENT = c)} {...GRANDPARENT_PROPS}>
79
+ <div ref={c => (PARENT = c)} {...PARENT_PROPS}>
80
+ <ChildWrapper {...CHILD_PROPS} />
81
+ <button
82
+ disabled={true}
83
+ ref={c => (BUTTON = c)}
84
+ {...BUTTON_PROPS}
85
+ />
86
+ </div>
87
+ </div>,
88
+ );
89
+ });
90
+ };
91
85
- putListener = function (node, eventName, listener) {
92
+ putListener = async function (node, eventName, listener) {
93
switch (node) {
94
case CHILD:
95
CHILD_PROPS[eventName] = listener;
@@ -98,9 +105,10 @@ describe('ReactBrowserEventEmitter', () => {
105
break;
106
}
107
// Rerender with new event listeners
101
- renderTree();
108
+ await renderTree();
109
};
103
- deleteAllListeners = function (node) {
110
+
111
+ deleteAllListeners = async function (node) {
112
switch (node) {
113
case CHILD:
114
CHILD_PROPS = {};
@@ -115,7 +123,7 @@ describe('ReactBrowserEventEmitter', () => {
123
BUTTON_PROPS = {};
124
break;
125
}
118
- renderTree();
126
+ await renderTree();
127
};
128
129
idCallOrder = [];
@@ -126,120 +134,178 @@ describe('ReactBrowserEventEmitter', () => {
134
container = null;
135
});
136
129
- it('should bubble simply', () => {
130
- putListener(CHILD, ON_CLICK_KEY, recordID.bind(null, CHILD));
131
- putListener(PARENT, ON_CLICK_KEY, recordID.bind(null, PARENT));
132
- putListener(GRANDPARENT, ON_CLICK_KEY, recordID.bind(null, GRANDPARENT));
133
- CHILD.click();
137
+ it('should bubble simply', async () => {
138
+ await renderTree();
139
+ await putListener(CHILD, ON_CLICK_KEY, recordID.bind(null, CHILD));
140
+ await putListener(PARENT, ON_CLICK_KEY, recordID.bind(null, PARENT));
141
+ await putListener(
142
+ GRANDPARENT,
143
+ ON_CLICK_KEY,
144
+ recordID.bind(null, GRANDPARENT),
145
+ );
146
+ await act(() => {
147
+ CHILD.click();
148
+ });
149
expect(idCallOrder.length).toBe(3);
150
expect(idCallOrder[0]).toBe(CHILD);
151
expect(idCallOrder[1]).toBe(PARENT);
152
expect(idCallOrder[2]).toBe(GRANDPARENT);
153
});
154
140
- it('should bubble to the right handler after an update', () => {
141
- putListener(GRANDPARENT, ON_CLICK_KEY, recordID.bind(null, 'GRANDPARENT'));
142
- putListener(PARENT, ON_CLICK_KEY, recordID.bind(null, 'PARENT'));
143
- putListener(CHILD, ON_CLICK_KEY, recordID.bind(null, 'CHILD'));
144
- CHILD.click();
155
+ it('should bubble to the right handler after an update', async () => {
156
+ await renderTree();
157
+ await putListener(
158
+ GRANDPARENT,
159
+ ON_CLICK_KEY,
160
+ recordID.bind(null, 'GRANDPARENT'),
161
+ );
162
+ await putListener(PARENT, ON_CLICK_KEY, recordID.bind(null, 'PARENT'));
163
+ await putListener(CHILD, ON_CLICK_KEY, recordID.bind(null, 'CHILD'));
164
+ await act(() => {
165
+ CHILD.click();
166
+ });
167
expect(idCallOrder).toEqual(['CHILD', 'PARENT', 'GRANDPARENT']);
168
169
idCallOrder = [];
170
171
// Update just the grand parent without updating the child.
150
- putListener(
172
+ await putListener(
173
GRANDPARENT,
174
ON_CLICK_KEY,
175
recordID.bind(null, 'UPDATED_GRANDPARENT'),
176
);
177
156
- CHILD.click();
178
+ await act(() => {
179
+ CHILD.click();
180
+ });
181
expect(idCallOrder).toEqual(['CHILD', 'PARENT', 'UPDATED_GRANDPARENT']);
182
});
183
160
- it('should continue bubbling if an error is thrown', () => {
161
- putListener(CHILD, ON_CLICK_KEY, recordID.bind(null, CHILD));
162
- putListener(PARENT, ON_CLICK_KEY, function () {
184
+ it('should continue bubbling if an error is thrown', async () => {
185
+ await renderTree();
186
+ await putListener(CHILD, ON_CLICK_KEY, recordID.bind(null, CHILD));
187
+ await putListener(PARENT, ON_CLICK_KEY, function () {
188
recordID(PARENT);
189
throw new Error('Handler interrupted');
190
});
166
- putListener(GRANDPARENT, ON_CLICK_KEY, recordID.bind(null, GRANDPARENT));
167
- expect(function () {
168
- ReactTestUtils.Simulate.click(CHILD);
169
- }).toThrow();
191
+ await putListener(
192
+ GRANDPARENT,
193
+ ON_CLICK_KEY,
194
+ recordID.bind(null, GRANDPARENT),
195
+ );
196
+ await expect(
197
+ act(() => {
198
+ ReactTestUtils.Simulate.click(CHILD);
199
+ }),
200
+ ).rejects.toThrow();
201
expect(idCallOrder.length).toBe(3);
202
expect(idCallOrder[0]).toBe(CHILD);
203
expect(idCallOrder[1]).toBe(PARENT);
204
expect(idCallOrder[2]).toBe(GRANDPARENT);
205
});
206
176
- it('should set currentTarget', () => {
177
- putListener(CHILD, ON_CLICK_KEY, function (event) {
207
+ it('should set currentTarget', async () => {
208
+ await renderTree();
209
+ await putListener(CHILD, ON_CLICK_KEY, function (event) {
210
recordID(CHILD);
211
expect(event.currentTarget).toBe(CHILD);
212
});
181
- putListener(PARENT, ON_CLICK_KEY, function (event) {
213
+ await putListener(PARENT, ON_CLICK_KEY, function (event) {
214
recordID(PARENT);
215
expect(event.currentTarget).toBe(PARENT);
216
});
185
- putListener(GRANDPARENT, ON_CLICK_KEY, function (event) {
217
+ await putListener(GRANDPARENT, ON_CLICK_KEY, function (event) {
218
recordID(GRANDPARENT);
219
expect(event.currentTarget).toBe(GRANDPARENT);
220
});
189
- CHILD.click();
221
+ await act(() => {
222
+ CHILD.click();
223
+ });
224
expect(idCallOrder.length).toBe(3);
225
expect(idCallOrder[0]).toBe(CHILD);
226
expect(idCallOrder[1]).toBe(PARENT);
227
expect(idCallOrder[2]).toBe(GRANDPARENT);
228
});
229
196
- it('should support stopPropagation()', () => {
197
- putListener(CHILD, ON_CLICK_KEY, recordID.bind(null, CHILD));
198
- putListener(
230
+ it('should support stopPropagation()', async () => {
231
+ await renderTree();
232
+ await putListener(CHILD, ON_CLICK_KEY, recordID.bind(null, CHILD));
233
+ await putListener(
234
PARENT,
235
ON_CLICK_KEY,
236
recordIDAndStopPropagation.bind(null, PARENT),
237
);
203
- putListener(GRANDPARENT, ON_CLICK_KEY, recordID.bind(null, GRANDPARENT));
204
- CHILD.click();
238
+ await putListener(
239
+ GRANDPARENT,
240
+ ON_CLICK_KEY,
241
+ recordID.bind(null, GRANDPARENT),
242
+ );
243
+ await act(() => {
244
+ CHILD.click();
245
+ });
246
expect(idCallOrder.length).toBe(2);
247
expect(idCallOrder[0]).toBe(CHILD);
248
expect(idCallOrder[1]).toBe(PARENT);
249
});
250
210
- it('should support overriding .isPropagationStopped()', () => {
251
+ it('should support overriding .isPropagationStopped()', async () => {
252
+ await renderTree();
253
// Ew. See D4504876.
212
- putListener(CHILD, ON_CLICK_KEY, recordID.bind(null, CHILD));
213
- putListener(PARENT, ON_CLICK_KEY, function (e) {
254
+ await putListener(CHILD, ON_CLICK_KEY, recordID.bind(null, CHILD));
255
+ await putListener(PARENT, ON_CLICK_KEY, function (e) {
256
recordID(PARENT, e);
257
// This stops React bubbling but avoids touching the native event
258
e.isPropagationStopped = () => true;
259
});
218
- putListener(GRANDPARENT, ON_CLICK_KEY, recordID.bind(null, GRANDPARENT));
219
- CHILD.click();
260
+ await putListener(
261
+ GRANDPARENT,
262
+ ON_CLICK_KEY,
263
+ recordID.bind(null, GRANDPARENT),
264
+ );
265
+ await act(() => {
266
+ CHILD.click();
267
+ });
268
expect(idCallOrder.length).toBe(2);
269
expect(idCallOrder[0]).toBe(CHILD);
270
expect(idCallOrder[1]).toBe(PARENT);
271
});
272
225
- it('should stop after first dispatch if stopPropagation', () => {
226
- putListener(
273
+ it('should stop after first dispatch if stopPropagation', async () => {
274
+ await renderTree();
275
+ await putListener(
276
CHILD,
277
ON_CLICK_KEY,
278
recordIDAndStopPropagation.bind(null, CHILD),
279
);
231
- putListener(PARENT, ON_CLICK_KEY, recordID.bind(null, PARENT));
232
- putListener(GRANDPARENT, ON_CLICK_KEY, recordID.bind(null, GRANDPARENT));
233
- CHILD.click();
280
+ await putListener(PARENT, ON_CLICK_KEY, recordID.bind(null, PARENT));
281
+ await putListener(
282
+ GRANDPARENT,
283
+ ON_CLICK_KEY,
284
+ recordID.bind(null, GRANDPARENT),
285
+ );
286
+ await act(() => {
287
+ CHILD.click();
288
+ });
289
expect(idCallOrder.length).toBe(1);
290
expect(idCallOrder[0]).toBe(CHILD);
291
});
292
238
- it('should not stopPropagation if false is returned', () => {
239
- putListener(CHILD, ON_CLICK_KEY, recordIDAndReturnFalse.bind(null, CHILD));
240
- putListener(PARENT, ON_CLICK_KEY, recordID.bind(null, PARENT));
241
- putListener(GRANDPARENT, ON_CLICK_KEY, recordID.bind(null, GRANDPARENT));
242
- CHILD.click();
293
+ it('should not stopPropagation if false is returned', async () => {
294
+ await renderTree();
295
+ await putListener(
296
+ CHILD,
297
+ ON_CLICK_KEY,
298
+ recordIDAndReturnFalse.bind(null, CHILD),
299
+ );
300
+ await putListener(PARENT, ON_CLICK_KEY, recordID.bind(null, PARENT));
301
+ await putListener(
302
+ GRANDPARENT,
303
+ ON_CLICK_KEY,
304
+ recordID.bind(null, GRANDPARENT),
305
+ );
306
+ await act(() => {
307
+ CHILD.click();
308
+ });
309
expect(idCallOrder.length).toBe(3);
310
expect(idCallOrder[0]).toBe(CHILD);
311
expect(idCallOrder[1]).toBe(PARENT);
@@ -255,30 +321,39 @@ describe('ReactBrowserEventEmitter', () => {
321
* these new listeners.
322
*/
323
258
- it('should invoke handlers that were removed while bubbling', () => {
324
+ it('should invoke handlers that were removed while bubbling', async () => {
325
+ await renderTree();
326
const handleParentClick = jest.fn();
260
- const handleChildClick = function (event) {
261
- deleteAllListeners(PARENT);
327
+ const handleChildClick = async function (event) {
328
+ await deleteAllListeners(PARENT);
329
};
263
- putListener(CHILD, ON_CLICK_KEY, handleChildClick);
264
- putListener(PARENT, ON_CLICK_KEY, handleParentClick);
265
- CHILD.click();
330
+ await putListener(CHILD, ON_CLICK_KEY, handleChildClick);
331
+ await putListener(PARENT, ON_CLICK_KEY, handleParentClick);
332
+ await act(() => {
333
+ CHILD.click();
334
+ });
335
expect(handleParentClick).toHaveBeenCalledTimes(1);
336
});
337
269
- it('should not invoke newly inserted handlers while bubbling', () => {
338
+ it('should not invoke newly inserted handlers while bubbling', async () => {
339
+ await renderTree();
340
const handleParentClick = jest.fn();
271
- const handleChildClick = function (event) {
272
- putListener(PARENT, ON_CLICK_KEY, handleParentClick);
341
+ const handleChildClick = async function (event) {
342
+ await putListener(PARENT, ON_CLICK_KEY, handleParentClick);
343
};
274
- putListener(CHILD, ON_CLICK_KEY, handleChildClick);
275
- CHILD.click();
344
+ await putListener(CHILD, ON_CLICK_KEY, handleChildClick);
345
+ await act(() => {
346
+ CHILD.click();
347
+ });
348
expect(handleParentClick).toHaveBeenCalledTimes(0);
349
});
350
279
- it('should have mouse enter simulated by test utils', () => {
280
- putListener(CHILD, ON_MOUSE_ENTER_KEY, recordID.bind(null, CHILD));
281
- ReactTestUtils.Simulate.mouseEnter(CHILD);
351
+ it('should have mouse enter simulated by test utils', async () => {
352
+ await renderTree();
353
+ await putListener(CHILD, ON_MOUSE_ENTER_KEY, recordID.bind(null, CHILD));
354
+ await act(() => {
355
+ ReactTestUtils.Simulate.mouseEnter(CHILD);
356
+ });
357
expect(idCallOrder.length).toBe(1);
358
expect(idCallOrder[0]).toBe(CHILD);
359
});