Add invariant check for composite components to event simulation test utils (#10414)
* Add invariant check for composite components to event simulation test utils * Change simulate variable names from domComponentOrNode to domNode, language for new simulate invariant, and add space in existing invariant * Update test name * Update test for invariant with shallow rendering * Update text for existing invariant and change comments to reflect change to only domNode usage * Update text for existing invariant to reflect syntax with new invariant * Update ReactTestUtilsEntry.js * Update React element invariant to reflect usage with shallow rendering * Move Simulate-related tests into Simulate block * Run prettier
Jack Ford committed
Aug 17, 2017 at 14:23 UTC
072b1d9860f290b6d9495763a433255cfc9c2ce5
2 files changed
+140
-110
src/renderers/dom/test/ReactTestUtilsEntry.js
+17
-17
@@ -437,40 +437,40 @@ var ReactTestUtils = {
437
/**
438
* Exports:
439
*
440
- * - `ReactTestUtils.Simulate.click(Element/ReactDOMComponent)`
441
- * - `ReactTestUtils.Simulate.mouseMove(Element/ReactDOMComponent)`
442
- * - `ReactTestUtils.Simulate.change(Element/ReactDOMComponent)`
440
+ * - `ReactTestUtils.Simulate.click(Element)`
441
+ * - `ReactTestUtils.Simulate.mouseMove(Element)`
442
+ * - `ReactTestUtils.Simulate.change(Element)`
443
* - ... (All keys from event plugin `eventTypes` objects)
444
*/
445
function makeSimulator(eventType) {
446
- return function(domComponentOrNode, eventData) {
447
- var node;
446
+ return function(domNode, eventData) {
447
invariant(
449
- !React.isValidElement(domComponentOrNode),
450
- 'TestUtils.Simulate expects a component instance and not a ReactElement.' +
451
- 'TestUtils.Simulate will not work if you are using shallow rendering.',
448
+ !React.isValidElement(domNode),
449
+ 'TestUtils.Simulate expected a DOM node as the first argument but received ' +
450
+ 'a React element. Pass the DOM node you wish to simulate the event on instead. ' +
451
+ 'Note that TestUtils.Simulate will not work if you are using shallow rendering.',
452
+ );
453
+ invariant(
454
+ !ReactTestUtils.isCompositeComponent(domNode),
455
+ 'TestUtils.Simulate expected a DOM node as the first argument but received ' +
456
+ 'a component instance. Pass the DOM node you wish to simulate the event on instead.',
457
);
453
- if (ReactTestUtils.isDOMComponent(domComponentOrNode)) {
454
- node = findDOMNode(domComponentOrNode);
455
- } else if (domComponentOrNode.tagName) {
456
- node = domComponentOrNode;
457
- }
458
459
var dispatchConfig =
460
EventPluginRegistry.eventNameDispatchConfigs[eventType];
461
462
var fakeNativeEvent = new Event();
463
- fakeNativeEvent.target = node;
463
+ fakeNativeEvent.target = domNode;
464
fakeNativeEvent.type = eventType.toLowerCase();
465
466
// We don't use SyntheticEvent.getPooled in order to not have to worry about
467
// properly destroying any properties assigned from `eventData` upon release
468
- var targetInst = ReactDOMComponentTree.getInstanceFromNode(node);
468
+ var targetInst = ReactDOMComponentTree.getInstanceFromNode(domNode);
469
var event = new SyntheticEvent(
470
dispatchConfig,
471
targetInst,
472
fakeNativeEvent,
473
- node,
473
+ domNode,
474
);
475
476
// Since we aren't using pooling, always persist the event. This will make
@@ -487,7 +487,7 @@ function makeSimulator(eventType) {
487
ReactDOM.unstable_batchedUpdates(function() {
488
// Normally extractEvent enqueues a state restore, but we'll just always
489
// do that since we we're by-passing it here.
490
- ReactControlledComponent.enqueueStateRestore(node);
490
+ ReactControlledComponent.enqueueStateRestore(domNode);
491
492
EventPluginHub.enqueueEvents(event);
493
EventPluginHub.processEventQueue(true);
src/renderers/dom/test/__tests__/ReactTestUtils-test.js
+123
-93
@@ -187,127 +187,157 @@ describe('ReactTestUtils', () => {
187
expect(ReactTestUtils.isDOMComponent(component.refs.body)).toBe(true);
188
});
189
190
- it('should change the value of an input field', () => {
191
- const obj = {
192
- handler: function(e) {
193
- e.persist();
194
- },
195
- };
196
- spyOn(obj, 'handler').and.callThrough();
197
- const container = document.createElement('div');
198
- const instance = ReactDOM.render(
199
- <input type="text" onChange={obj.handler} />,
200
- container,
201
- );
202
-
203
- const node = ReactDOM.findDOMNode(instance);
204
- node.value = 'giraffe';
205
- ReactTestUtils.Simulate.change(node);
206
-
207
- expect(obj.handler).toHaveBeenCalledWith(
208
- jasmine.objectContaining({target: node}),
209
- );
210
- });
190
+ it('can scry with stateless components involved', () => {
191
+ const Stateless = () => <div><hr /></div>;
192
212
- it('should change the value of an input field in a component', () => {
193
class SomeComponent extends React.Component {
194
render() {
195
return (
196
<div>
217
- <input type="text" ref="input" onChange={this.props.handleChange} />
197
+ <Stateless />
198
+ <hr />
199
</div>
200
);
201
}
202
}
203
223
- const obj = {
224
- handler: function(e) {
225
- e.persist();
226
- },
227
- };
228
- spyOn(obj, 'handler').and.callThrough();
229
- const container = document.createElement('div');
230
- const instance = ReactDOM.render(
231
- <SomeComponent handleChange={obj.handler} />,
232
- container,
233
- );
204
+ const inst = ReactTestUtils.renderIntoDocument(<SomeComponent />);
205
+ const hrs = ReactTestUtils.scryRenderedDOMComponentsWithTag(inst, 'hr');
206
+ expect(hrs.length).toBe(2);
207
+ });
208
235
- const node = ReactDOM.findDOMNode(instance.refs.input);
236
- node.value = 'zebra';
237
- ReactTestUtils.Simulate.change(node);
209
+ describe('Simulate', () => {
210
+ it('should change the value of an input field', () => {
211
+ const obj = {
212
+ handler: function(e) {
213
+ e.persist();
214
+ },
215
+ };
216
+ spyOn(obj, 'handler').and.callThrough();
217
+ const container = document.createElement('div');
218
+ const instance = ReactDOM.render(
219
+ <input type="text" onChange={obj.handler} />,
220
+ container,
221
+ );
222
239
- expect(obj.handler).toHaveBeenCalledWith(
240
- jasmine.objectContaining({target: node}),
241
- );
242
- });
223
+ const node = ReactDOM.findDOMNode(instance);
224
+ node.value = 'giraffe';
225
+ ReactTestUtils.Simulate.change(node);
226
244
- it('should throw when attempting to use ReactTestUtils.Simulate with shallow rendering', () => {
245
- class SomeComponent extends React.Component {
246
- render() {
247
- return (
248
- <div onClick={this.props.handleClick}>
249
- hello, world.
250
- </div>
251
- );
227
+ expect(obj.handler).toHaveBeenCalledWith(
228
+ jasmine.objectContaining({target: node}),
229
+ );
230
+ });
231
+
232
+ it('should change the value of an input field in a component', () => {
233
+ class SomeComponent extends React.Component {
234
+ render() {
235
+ return (
236
+ <div>
237
+ <input
238
+ type="text"
239
+ ref="input"
240
+ onChange={this.props.handleChange}
241
+ />
242
+ </div>
243
+ );
244
+ }
245
}
253
- }
246
255
- const handler = jasmine.createSpy('spy');
256
- const shallowRenderer = createRenderer();
257
- const result = shallowRenderer.render(
258
- <SomeComponent handleClick={handler} />,
259
- );
247
+ const obj = {
248
+ handler: function(e) {
249
+ e.persist();
250
+ },
251
+ };
252
+ spyOn(obj, 'handler').and.callThrough();
253
+ const container = document.createElement('div');
254
+ const instance = ReactDOM.render(
255
+ <SomeComponent handleChange={obj.handler} />,
256
+ container,
257
+ );
258
261
- expect(() => ReactTestUtils.Simulate.click(result)).toThrowError(
262
- 'TestUtils.Simulate expects a component instance and not a ReactElement.' +
263
- 'TestUtils.Simulate will not work if you are using shallow rendering.',
264
- );
265
- expect(handler).not.toHaveBeenCalled();
266
- });
259
+ const node = ReactDOM.findDOMNode(instance.refs.input);
260
+ node.value = 'zebra';
261
+ ReactTestUtils.Simulate.change(node);
262
268
- it('should not warn when simulating events with extra properties', () => {
269
- spyOn(console, 'error');
263
+ expect(obj.handler).toHaveBeenCalledWith(
264
+ jasmine.objectContaining({target: node}),
265
+ );
266
+ });
267
271
- const CLIENT_X = 100;
268
+ it('should throw when attempting to use a React element', () => {
269
+ class SomeComponent extends React.Component {
270
+ render() {
271
+ return (
272
+ <div onClick={this.props.handleClick}>
273
+ hello, world.
274
+ </div>
275
+ );
276
+ }
277
+ }
278
273
- class Component extends React.Component {
274
- handleClick = e => {
275
- expect(e.clientX).toBe(CLIENT_X);
276
- };
279
+ const handler = jasmine.createSpy('spy');
280
+ const shallowRenderer = createRenderer();
281
+ const result = shallowRenderer.render(
282
+ <SomeComponent handleClick={handler} />,
283
+ );
284
278
- render() {
279
- return <div onClick={this.handleClick} />;
285
+ expect(() => ReactTestUtils.Simulate.click(result)).toThrowError(
286
+ 'TestUtils.Simulate expected a DOM node as the first argument but received ' +
287
+ 'a React element. Pass the DOM node you wish to simulate the event on instead. ' +
288
+ 'Note that TestUtils.Simulate will not work if you are using shallow rendering.',
289
+ );
290
+ expect(handler).not.toHaveBeenCalled();
291
+ });
292
+
293
+ it('should throw when attempting to use a component instance', () => {
294
+ class SomeComponent extends React.Component {
295
+ render() {
296
+ return (
297
+ <div onClick={this.props.handleClick}>
298
+ hello, world.
299
+ </div>
300
+ );
301
+ }
302
}
281
- }
303
283
- const element = document.createElement('div');
284
- const instance = ReactDOM.render(<Component />, element);
285
- ReactTestUtils.Simulate.click(ReactDOM.findDOMNode(instance), {
286
- clientX: CLIENT_X,
304
+ const handler = jasmine.createSpy('spy');
305
+ const container = document.createElement('div');
306
+ const instance = ReactDOM.render(
307
+ <SomeComponent handleClick={handler} />,
308
+ container,
309
+ );
310
+
311
+ expect(() => ReactTestUtils.Simulate.click(instance)).toThrowError(
312
+ 'TestUtils.Simulate expected a DOM node as the first argument but received ' +
313
+ 'a component instance. Pass the DOM node you wish to simulate the event on instead.',
314
+ );
315
+ expect(handler).not.toHaveBeenCalled();
316
});
288
- expectDev(console.error.calls.count()).toBe(0);
289
- });
317
291
- it('can scry with stateless components involved', () => {
292
- const Stateless = () => <div><hr /></div>;
318
+ it('should not warn when used with extra properties', () => {
319
+ spyOn(console, 'error');
320
294
- class SomeComponent extends React.Component {
295
- render() {
296
- return (
297
- <div>
298
- <Stateless />
299
- <hr />
300
- </div>
301
- );
321
+ const CLIENT_X = 100;
322
+
323
+ class Component extends React.Component {
324
+ handleClick = e => {
325
+ expect(e.clientX).toBe(CLIENT_X);
326
+ };
327
+
328
+ render() {
329
+ return <div onClick={this.handleClick} />;
330
+ }
331
}
303
- }
332
305
- const inst = ReactTestUtils.renderIntoDocument(<SomeComponent />);
306
- const hrs = ReactTestUtils.scryRenderedDOMComponentsWithTag(inst, 'hr');
307
- expect(hrs.length).toBe(2);
308
- });
333
+ const element = document.createElement('div');
334
+ const instance = ReactDOM.render(<Component />, element);
335
+ ReactTestUtils.Simulate.click(ReactDOM.findDOMNode(instance), {
336
+ clientX: CLIENT_X,
337
+ });
338
+ expectDev(console.error.calls.count()).toBe(0);
339
+ });
340
310
- describe('Simulate', () => {
341
it('should set the type of the event', () => {
342
let event;
343
const stub = jest.genMockFn().mockImplementation(e => {