Skip to content

Commit f945f3a

Browse files
committed
Convert the test to use native events
1 parent fac7551 commit f945f3a

File tree

1 file changed

+69
-51
lines changed

1 file changed

+69
-51
lines changed

packages/react-dom/src/__tests__/ReactDOMNativeEventHeuristic-test.js

Lines changed: 69 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -31,31 +31,36 @@ describe('ReactDOMNativeEventHeuristic-test', () => {
3131
document.body.removeChild(container);
3232
});
3333

34+
function dispatchAndSetCurrentEvent(el, event) {
35+
try {
36+
window.event = event;
37+
el.dispatchEvent(event);
38+
} finally {
39+
window.event = undefined;
40+
}
41+
}
42+
3443
// @gate experimental
35-
it('ignores discrete events on a pending removed element', () => {
44+
// @gate enableDiscreteEventMicroTasks && enableNativeEventPriorityInference
45+
it('ignores discrete events on a pending removed element', async () => {
3646
const disableButtonRef = React.createRef();
3747
const submitButtonRef = React.createRef();
3848

39-
let formSubmitted = false;
40-
4149
function Form() {
4250
const [active, setActive] = React.useState(true);
51+
52+
React.useLayoutEffect(() => {
53+
disableButtonRef.current.onclick = disableForm;
54+
});
55+
4356
function disableForm() {
4457
setActive(false);
4558
}
46-
function submitForm() {
47-
formSubmitted = true; // This should not get invoked
48-
}
59+
4960
return (
5061
<div>
51-
<button onClick={disableForm} ref={disableButtonRef}>
52-
Disable
53-
</button>
54-
{active ? (
55-
<button onClick={submitForm} ref={submitButtonRef}>
56-
Submit
57-
</button>
58-
) : null}
62+
<button ref={disableButtonRef}>Disable</button>
63+
{active ? <button ref={submitButtonRef}>Submit</button> : null}
5964
</div>
6065
);
6166
}
@@ -71,54 +76,56 @@ describe('ReactDOMNativeEventHeuristic-test', () => {
7176
// Dispatch a click event on the Disable-button.
7277
const firstEvent = document.createEvent('Event');
7378
firstEvent.initEvent('click', true, true);
74-
disableButton.dispatchEvent(firstEvent);
79+
expect(() =>
80+
dispatchAndSetCurrentEvent(disableButton, firstEvent),
81+
).toErrorDev(['An update to Form inside a test was not wrapped in act']);
7582

7683
// There should now be a pending update to disable the form.
77-
7884
// This should not have flushed yet since it's in concurrent mode.
7985
const submitButton = submitButtonRef.current;
8086
expect(submitButton.tagName).toBe('BUTTON');
8187

82-
// In the meantime, we can dispatch a new client event on the submit button.
83-
const secondEvent = document.createEvent('Event');
84-
secondEvent.initEvent('click', true, true);
85-
// This should force the pending update to flush which disables the submit button before the event is invoked.
86-
submitButton.dispatchEvent(secondEvent);
87-
88-
// Therefore the form should never have been submitted.
89-
expect(formSubmitted).toBe(false);
90-
88+
// Discrete events should be flushed in a microtask.
89+
// Verify that the second button was removed.
90+
await null;
9191
expect(submitButtonRef.current).toBe(null);
92+
// We'll assume that the browser won't let the user click it.
9293
});
9394

9495
// @gate experimental
95-
it('ignores discrete events on a pending removed event listener', () => {
96+
// @gate enableDiscreteEventMicroTasks && enableNativeEventPriorityInference
97+
it('ignores discrete events on a pending removed event listener', async () => {
9698
const disableButtonRef = React.createRef();
9799
const submitButtonRef = React.createRef();
98100

99101
let formSubmitted = false;
100102

101103
function Form() {
102104
const [active, setActive] = React.useState(true);
105+
106+
React.useLayoutEffect(() => {
107+
disableButtonRef.current.onclick = disableForm;
108+
submitButtonRef.current.onclick = active
109+
? submitForm
110+
: disabledSubmitForm;
111+
});
112+
103113
function disableForm() {
104114
setActive(false);
105115
}
116+
106117
function submitForm() {
107118
formSubmitted = true; // This should not get invoked
108119
}
120+
109121
function disabledSubmitForm() {
110122
// The form is disabled.
111123
}
124+
112125
return (
113126
<div>
114-
<button onClick={disableForm} ref={disableButtonRef}>
115-
Disable
116-
</button>
117-
<button
118-
onClick={active ? submitForm : disabledSubmitForm}
119-
ref={submitButtonRef}>
120-
Submit
121-
</button>
127+
<button ref={disableButtonRef}>Disable</button>
128+
<button ref={submitButtonRef}>Submit</button>
122129
</div>
123130
);
124131
}
@@ -134,47 +141,55 @@ describe('ReactDOMNativeEventHeuristic-test', () => {
134141
// Dispatch a click event on the Disable-button.
135142
const firstEvent = document.createEvent('Event');
136143
firstEvent.initEvent('click', true, true);
137-
disableButton.dispatchEvent(firstEvent);
144+
expect(() => {
145+
dispatchAndSetCurrentEvent(disableButton, firstEvent);
146+
}).toErrorDev(['An update to Form inside a test was not wrapped in act']);
138147

139148
// There should now be a pending update to disable the form.
140-
141149
// This should not have flushed yet since it's in concurrent mode.
142150
const submitButton = submitButtonRef.current;
143151
expect(submitButton.tagName).toBe('BUTTON');
144152

145-
// In the meantime, we can dispatch a new client event on the submit button.
153+
// Discrete events should be flushed in a microtask.
154+
await null;
155+
156+
// Now let's dispatch an event on the submit button.
146157
const secondEvent = document.createEvent('Event');
147158
secondEvent.initEvent('click', true, true);
148-
// This should force the pending update to flush which disables the submit button before the event is invoked.
149-
submitButton.dispatchEvent(secondEvent);
159+
dispatchAndSetCurrentEvent(submitButton, secondEvent);
150160

151161
// Therefore the form should never have been submitted.
152162
expect(formSubmitted).toBe(false);
153163
});
154164

155165
// @gate experimental
156-
it('uses the newest discrete events on a pending changed event listener', () => {
166+
// @gate enableDiscreteEventMicroTasks && enableNativeEventPriorityInference
167+
it('uses the newest discrete events on a pending changed event listener', async () => {
157168
const enableButtonRef = React.createRef();
158169
const submitButtonRef = React.createRef();
159170

160171
let formSubmitted = false;
161172

162173
function Form() {
163174
const [active, setActive] = React.useState(false);
175+
176+
React.useLayoutEffect(() => {
177+
enableButtonRef.current.onclick = enableForm;
178+
submitButtonRef.current.onclick = active ? submitForm : null;
179+
});
180+
164181
function enableForm() {
165182
setActive(true);
166183
}
184+
167185
function submitForm() {
168186
formSubmitted = true; // This should not get invoked
169187
}
188+
170189
return (
171190
<div>
172-
<button onClick={enableForm} ref={enableButtonRef}>
173-
Enable
174-
</button>
175-
<button onClick={active ? submitForm : null} ref={submitButtonRef}>
176-
Submit
177-
</button>
191+
<button ref={enableButtonRef}>Enable</button>
192+
<button ref={submitButtonRef}>Submit</button>
178193
</div>
179194
);
180195
}
@@ -190,19 +205,22 @@ describe('ReactDOMNativeEventHeuristic-test', () => {
190205
// Dispatch a click event on the Enable-button.
191206
const firstEvent = document.createEvent('Event');
192207
firstEvent.initEvent('click', true, true);
193-
enableButton.dispatchEvent(firstEvent);
208+
expect(() => {
209+
dispatchAndSetCurrentEvent(enableButton, firstEvent);
210+
}).toErrorDev(['An update to Form inside a test was not wrapped in act']);
194211

195212
// There should now be a pending update to enable the form.
196-
197213
// This should not have flushed yet since it's in concurrent mode.
198214
const submitButton = submitButtonRef.current;
199215
expect(submitButton.tagName).toBe('BUTTON');
200216

201-
// In the meantime, we can dispatch a new client event on the submit button.
217+
// Discrete events should be flushed in a microtask.
218+
await null;
219+
220+
// Now let's dispatch an event on the submit button.
202221
const secondEvent = document.createEvent('Event');
203222
secondEvent.initEvent('click', true, true);
204-
// This should force the pending update to flush which enables the submit button before the event is invoked.
205-
submitButton.dispatchEvent(secondEvent);
223+
dispatchAndSetCurrentEvent(submitButton, secondEvent);
206224

207225
// Therefore the form should have been submitted.
208226
expect(formSubmitted).toBe(true);

0 commit comments

Comments
 (0)