9
10
'use strict';
11
12
-import {
13
- click,
14
- dispatchPointerCancel,
15
- dispatchPointerDown,
16
- dispatchPointerUp,
17
- dispatchPointerHoverMove,
18
- dispatchPointerMove,
19
- keydown,
20
- keyup,
21
- scroll,
22
- pointerdown,
23
- pointerup,
24
- setPointerEvent,
25
-} from '../test-utils';
12
+import {createEventTarget, setPointerEvent} from '../testing-library';
13
14
let React;
15
let ReactFeatureFlags;
16
let ReactDOM;
17
let PressResponder;
18
let usePressResponder;
32
-let Scheduler;
19
20
function initializeModules(hasPointerEvents) {
21
jest.resetModules();
26
ReactDOM = require('react-dom');
27
PressResponder = require('react-events/press').PressResponder;
28
usePressResponder = require('react-events/press').usePressResponder;
43
- Scheduler = require('scheduler');
29
}
30
31
function removePressMoveStrings(eventString) {
77
});
78
79
it('does not call callbacks', () => {
95
- const target = ref.current;
96
- dispatchPointerDown(target);
97
- dispatchPointerUp(target);
80
+ const target = createEventTarget(ref.current);
81
+ target.pointerdown();
82
+ target.pointerup();
83
expect(onPressStart).not.toBeCalled();
84
expect(onPress).not.toBeCalled();
85
expect(onPressEnd).not.toBeCalled();
105
it.each(pointerTypesTable)(
106
'is called after pointer down: %s',
107
pointerType => {
123
- dispatchPointerDown(ref.current, {pointerType});
108
+ const target = createEventTarget(ref.current);
109
+ target.pointerdown({pointerType});
110
expect(onPressStart).toHaveBeenCalledTimes(1);
111
expect(onPressStart).toHaveBeenCalledWith(
112
expect.objectContaining({pointerType, type: 'pressstart'}),
115
);
116
117
it('is called after auxillary-button pointer down', () => {
132
- dispatchPointerDown(ref.current, {button: 1, pointerType: 'mouse'});
118
+ const target = createEventTarget(ref.current);
119
+ target.pointerdown({button: 1, pointerType: 'mouse'});
120
expect(onPressStart).toHaveBeenCalledTimes(1);
121
expect(onPressStart).toHaveBeenCalledWith(
122
expect.objectContaining({
127
);
128
});
129
143
- it('is not called after "pointermove" following auxillary-button press', () => {
144
- const target = ref.current;
145
- target.getBoundingClientRect = () => ({
146
- top: 0,
147
- left: 0,
148
- bottom: 100,
149
- right: 100,
150
- });
151
- dispatchPointerDown(target, {
152
- button: 1,
153
- pointerType: 'mouse',
154
- });
155
- dispatchPointerUp(target, {
156
- button: 1,
157
- pointerType: 'mouse',
158
- });
159
- dispatchPointerHoverMove(target, {x: 110, y: 110});
160
- dispatchPointerHoverMove(target, {x: 50, y: 50});
130
+ it('is not called after pointer move following auxillary-button press', () => {
131
+ const node = ref.current;
132
+ const target = createEventTarget(node);
133
+ target.setBoundingClientRect({x: 0, y: 0, width: 100, height: 100});
134
+ target.pointerdown({button: 1, pointerType: 'mouse'});
135
+ target.pointerup({button: 1, pointerType: 'mouse'});
136
+ target.pointerhover({x: 110, y: 110});
137
+ target.pointerhover({x: 50, y: 50});
138
expect(onPressStart).toHaveBeenCalledTimes(1);
139
});
140
141
it('ignores any events not caused by primary/auxillary-click or touch/pen contact', () => {
165
- const target = ref.current;
166
- dispatchPointerDown(target, {button: 2});
167
- dispatchPointerDown(target, {button: 5});
142
+ const target = createEventTarget(ref.current);
143
+ target.pointerdown({button: 2});
144
+ target.pointerup({button: 2});
145
+ target.pointerdown({button: 5});
146
+ target.pointerup({button: 5});
147
expect(onPressStart).toHaveBeenCalledTimes(0);
148
});
149
150
it('is called once after "keydown" events for Enter', () => {
172
- const target = ref.current;
173
- target.dispatchEvent(keydown({key: 'Enter'}));
174
- target.dispatchEvent(keydown({key: 'Enter'}));
175
- target.dispatchEvent(keydown({key: 'Enter'}));
151
+ const target = createEventTarget(ref.current);
152
+ target.keydown({key: 'Enter'});
153
+ target.keydown({key: 'Enter'});
154
+ target.keydown({key: 'Enter'});
155
expect(onPressStart).toHaveBeenCalledTimes(1);
156
expect(onPressStart).toHaveBeenCalledWith(
157
expect.objectContaining({pointerType: 'keyboard', type: 'pressstart'}),
159
});
160
161
it('is called once after "keydown" events for Spacebar', () => {
183
- const target = ref.current;
162
+ const target = createEventTarget(ref.current);
163
const preventDefault = jest.fn();
185
- target.dispatchEvent(keydown({key: ' ', preventDefault}));
164
+ target.keydown({key: ' ', preventDefault});
165
expect(preventDefault).toBeCalled();
187
- target.dispatchEvent(keydown({key: ' ', preventDefault}));
166
+ target.keydown({key: ' ', preventDefault});
167
expect(onPressStart).toHaveBeenCalledTimes(1);
168
expect(onPressStart).toHaveBeenCalledWith(
169
expect.objectContaining({
174
});
175
176
it('is not called after "keydown" for other keys', () => {
198
- ref.current.dispatchEvent(keydown({key: 'a'}));
177
+ const target = createEventTarget(ref.current);
178
+ target.keydown({key: 'a'});
179
expect(onPressStart).not.toBeCalled();
180
});
181
});
199
it.each(pointerTypesTable)(
200
'is called after pointer up: %s',
201
pointerType => {
222
- const target = ref.current;
223
- dispatchPointerDown(target, {pointerType});
224
- dispatchPointerUp(target, {pointerType});
202
+ const target = createEventTarget(ref.current);
203
+ target.pointerdown({pointerType});
204
+ target.pointerup({pointerType});
205
expect(onPressEnd).toHaveBeenCalledTimes(1);
206
expect(onPressEnd).toHaveBeenCalledWith(
207
expect.objectContaining({pointerType, type: 'pressend'}),
210
);
211
212
it('is called after auxillary-button pointer up', () => {
233
- const target = ref.current;
234
- dispatchPointerDown(target, {button: 1, pointerType: 'mouse'});
235
- dispatchPointerUp(target, {button: 1, pointerType: 'mouse'});
213
+ const target = createEventTarget(ref.current);
214
+ target.pointerdown({button: 1, pointerType: 'mouse'});
215
+ target.pointerup({button: 1, pointerType: 'mouse'});
216
expect(onPressEnd).toHaveBeenCalledTimes(1);
217
expect(onPressEnd).toHaveBeenCalledWith(
218
expect.objectContaining({
224
});
225
226
it('is called after "keyup" event for Enter', () => {
247
- const target = ref.current;
248
- target.dispatchEvent(keydown({key: 'Enter'}));
227
+ const target = createEventTarget(ref.current);
228
+ target.keydown({key: 'Enter'});
229
// click occurs before keyup
250
- target.dispatchEvent(click());
251
- target.dispatchEvent(keyup({key: 'Enter'}));
230
+ target.click();
231
+ target.keyup({key: 'Enter'});
232
expect(onPressEnd).toHaveBeenCalledTimes(1);
233
expect(onPressEnd).toHaveBeenCalledWith(
234
expect.objectContaining({pointerType: 'keyboard', type: 'pressend'}),
236
});
237
238
it('is called after "keyup" event for Spacebar', () => {
259
- const target = ref.current;
260
- target.dispatchEvent(keydown({key: ' '}));
261
- target.dispatchEvent(keyup({key: ' '}));
239
+ const target = createEventTarget(ref.current);
240
+ target.keydown({key: ' '});
241
+ target.keyup({key: ' '});
242
expect(onPressEnd).toHaveBeenCalledTimes(1);
243
expect(onPressEnd).toHaveBeenCalledWith(
244
expect.objectContaining({pointerType: 'keyboard', type: 'pressend'}),
246
});
247
248
it('is not called after "keyup" event for other keys', () => {
269
- const target = ref.current;
270
- target.dispatchEvent(keydown({key: 'Enter'}));
271
- target.dispatchEvent(keyup({key: 'a'}));
249
+ const target = createEventTarget(ref.current);
250
+ target.keydown({key: 'Enter'});
251
+ target.keyup({key: 'a'});
252
expect(onPressEnd).not.toBeCalled();
253
});
254
255
it('is called with keyboard modifiers', () => {
276
- const target = ref.current;
277
- target.dispatchEvent(keydown({key: 'Enter'}));
278
- target.dispatchEvent(
279
- keyup({
280
- key: 'Enter',
281
- metaKey: true,
282
- ctrlKey: true,
283
- altKey: true,
284
- shiftKey: true,
285
- }),
286
- );
256
+ const target = createEventTarget(ref.current);
257
+ target.keydown({key: 'Enter'});
258
+ target.keyup({
259
+ key: 'Enter',
260
+ metaKey: true,
261
+ ctrlKey: true,
262
+ altKey: true,
263
+ shiftKey: true,
264
+ });
265
expect(onPressEnd).toHaveBeenCalledWith(
266
expect.objectContaining({
267
pointerType: 'keyboard',
294
it.each(pointerTypesTable)(
295
'is called after pointer down and up: %s',
296
pointerType => {
319
- const target = ref.current;
320
- dispatchPointerDown(target, {pointerType});
297
+ const target = createEventTarget(ref.current);
298
+ target.pointerdown({pointerType});
299
expect(onPressChange).toHaveBeenCalledTimes(1);
300
expect(onPressChange).toHaveBeenCalledWith(true);
323
- dispatchPointerUp(target, {pointerType});
301
+ target.pointerup({pointerType});
302
expect(onPressChange).toHaveBeenCalledTimes(2);
303
expect(onPressChange).toHaveBeenCalledWith(false);
304
},
305
);
306
307
it('is called after valid "keydown" and "keyup" events', () => {
330
- ref.current.dispatchEvent(keydown({key: 'Enter'}));
308
+ const target = createEventTarget(ref.current);
309
+ target.keydown({key: 'Enter'});
310
expect(onPressChange).toHaveBeenCalledTimes(1);
311
expect(onPressChange).toHaveBeenCalledWith(true);
333
- ref.current.dispatchEvent(keyup({key: 'Enter'}));
312
+ target.keyup({key: 'Enter'});
313
expect(onPressChange).toHaveBeenCalledTimes(2);
314
expect(onPressChange).toHaveBeenCalledWith(false);
315
});
340
it.each(pointerTypesTable)(
341
'is called after pointer up: %s',
342
pointerType => {
364
- const target = ref.current;
365
- dispatchPointerDown(target, {pointerType});
366
- dispatchPointerUp(target, {pointerType, x: 10, y: 10});
343
+ const target = createEventTarget(ref.current);
344
+ target.pointerdown({pointerType});
345
+ target.pointerup({pointerType, x: 10, y: 10});
346
expect(onPress).toHaveBeenCalledTimes(1);
347
expect(onPress).toHaveBeenCalledWith(
348
expect.objectContaining({pointerType, type: 'press'}),
351
);
352
353
it('is not called after auxillary-button press', () => {
375
- const target = ref.current;
376
- dispatchPointerDown(target, {button: 1, pointerType: 'mouse'});
377
- dispatchPointerUp(target, {button: 1, pointerType: 'mouse'});
354
+ const target = createEventTarget(ref.current);
355
+ target.pointerdown({button: 1, pointerType: 'mouse'});
356
+ target.pointerup({button: 1, pointerType: 'mouse'});
357
expect(onPress).not.toHaveBeenCalled();
358
});
359
360
it('is called after valid "keyup" event', () => {
382
- const target = ref.current;
383
- target.dispatchEvent(keydown({key: 'Enter'}));
384
- target.dispatchEvent(keyup({key: 'Enter'}));
361
+ const target = createEventTarget(ref.current);
362
+ target.keydown({key: 'Enter'});
363
+ target.keyup({key: 'Enter'});
364
expect(onPress).toHaveBeenCalledTimes(1);
365
expect(onPress).toHaveBeenCalledWith(
366
expect.objectContaining({pointerType: 'keyboard', type: 'press'}),
370
it('is not called after invalid "keyup" event', () => {
371
const inputRef = React.createRef();
372
const Component = () => {
394
- const listener = usePressResponder({
395
- onPress,
396
- });
373
+ const listener = usePressResponder({onPress});
374
return <input ref={inputRef} listeners={listener} />;
375
};
376
ReactDOM.render(<Component />, container);
400
- const target = inputRef.current;
401
- target.dispatchEvent(keydown({key: 'Enter'}));
402
- target.dispatchEvent(keyup({key: 'Enter'}));
403
- target.dispatchEvent(keydown({key: ' '}));
404
- target.dispatchEvent(keyup({key: ' '}));
377
+ const target = createEventTarget(inputRef.current);
378
+ target.keydown({key: 'Enter'});
379
+ target.keyup({key: 'Enter'});
380
+ target.keydown({key: ' '});
381
+ target.keyup({key: ' '});
382
expect(onPress).not.toBeCalled();
383
});
384
385
it('is called with modifier keys', () => {
409
- const target = ref.current;
410
- dispatchPointerDown(target, {metaKey: true, pointerType: 'mouse'});
411
- dispatchPointerUp(target, {
412
- metaKey: true,
413
- pointerType: 'mouse',
414
- });
386
+ const target = createEventTarget(ref.current);
387
+ target.pointerdown({metaKey: true, pointerType: 'mouse'});
388
+ target.pointerup({metaKey: true, pointerType: 'mouse'});
389
expect(onPress).toHaveBeenCalledWith(
390
expect.objectContaining({
391
pointerType: 'mouse',
400
const divRef = React.createRef();
401
402
const Component = () => {
429
- const listener = usePressResponder({
430
- onPress,
431
- });
403
+ const listener = usePressResponder({onPress});
404
return (
405
<div ref={divRef} listeners={listener}>
406
<button ref={buttonRef} />
409
};
410
ReactDOM.render(<Component />, container);
411
440
- divRef.current.getBoundingClientRect = () => ({
441
- left: 0,
442
- right: 0,
443
- bottom: 0,
444
- top: 0,
445
- });
446
- const target = buttonRef.current;
447
- dispatchPointerDown(target, {pointerType: 'mouse'});
448
- dispatchPointerUp(target, {pointerType: 'mouse'});
412
+ const target = createEventTarget(divRef.current);
413
+ target.setBoundingClientRect({x: 0, y: 0, width: 0, height: 0});
414
+ const innerTarget = createEventTarget(buttonRef.current);
415
+ innerTarget.pointerdown({pointerType: 'mouse'});
416
+ innerTarget.pointerup({pointerType: 'mouse'});
417
expect(onPress).toBeCalled();
418
});
419
});
443
it.each(pointerTypesTable)(
444
'is called after pointer move: %s',
445
pointerType => {
478
- const target = ref.current;
479
- target.getBoundingClientRect = () => ({
480
- top: 0,
481
- left: 0,
482
- bottom: 100,
483
- right: 100,
484
- });
485
- dispatchPointerDown(target, {pointerType});
486
- dispatchPointerMove(target, {
487
- pointerType,
488
- x: 10,
489
- y: 10,
490
- });
491
- dispatchPointerMove(target, {
492
- pointerType,
493
- x: 20,
494
- y: 20,
495
- });
446
+ const node = ref.current;
447
+ const target = createEventTarget(node);
448
+ target.setBoundingClientRect({x: 0, y: 0, width: 100, height: 100});
449
+ target.pointerdown({pointerType});
450
+ target.pointermove({pointerType, x: 10, y: 10});
451
+ target.pointermove({pointerType, x: 20, y: 20});
452
expect(onPressMove).toHaveBeenCalledTimes(2);
453
expect(onPressMove).toHaveBeenCalledWith(
454
expect.objectContaining({pointerType, type: 'pressmove'}),
457
);
458
459
it('is not called if pointer move occurs during keyboard press', () => {
504
- const target = ref.current;
505
- target.getBoundingClientRect = () => ({
506
- top: 0,
507
- left: 0,
508
- bottom: 100,
509
- right: 100,
510
- });
511
- target.dispatchEvent(keydown({key: 'Enter'}));
512
- dispatchPointerMove(target, {
513
- button: -1,
514
- pointerType: 'mouse',
515
- x: 10,
516
- y: 10,
517
- });
460
+ const target = createEventTarget(ref.current);
461
+ target.setBoundingClientRect({x: 0, y: 0, width: 100, height: 100});
462
+ target.keydown({key: 'Enter'});
463
+ target.pointermove({button: -1, pointerType: 'mouse', x: 10, y: 10});
464
expect(onPressMove).not.toBeCalled();
465
});
466
});
493
document.elementFromPoint = () => ref.current;
494
});
495
550
- const rectMock = {
551
- width: 100,
552
- height: 100,
553
- top: 50,
554
- left: 50,
555
- right: 150,
556
- bottom: 150,
557
- };
496
+ const rectMock = {width: 100, height: 100, x: 50, y: 50};
497
const pressRectOffset = 20;
559
- const getBoundingClientRectMock = () => rectMock;
498
const coordinatesInside = {
561
- x: rectMock.left - pressRectOffset,
562
- y: rectMock.top - pressRectOffset,
499
+ x: rectMock.x - pressRectOffset,
500
+ y: rectMock.y - pressRectOffset,
501
};
502
const coordinatesOutside = {
565
- x: rectMock.left - pressRectOffset - 1,
566
- y: rectMock.top - pressRectOffset - 1,
503
+ x: rectMock.x - pressRectOffset - 1,
504
+ y: rectMock.y - pressRectOffset - 1,
505
};
506
507
describe('within bounds of hit rect', () => {
513
* └──────────────────┘
514
*/
515
it('"onPress*" events are called immediately', () => {
578
- const target = ref.current;
579
- target.getBoundingClientRect = getBoundingClientRectMock;
580
- dispatchPointerDown(target, {pointerType});
581
- dispatchPointerMove(target, {pointerType, ...coordinatesInside});
582
- dispatchPointerUp(target, {pointerType, ...coordinatesInside});
583
- jest.runAllTimers();
516
+ const target = createEventTarget(ref.current);
517
+ target.setBoundingClientRect(rectMock);
518
+ target.pointerdown({pointerType});
519
+ target.pointermove({pointerType, ...coordinatesInside});
520
+ target.pointerup({pointerType, ...coordinatesInside});
521
expect(events).toEqual([
522
'onPressStart',
523
'onPressChange',
529
});
530
531
it('"onPress*" events are correctly called with target change', () => {
595
- const target = ref.current;
596
- const outer = outerRef.current;
597
- target.getBoundingClientRect = getBoundingClientRectMock;
598
- dispatchPointerDown(target, {pointerType});
599
- dispatchPointerMove(target, {pointerType, ...coordinatesInside});
532
+ const target = createEventTarget(ref.current);
533
+ const outerTarget = createEventTarget(outerRef.current);
534
+ target.setBoundingClientRect(rectMock);
535
+ target.pointerdown({pointerType});
536
+ target.pointermove({pointerType, ...coordinatesInside});
537
// TODO: this sequence may differ in the future between PointerEvent and mouse fallback when
538
// use 'setPointerCapture'.
539
if (pointerType === 'touch') {
603
- dispatchPointerMove(target, {pointerType, ...coordinatesOutside});
540
+ target.pointermove({pointerType, ...coordinatesOutside});
541
} else {
605
- dispatchPointerMove(outer, {pointerType, ...coordinatesOutside});
542
+ outerTarget.pointermove({pointerType, ...coordinatesOutside});
543
}
607
- dispatchPointerMove(target, {pointerType, ...coordinatesInside});
608
- dispatchPointerUp(target, {pointerType, ...coordinatesInside});
544
+ target.pointermove({pointerType, ...coordinatesInside});
545
+ target.pointerup({pointerType, ...coordinatesInside});
546
547
expect(events.filter(removePressMoveStrings)).toEqual([
548
'onPressStart',
578
};
579
ReactDOM.render(<Component />, container);
580
644
- const target = localRef.current;
645
- target.getBoundingClientRect = getBoundingClientRectMock;
646
- dispatchPointerDown(target, {pointerType});
647
- dispatchPointerMove(target, {
581
+ const target = createEventTarget(localRef.current);
582
+ target.setBoundingClientRect(rectMock);
583
+ target.pointerdown({pointerType});
584
+ target.pointermove({
585
pointerType,
649
- x: rectMock.left,
650
- y: rectMock.top,
586
+ x: rectMock.x,
587
+ y: rectMock.y,
588
});
652
- dispatchPointerUp(target, {pointerType, ...coordinatesInside});
589
+ target.pointerup({pointerType, ...coordinatesInside});
590
expect(localEvents).toEqual([
591
'onPressStart',
592
'onPressChange',
598
});
599
600
it('responder region accounts for decrease in element dimensions', () => {
664
- const target = ref.current;
665
- target.getBoundingClientRect = getBoundingClientRectMock;
666
- dispatchPointerDown(target, {pointerType});
601
+ const target = createEventTarget(ref.current);
602
+ target.setBoundingClientRect(rectMock);
603
+ target.pointerdown({pointerType});
604
// emulate smaller dimensions change on activation
668
- target.getBoundingClientRect = () => ({
669
- width: 80,
670
- height: 80,
671
- top: 60,
672
- left: 60,
673
- right: 490,
674
- bottom: 490,
675
- });
676
- const coordinates = {
677
- x: rectMock.left,
678
- y: rectMock.top,
679
- };
605
+ target.setBoundingClientRect({width: 80, height: 80, y: 60, x: 60});
606
+ const coordinates = {x: rectMock.x, y: rectMock.y};
607
// move to an area within the pre-activation region
681
- dispatchPointerMove(target, {pointerType, ...coordinates});
682
- dispatchPointerUp(target, {pointerType, ...coordinates});
608
+ target.pointermove({pointerType, ...coordinates});
609
+ target.pointerup({pointerType, ...coordinates});
610
expect(events).toEqual([
611
'onPressStart',
612
'onPressChange',
618
});
619
620
it('responder region accounts for increase in element dimensions', () => {
694
- const target = ref.current;
695
- target.getBoundingClientRect = getBoundingClientRectMock;
696
- dispatchPointerDown(target, {pointerType});
621
+ const target = createEventTarget(ref.current);
622
+ target.setBoundingClientRect(rectMock);
623
+ target.pointerdown({pointerType});
624
// emulate larger dimensions change on activation
698
- target.getBoundingClientRect = () => ({
699
- width: 200,
700
- height: 200,
701
- top: 0,
702
- left: 0,
703
- right: 550,
704
- bottom: 550,
705
- });
706
- const coordinates = {
707
- x: rectMock.left - 50,
708
- y: rectMock.top - 50,
709
- };
625
+ target.setBoundingClientRect({width: 200, height: 200, y: 0, x: 0});
626
+ const coordinates = {x: rectMock.x - 50, y: rectMock.y - 50};
627
// move to an area within the post-activation region
711
- dispatchPointerMove(target, {pointerType, ...coordinates});
712
- dispatchPointerUp(target, {pointerType, ...coordinates});
628
+ target.pointermove({pointerType, ...coordinates});
629
+ target.pointerup({pointerType, ...coordinates});
630
expect(events).toEqual([
631
'onPressStart',
632
'onPressChange',
648
* X <= Move to X and release
649
*/
650
it('"onPress" is not called on release', () => {
734
- const target = ref.current;
735
- target.getBoundingClientRect = getBoundingClientRectMock;
736
- dispatchPointerDown(target, {pointerType});
737
- dispatchPointerMove(target, {pointerType, ...coordinatesInside});
651
+ const target = createEventTarget(ref.current);
652
+ const targetContainer = createEventTarget(container);
653
+ target.setBoundingClientRect(rectMock);
654
+ target.pointerdown({pointerType});
655
+ target.pointermove({pointerType, ...coordinatesInside});
656
if (pointerType === 'mouse') {
657
// TODO: use setPointerCapture so this is only true for fallback mouse events.
740
- dispatchPointerMove(container, {pointerType, ...coordinatesOutside});
658
+ targetContainer.pointermove({pointerType, ...coordinatesOutside});
659
+ targetContainer.pointerup({pointerType, ...coordinatesOutside});
660
} else {
742
- dispatchPointerMove(target, {pointerType, ...coordinatesOutside});
661
+ target.pointermove({pointerType, ...coordinatesOutside});
662
+ target.pointerup({pointerType, ...coordinatesOutside});
663
}
744
- dispatchPointerUp(container, {pointerType, ...coordinatesOutside});
664
expect(events.filter(removePressMoveStrings)).toEqual([
665
'onPressStart',
666
'onPressChange',
671
});
672
673
it('"onPress" is called on re-entry to hit rect', () => {
755
- const target = ref.current;
756
- target.getBoundingClientRect = getBoundingClientRectMock;
757
- dispatchPointerDown(target, {pointerType});
758
- dispatchPointerMove(target, {pointerType, ...coordinatesInside});
674
+ const target = createEventTarget(ref.current);
675
+ const targetContainer = createEventTarget(container);
676
+ target.setBoundingClientRect(rectMock);
677
+ target.pointerdown({pointerType});
678
+ target.pointermove({pointerType, ...coordinatesInside});
679
if (pointerType === 'mouse') {
680
// TODO: use setPointerCapture so this is only true for fallback mouse events.
761
- dispatchPointerMove(container, {pointerType, ...coordinatesOutside});
681
+ targetContainer.pointermove({pointerType, ...coordinatesOutside});
682
} else {
763
- dispatchPointerMove(target, {pointerType, ...coordinatesOutside});
683
+ target.pointermove({pointerType, ...coordinatesOutside});
684
}
765
- dispatchPointerMove(target, {pointerType, ...coordinatesInside});
766
- dispatchPointerUp(target, {pointerType, ...coordinatesInside});
685
+ target.pointermove({pointerType, ...coordinatesInside});
686
+ target.pointerup({pointerType, ...coordinatesInside});
687
688
expect(events).toEqual([
689
'onPressStart',
746
};
747
ReactDOM.render(<Outer />, container);
748
829
- const target = ref.current;
830
- target.getBoundingClientRect = () => ({
831
- top: 0,
832
- left: 0,
833
- bottom: 100,
834
- right: 100,
835
- });
836
- dispatchPointerDown(target);
837
- dispatchPointerUp(target);
749
+ const target = createEventTarget(ref.current);
750
+ target.setBoundingClientRect({x: 0, y: 0, width: 100, height: 100});
751
+ target.pointerdown();
752
+ target.pointerup();
753
expect(events).toEqual([
754
'inner: onPressStart',
755
'inner: onPressChange',
765
describe('correctly not propagate', () => {
766
it('for onPress', () => {
767
const ref = React.createRef();
853
- const fn = jest.fn();
768
+ const onPress = jest.fn();
769
770
const Inner = () => {
856
- const listener = usePressResponder({
857
- onPress: fn,
858
- });
771
+ const listener = usePressResponder({onPress});
772
return <div ref={ref} listeners={listener} />;
773
};
774
775
const Outer = () => {
863
- const listener = usePressResponder({
864
- onPress: fn,
865
- });
776
+ const listener = usePressResponder({onPress});
777
return (
778
<div listeners={listener}>
779
<Inner />
782
};
783
ReactDOM.render(<Outer />, container);
784
874
- const target = ref.current;
875
- target.getBoundingClientRect = () => ({
876
- top: 0,
877
- left: 0,
878
- bottom: 100,
879
- right: 100,
880
- });
881
- dispatchPointerDown(target);
882
- dispatchPointerUp(target);
883
- expect(fn).toHaveBeenCalledTimes(1);
785
+ const target = createEventTarget(ref.current);
786
+ target.setBoundingClientRect({x: 0, y: 0, width: 100, height: 100});
787
+ target.pointerdown();
788
+ target.pointerup();
789
+ expect(onPress).toHaveBeenCalledTimes(1);
790
});
791
792
it('for onPressStart/onPressEnd', () => {
793
const ref = React.createRef();
888
- const fn = jest.fn();
889
- const fn2 = jest.fn();
794
+ const onPressStart = jest.fn();
795
+ const onPressEnd = jest.fn();
796
797
const Inner = () => {
892
- const listener = usePressResponder({
893
- onPressStart: fn,
894
- onPressEnd: fn2,
895
- });
798
+ const listener = usePressResponder({onPressStart, onPressEnd});
799
return <div ref={ref} listeners={listener} />;
800
};
801
802
const Outer = () => {
900
- const listener = usePressResponder({
901
- onPressStart: fn,
902
- onPressEnd: fn2,
903
- });
803
+ const listener = usePressResponder({onPressStart, onPressEnd});
804
return (
805
<div listeners={listener}>
806
<Inner />
809
};
810
ReactDOM.render(<Outer />, container);
811
912
- const target = ref.current;
913
- dispatchPointerDown(target);
914
- expect(fn).toHaveBeenCalledTimes(1);
915
- expect(fn2).toHaveBeenCalledTimes(0);
916
- dispatchPointerUp(target);
917
- expect(fn).toHaveBeenCalledTimes(1);
918
- expect(fn2).toHaveBeenCalledTimes(1);
812
+ const target = createEventTarget(ref.current);
813
+ target.pointerdown();
814
+ expect(onPressStart).toHaveBeenCalledTimes(1);
815
+ expect(onPressEnd).toHaveBeenCalledTimes(0);
816
+ target.pointerup();
817
+ expect(onPressStart).toHaveBeenCalledTimes(1);
818
+ expect(onPressEnd).toHaveBeenCalledTimes(1);
819
});
820
821
it('for onPressChange', () => {
822
const ref = React.createRef();
923
- const fn = jest.fn();
823
+ const onPressChange = jest.fn();
824
825
const Inner = () => {
926
- const listener = usePressResponder({
927
- onPressChange: fn,
928
- });
826
+ const listener = usePressResponder({onPressChange});
827
return <div ref={ref} listeners={listener} />;
828
};
829
830
const Outer = () => {
933
- const listener = usePressResponder({
934
- onPressChange: fn,
935
- });
831
+ const listener = usePressResponder({onPressChange});
832
return (
833
<div listeners={listener}>
834
<Inner />
837
};
838
ReactDOM.render(<Outer />, container);
839
944
- const target = ref.current;
945
- dispatchPointerDown(target);
946
- expect(fn).toHaveBeenCalledTimes(1);
947
- dispatchPointerUp(target);
948
- expect(fn).toHaveBeenCalledTimes(2);
840
+ const target = createEventTarget(ref.current);
841
+ target.pointerdown();
842
+ expect(onPressChange).toHaveBeenCalledTimes(1);
843
+ target.pointerup();
844
+ expect(onPressChange).toHaveBeenCalledTimes(2);
845
});
846
});
847
});
853
const ref = React.createRef();
854
855
const Component = () => {
960
- const listener = usePressResponder({
961
- onPress,
962
- });
856
+ const listener = usePressResponder({onPress});
857
return <a href="#" ref={ref} listeners={listener} />;
858
};
859
ReactDOM.render(<Component />, container);
860
967
- const target = ref.current;
968
- dispatchPointerDown(target);
969
- dispatchPointerUp(target, {preventDefault});
861
+ const target = createEventTarget(ref.current);
862
+ target.pointerdown();
863
+ target.pointerup({preventDefault});
864
expect(preventDefault).toBeCalled();
865
expect(onPress).toHaveBeenCalledWith(
866
expect.objectContaining({defaultPrevented: true}),
873
const ref = React.createRef();
874
875
const Component = () => {
982
- const listener = usePressResponder({
983
- onPress,
984
- });
876
+ const listener = usePressResponder({onPress});
877
return <a href="#" ref={ref} listeners={listener} />;
878
};
879
ReactDOM.render(<Component />, container);
880
989
- const target = ref.current;
990
- target.dispatchEvent(keydown({key: 'Enter'}));
991
- target.dispatchEvent(click({preventDefault}));
992
- target.dispatchEvent(keyup({key: 'Enter'}));
881
+ const target = createEventTarget(ref.current);
882
+ target.keydown({key: 'Enter'});
883
+ target.click({preventDefault});
884
+ target.keyup({key: 'Enter'});
885
expect(preventDefault).toBeCalled();
886
expect(onPress).toHaveBeenCalledWith(
887
expect.objectContaining({defaultPrevented: true}),
894
const buttonRef = React.createRef();
895
896
const Component = () => {
1005
- const listener = usePressResponder({
1006
- onPress,
1007
- });
897
+ const listener = usePressResponder({onPress});
898
return (
899
<a href="#">
900
<button ref={buttonRef} listeners={listener} />
903
};
904
ReactDOM.render(<Component />, container);
905
1016
- const target = buttonRef.current;
1017
- dispatchPointerDown(target);
1018
- dispatchPointerUp(target, {preventDefault});
906
+ const target = createEventTarget(buttonRef.current);
907
+ target.pointerdown();
908
+ target.pointerup({preventDefault});
909
expect(preventDefault).toBeCalled();
910
});
911
915
const ref = React.createRef();
916
917
const Component = () => {
1028
- const listener = usePressResponder({
1029
- onPress,
1030
- });
918
+ const listener = usePressResponder({onPress});
919
return (
920
<a href="#" listeners={listener}>
921
<div ref={ref} />
924
};
925
ReactDOM.render(<Component />, container);
926
1039
- const target = ref.current;
1040
- dispatchPointerDown(target);
1041
- dispatchPointerUp(target, {preventDefault});
927
+ const target = createEventTarget(ref.current);
928
+ target.pointerdown();
929
+ target.pointerup({preventDefault});
930
expect(preventDefault).toBeCalled();
931
expect(onPress).toHaveBeenCalledWith(
932
expect.objectContaining({defaultPrevented: true}),
939
const ref = React.createRef();
940
941
const Component = () => {
1054
- const listener = usePressResponder({
1055
- onPress,
1056
- });
942
+ const listener = usePressResponder({onPress});
943
return <a href="#" ref={ref} listeners={listener} />;
944
};
945
ReactDOM.render(<Component />, container);
946
947
['metaKey', 'ctrlKey', 'shiftKey'].forEach(modifierKey => {
1062
- const target = ref.current;
1063
- dispatchPointerDown(target, {[modifierKey]: true});
1064
- dispatchPointerUp(target, {[modifierKey]: true, preventDefault});
948
+ const target = createEventTarget(ref.current);
949
+ target.pointerdown({[modifierKey]: true});
950
+ target.pointerup({[modifierKey]: true, preventDefault});
951
expect(preventDefault).not.toBeCalled();
952
expect(onPress).toHaveBeenCalledWith(
953
expect.objectContaining({defaultPrevented: false}),
961
const ref = React.createRef();
962
963
const Component = () => {
1078
- const listener = usePressResponder({
1079
- onPress,
1080
- preventDefault: false,
1081
- });
964
+ const listener = usePressResponder({onPress, preventDefault: false});
965
return <a href="#" ref={ref} listeners={listener} />;
966
};
967
ReactDOM.render(<Component />, container);
968
1086
- const target = ref.current;
1087
- dispatchPointerDown(target);
1088
- dispatchPointerUp(target, {preventDefault});
969
+ const target = createEventTarget(ref.current);
970
+ target.pointerdown();
971
+ target.pointerup({preventDefault});
972
expect(preventDefault).not.toBeCalled();
973
expect(onPress).toHaveBeenCalledWith(
974
expect.objectContaining({defaultPrevented: false}),
981
const ref = React.createRef();
982
983
const Component = () => {
1101
- const listener = usePressResponder({
1102
- onPress,
1103
- preventDefault: false,
1104
- });
984
+ const listener = usePressResponder({onPress, preventDefault: false});
985
return <a href="#" ref={ref} listeners={listener} />;
986
};
987
ReactDOM.render(<Component />, container);
988
1109
- const target = ref.current;
1110
- target.dispatchEvent(keydown({key: 'Enter'}));
1111
- target.dispatchEvent(click({preventDefault}));
1112
- target.dispatchEvent(keyup({key: 'Enter'}));
989
+ const target = createEventTarget(ref.current);
990
+ target.keydown({key: 'Enter'});
991
+ target.click({preventDefault});
992
+ target.keyup({key: 'Enter'});
993
expect(preventDefault).not.toBeCalled();
994
expect(onPress).toHaveBeenCalledWith(
995
expect.objectContaining({defaultPrevented: false}),
1003
const ref = React.createRef();
1004
1005
const Component = () => {
1126
- const listener = usePressResponder({
1127
- onPressEnd,
1128
- });
1006
+ const listener = usePressResponder({onPressEnd});
1007
return <a href="#" ref={ref} listeners={listener} />;
1008
};
1009
ReactDOM.render(<Component />, container);
1010
1133
- const target = ref.current;
1134
- dispatchPointerDown(target, {pointerType});
1135
- dispatchPointerCancel(target, {pointerType});
1011
+ const target = createEventTarget(ref.current);
1012
+ target.pointerdown({pointerType});
1013
+ target.pointercancel({pointerType});
1014
expect(onPressEnd).toHaveBeenCalledTimes(1);
1015
});
1016
});
1020
const ref = React.createRef();
1021
1022
const Component = () => {
1145
- const listener = usePressResponder({
1146
- onPressEnd,
1147
- });
1023
+ const listener = usePressResponder({onPressEnd});
1024
return <a href="#" ref={ref} listeners={listener} />;
1025
};
1026
ReactDOM.render(<Component />, container);
1027
1152
- const target = ref.current;
1153
- dispatchPointerDown(target, {pointerType: 'touch'});
1154
- document.dispatchEvent(scroll());
1028
+ const target = createEventTarget(ref.current);
1029
+ const targetDocument = createEventTarget(document);
1030
+ target.pointerdown({pointerType: 'touch'});
1031
+ targetDocument.scroll();
1032
expect(onPressEnd).toHaveBeenCalledTimes(1);
1033
});
1034
1038
const containerRef = React.createRef();
1039
1040
const Component = () => {
1164
- const listener = usePressResponder({
1165
- onPressEnd,
1166
- });
1041
+ const listener = usePressResponder({onPressEnd});
1042
return (
1043
<div ref={containerRef}>
1044
<a ref={ref} listeners={listener} />
1047
};
1048
ReactDOM.render(<Component />, container);
1049
1175
- dispatchPointerDown(ref.current, {pointerType: 'touch'});
1176
- containerRef.current.dispatchEvent(scroll());
1050
+ const target = createEventTarget(ref.current);
1051
+ const targetContainer = createEventTarget(containerRef.current);
1052
+ target.pointerdown({pointerType: 'touch'});
1053
+ targetContainer.scroll();
1054
expect(onPressEnd).toHaveBeenCalledTimes(1);
1055
});
1056
1060
const outsideRef = React.createRef();
1061
1062
const Component = () => {
1186
- const listener = usePressResponder({
1187
- onPressEnd,
1188
- });
1063
+ const listener = usePressResponder({onPressEnd});
1064
return (
1065
<div>
1066
<a ref={ref} listeners={listener} />
1070
};
1071
ReactDOM.render(<Component />, container);
1072
1198
- dispatchPointerDown(ref.current);
1199
- outsideRef.current.dispatchEvent(scroll());
1073
+ const target = createEventTarget(ref.current);
1074
+ const targetOutside = createEventTarget(outsideRef.current);
1075
+ target.pointerdown();
1076
+ targetOutside.scroll();
1077
expect(onPressEnd).not.toBeCalled();
1078
});
1079
1085
const ref = React.createRef();
1086
1087
const Component = () => {
1211
- return <button ref={ref} responders={<PressResponder />} />;
1088
+ const listener = usePressResponder();
1089
+ return <button ref={ref} listeners={listener} />;
1090
};
1091
ReactDOM.render(<Component />, container);
1092
1215
- const target = ref.current;
1216
- dispatchPointerDown(target);
1217
- dispatchPointerMove(target);
1218
- dispatchPointerUp(target);
1219
- dispatchPointerDown(target);
1093
+ const target = createEventTarget(ref.current);
1094
+ target.pointerdown();
1095
+ target.pointermove();
1096
+ target.pointerup();
1097
+ target.pointerdown();
1098
});
1099
1100
it('should correctly pass through event properties', () => {
1129
};
1130
ReactDOM.render(<Component />, container);
1131
1254
- const target = ref.current;
1255
- target.getBoundingClientRect = () => ({
1256
- top: 10,
1257
- left: 10,
1258
- bottom: 110,
1259
- right: 110,
1260
- });
1261
- dispatchPointerDown(target, {
1132
+ const target = createEventTarget(ref.current);
1133
+ target.setBoundingClientRect({x: 10, y: 10, width: 100, height: 100});
1134
+ target.pointerdown({
1135
pointerType: 'mouse',
1136
pageX: 15,
1137
pageY: 16,
1265
- screenX: 20,
1266
- screenY: 21,
1267
- clientX: 30,
1268
- clientY: 31,
1138
+ x: 30,
1139
+ y: 31,
1140
});
1270
- dispatchPointerMove(target, {
1141
+ target.pointermove({
1142
pointerType: 'mouse',
1143
pageX: 16,
1144
pageY: 17,
1274
- screenX: 21,
1275
- screenY: 22,
1276
- clientX: 31,
1277
- clientY: 32,
1145
+ x: 31,
1146
+ y: 32,
1147
});
1279
- dispatchPointerUp(target, {
1148
+ target.pointerup({
1149
pointerType: 'mouse',
1150
pageX: 17,
1151
pageY: 18,
1283
- screenX: 22,
1284
- screenY: 23,
1285
- clientX: 32,
1286
- clientY: 33,
1152
+ x: 32,
1153
+ y: 33,
1154
});
1288
- dispatchPointerDown(target, {
1155
+ target.pointerdown({
1156
pointerType: 'mouse',
1157
pageX: 18,
1158
pageY: 19,
1292
- screenX: 23,
1293
- screenY: 24,
1294
- clientX: 33,
1295
- clientY: 34,
1159
+ x: 33,
1160
+ y: 34,
1161
});
1162
expect(typeof timeStamps[0] === 'number').toBe(true);
1163
expect(eventLog).toEqual([
1165
pointerType: 'mouse',
1166
pageX: 15,
1167
pageY: 16,
1303
- screenX: 20,
1304
- screenY: 21,
1168
+ screenX: 30,
1169
+ screenY: 81,
1170
clientX: 30,
1171
clientY: 31,
1172
target: ref.current,
1177
pointerType: 'mouse',
1178
pageX: 16,
1179
pageY: 17,
1315
- screenX: 21,
1316
- screenY: 22,
1180
+ screenX: 31,
1181
+ screenY: 82,
1182
clientX: 31,
1183
clientY: 32,
1184
target: ref.current,
1189
pointerType: 'mouse',
1190
pageX: 17,
1191
pageY: 18,
1327
- screenX: 22,
1328
- screenY: 23,
1192
+ screenX: 32,
1193
+ screenY: 83,
1194
clientX: 32,
1195
clientY: 33,
1196
target: ref.current,
1201
pointerType: 'mouse',
1202
pageX: 17,
1203
pageY: 18,
1339
- screenX: 22,
1340
- screenY: 23,
1204
+ screenX: 32,
1205
+ screenY: 83,
1206
clientX: 32,
1207
clientY: 33,
1208
target: ref.current,
1213
pointerType: 'mouse',
1214
pageX: 18,
1215
pageY: 19,
1351
- screenX: 23,
1352
- screenY: 24,
1216
+ screenX: 33,
1217
+ screenY: 84,
1218
clientX: 33,
1219
clientY: 34,
1220
target: ref.current,
1225
});
1226
1227
if (hasPointerEvents) {
1228
+ // TODO(T46067442): move these tests to core
1229
+ /*
1230
it('should properly only flush sync once when the event systems are mixed', () => {
1231
const ref = React.createRef();
1232
let renderCounts = 0;
1424
expect(ops).toEqual(['Presses: 0, Clicks: 0']);
1425
},
1426
);
1560
-
1427
+ */
1428
it('should work correctly with stopPropagation set to true', () => {
1429
const ref = React.createRef();
1430
const pointerDownEvent = jest.fn();
1436
1437
container.addEventListener('pointerdown', pointerDownEvent);
1438
ReactDOM.render(<Component />, container);
1572
- dispatchPointerDown(ref.current);
1439
+ createEventTarget(ref.current).pointerdown();
1440
container.removeEventListener('pointerdown', pointerDownEvent);
1441
expect(pointerDownEvent).toHaveBeenCalledTimes(0);
1442
});