]> git.proxmox.com Git - mirror_novnc.git/blame - tests/test.gesturehandler.js
Merge pull request #1414 from CendioOssman/gesture
[mirror_novnc.git] / tests / test.gesturehandler.js
CommitLineData
8be924c9
PO
1const expect = chai.expect;
2
3import EventTargetMixin from '../core/util/eventtarget.js';
4
5import GestureHandler from '../core/input/gesturehandler.js';
6import * as browser from '../core/util/browser.js';
7
8class DummyTarget extends EventTargetMixin {
9}
10
11describe('Gesture handler', function () {
12 let target, handler;
13 let gestures;
14 let clock;
15 let touches;
16
17 before(function () {
18 clock = sinon.useFakeTimers();
19 });
20
21 after(function () {
22 clock.restore();
23 });
24
25 beforeEach(function () {
26 // Touch events and gestures are not supported on IE
27 if (browser.isIE()) {
28 this.skip();
29 return;
30 }
31
32 target = new DummyTarget();
33 gestures = sinon.spy();
34 target.addEventListener('gesturestart', gestures);
35 target.addEventListener('gesturemove', gestures);
36 target.addEventListener('gestureend', gestures);
37 touches = [];
38 handler = new GestureHandler();
39 handler.attach(target);
40 });
41
42 afterEach(function () {
43 handler.detach();
44 target = null;
45 gestures = null;
46 });
47
48 function touchStart(id, x, y) {
49 let touch = { identifier: id,
50 clientX: x, clientY: y };
51 touches.push(touch);
52 let ev = { type: 'touchstart',
53 touches: touches,
54 targetTouches: touches,
55 changedTouches: [ touch ],
56 stopPropagation: sinon.spy(),
57 preventDefault: sinon.spy() };
58 target.dispatchEvent(ev);
59 }
60
61 function touchMove(id, x, y) {
62 let touch = touches.find(t => t.identifier === id);
63 touch.clientX = x;
64 touch.clientY = y;
65 let ev = { type: 'touchmove',
66 touches: touches,
67 targetTouches: touches,
68 changedTouches: [ touch ],
69 stopPropagation: sinon.spy(),
70 preventDefault: sinon.spy() };
71 target.dispatchEvent(ev);
72 }
73
74 function touchEnd(id) {
75 let idx = touches.findIndex(t => t.identifier === id);
76 let touch = touches.splice(idx, 1)[0];
77 let ev = { type: 'touchend',
78 touches: touches,
79 targetTouches: touches,
80 changedTouches: [ touch ],
81 stopPropagation: sinon.spy(),
82 preventDefault: sinon.spy() };
83 target.dispatchEvent(ev);
84 }
85
86 describe('Single finger tap', function () {
87 it('should handle single finger tap', function () {
88 touchStart(1, 20.0, 30.0);
89
90 expect(gestures).to.not.have.been.called;
91
92 touchEnd(1);
93
94 expect(gestures).to.have.been.calledTwice;
95
96 expect(gestures.firstCall).to.have.been.calledWith(
97 sinon.match({ type: 'gesturestart',
98 detail: { type: 'onetap',
99 clientX: 20.0,
100 clientY: 30.0 } }));
101
102 expect(gestures.secondCall).to.have.been.calledWith(
103 sinon.match({ type: 'gestureend',
104 detail: { type: 'onetap',
105 clientX: 20.0,
106 clientY: 30.0 } }));
107 });
108 });
109
110 describe('Two finger tap', function () {
111 it('should handle two finger tap', function () {
112 touchStart(1, 20.0, 30.0);
113 touchStart(2, 30.0, 50.0);
114
115 expect(gestures).to.not.have.been.called;
116
117 touchEnd(1);
118
119 expect(gestures).to.not.have.been.called;
120
121 touchEnd(2);
122
123 expect(gestures).to.have.been.calledTwice;
124
125 expect(gestures.firstCall).to.have.been.calledWith(
126 sinon.match({ type: 'gesturestart',
127 detail: { type: 'twotap',
128 clientX: 25.0,
129 clientY: 40.0 } }));
130
131 expect(gestures.secondCall).to.have.been.calledWith(
132 sinon.match({ type: 'gestureend',
133 detail: { type: 'twotap',
134 clientX: 25.0,
135 clientY: 40.0 } }));
136 });
137
138 it('should ignore slow starting two finger tap', function () {
139 touchStart(1, 20.0, 30.0);
140
141 clock.tick(500);
142
143 touchStart(2, 30.0, 50.0);
144 touchEnd(1);
145 touchEnd(2);
146
147 expect(gestures).to.not.have.been.called;
148 });
149
150 it('should ignore slow ending two finger tap', function () {
151 touchStart(1, 20.0, 30.0);
152 touchStart(2, 30.0, 50.0);
153 touchEnd(1);
154
155 clock.tick(500);
156
157 touchEnd(2);
158
159 expect(gestures).to.not.have.been.called;
160 });
161
162 it('should ignore slow two finger tap', function () {
163 touchStart(1, 20.0, 30.0);
164 touchStart(2, 30.0, 50.0);
165
166 clock.tick(1500);
167
168 touchEnd(1);
169 touchEnd(2);
170
171 expect(gestures).to.not.have.been.called;
172 });
173 });
174
175 describe('Three finger tap', function () {
176 it('should handle three finger tap', function () {
177 touchStart(1, 20.0, 30.0);
178 touchStart(2, 30.0, 50.0);
179 touchStart(3, 40.0, 40.0);
180
181 expect(gestures).to.not.have.been.called;
182
183 touchEnd(1);
184
185 expect(gestures).to.not.have.been.called;
186
187 touchEnd(2);
188
189 expect(gestures).to.not.have.been.called;
190
191 touchEnd(3);
192
193 expect(gestures).to.have.been.calledTwice;
194
195 expect(gestures.firstCall).to.have.been.calledWith(
196 sinon.match({ type: 'gesturestart',
197 detail: { type: 'threetap',
198 clientX: 30.0,
199 clientY: 40.0 } }));
200
201 expect(gestures.secondCall).to.have.been.calledWith(
202 sinon.match({ type: 'gestureend',
203 detail: { type: 'threetap',
204 clientX: 30.0,
205 clientY: 40.0 } }));
206 });
207
208 it('should ignore slow starting three finger tap', function () {
209 touchStart(1, 20.0, 30.0);
210 touchStart(2, 30.0, 50.0);
211
212 clock.tick(500);
213
214 touchStart(3, 40.0, 40.0);
215 touchEnd(1);
216 touchEnd(2);
217 touchEnd(3);
218
219 expect(gestures).to.not.have.been.called;
220 });
221
222 it('should ignore slow ending three finger tap', function () {
223 touchStart(1, 20.0, 30.0);
224 touchStart(2, 30.0, 50.0);
225 touchStart(3, 40.0, 40.0);
226 touchEnd(1);
227 touchEnd(2);
228
229 clock.tick(500);
230
231 touchEnd(3);
232
233 expect(gestures).to.not.have.been.called;
234 });
235
236 it('should ignore three finger drag', function () {
237 touchStart(1, 20.0, 30.0);
238 touchStart(2, 30.0, 50.0);
239 touchStart(3, 40.0, 40.0);
240
241 touchMove(1, 120.0, 130.0);
242 touchMove(2, 130.0, 150.0);
243 touchMove(3, 140.0, 140.0);
244
245 touchEnd(1);
246 touchEnd(2);
247 touchEnd(3);
248
249 expect(gestures).to.not.have.been.called;
250 });
251
252 it('should ignore slow three finger tap', function () {
253 touchStart(1, 20.0, 30.0);
254 touchStart(2, 30.0, 50.0);
255 touchStart(3, 40.0, 40.0);
256
257 clock.tick(1500);
258
259 touchEnd(1);
260 touchEnd(2);
261 touchEnd(3);
262
263 expect(gestures).to.not.have.been.called;
264 });
265 });
266
267 describe('Single finger drag', function () {
268 it('should handle horizontal single finger drag', function () {
269 touchStart(1, 20.0, 30.0);
270
271 expect(gestures).to.not.have.been.called;
272
273 touchMove(1, 40.0, 30.0);
274
275 expect(gestures).to.not.have.been.called;
276
277 touchMove(1, 80.0, 30.0);
278
279 expect(gestures).to.have.been.calledTwice;
280
281 expect(gestures.firstCall).to.have.been.calledWith(
282 sinon.match({ type: 'gesturestart',
283 detail: { type: 'drag',
284 clientX: 20.0,
285 clientY: 30.0 } }));
286
287 expect(gestures.secondCall).to.have.been.calledWith(
288 sinon.match({ type: 'gesturemove',
289 detail: { type: 'drag',
290 clientX: 80.0,
291 clientY: 30.0 } }));
292
293 gestures.resetHistory();
294
295 touchEnd(1);
296
297 expect(gestures).to.have.been.calledOnceWith(
298 sinon.match({ type: 'gestureend',
299 detail: { type: 'drag',
300 clientX: 80.0,
301 clientY: 30.0 } }));
302 });
303
304 it('should handle vertical single finger drag', function () {
305 touchStart(1, 20.0, 30.0);
306
307 expect(gestures).to.not.have.been.called;
308
309 touchMove(1, 20.0, 50.0);
310
311 expect(gestures).to.not.have.been.called;
312
313 touchMove(1, 20.0, 90.0);
314
315 expect(gestures).to.have.been.calledTwice;
316
317 expect(gestures.firstCall).to.have.been.calledWith(
318 sinon.match({ type: 'gesturestart',
319 detail: { type: 'drag',
320 clientX: 20.0,
321 clientY: 30.0 } }));
322
323 expect(gestures.secondCall).to.have.been.calledWith(
324 sinon.match({ type: 'gesturemove',
325 detail: { type: 'drag',
326 clientX: 20.0,
327 clientY: 90.0 } }));
328
329 gestures.resetHistory();
330
331 touchEnd(1);
332
333 expect(gestures).to.have.been.calledOnceWith(
334 sinon.match({ type: 'gestureend',
335 detail: { type: 'drag',
336 clientX: 20.0,
337 clientY: 90.0 } }));
338 });
339
340 it('should handle diagonal single finger drag', function () {
341 touchStart(1, 120.0, 130.0);
342
343 expect(gestures).to.not.have.been.called;
344
345 touchMove(1, 90.0, 100.0);
346
347 expect(gestures).to.not.have.been.called;
348
349 touchMove(1, 60.0, 70.0);
350
351 expect(gestures).to.have.been.calledTwice;
352
353 expect(gestures.firstCall).to.have.been.calledWith(
354 sinon.match({ type: 'gesturestart',
355 detail: { type: 'drag',
356 clientX: 120.0,
357 clientY: 130.0 } }));
358
359 expect(gestures.secondCall).to.have.been.calledWith(
360 sinon.match({ type: 'gesturemove',
361 detail: { type: 'drag',
362 clientX: 60.0,
363 clientY: 70.0 } }));
364
365 gestures.resetHistory();
366
367 touchEnd(1);
368
369 expect(gestures).to.have.been.calledOnceWith(
370 sinon.match({ type: 'gestureend',
371 detail: { type: 'drag',
372 clientX: 60.0,
373 clientY: 70.0 } }));
374 });
375 });
376
377 describe('Long press', function () {
378 it('should handle long press', function () {
379 touchStart(1, 20.0, 30.0);
380
381 expect(gestures).to.not.have.been.called;
382
383 clock.tick(1500);
384
385 expect(gestures).to.have.been.calledOnceWith(
386 sinon.match({ type: 'gesturestart',
387 detail: { type: 'longpress',
388 clientX: 20.0,
389 clientY: 30.0 } }));
390
391 gestures.resetHistory();
392
393 touchEnd(1);
394
395 expect(gestures).to.have.been.calledOnceWith(
396 sinon.match({ type: 'gestureend',
397 detail: { type: 'longpress',
398 clientX: 20.0,
399 clientY: 30.0 } }));
400 });
401
402 it('should handle long press drag', function () {
403 touchStart(1, 20.0, 30.0);
404
405 expect(gestures).to.not.have.been.called;
406
407 clock.tick(1500);
408
409 expect(gestures).to.have.been.calledOnceWith(
410 sinon.match({ type: 'gesturestart',
411 detail: { type: 'longpress',
412 clientX: 20.0,
413 clientY: 30.0 } }));
414
415 gestures.resetHistory();
416
417 touchMove(1, 120.0, 50.0);
418
419 expect(gestures).to.have.been.calledOnceWith(
420 sinon.match({ type: 'gesturemove',
421 detail: { type: 'longpress',
422 clientX: 120.0,
423 clientY: 50.0 } }));
424
425 gestures.resetHistory();
426
427 touchEnd(1);
428
429 expect(gestures).to.have.been.calledOnceWith(
430 sinon.match({ type: 'gestureend',
431 detail: { type: 'longpress',
432 clientX: 120.0,
433 clientY: 50.0 } }));
434 });
435 });
436
437 describe('Two finger drag', function () {
438 it('should handle fast and distinct horizontal two finger drag', function () {
439 touchStart(1, 20.0, 30.0);
440 touchStart(2, 30.0, 30.0);
441
442 expect(gestures).to.not.have.been.called;
443
444 touchMove(1, 40.0, 30.0);
445 touchMove(2, 50.0, 30.0);
446
447 expect(gestures).to.not.have.been.called;
448
449 touchMove(2, 90.0, 30.0);
450 touchMove(1, 80.0, 30.0);
451
452 expect(gestures).to.have.been.calledTwice;
453
454 expect(gestures.firstCall).to.have.been.calledWith(
455 sinon.match({ type: 'gesturestart',
456 detail: { type: 'twodrag',
457 clientX: 25.0,
458 clientY: 30.0,
459 magnitudeX: 0.0,
460 magnitudeY: 0.0 } }));
461
462 expect(gestures.secondCall).to.have.been.calledWith(
463 sinon.match({ type: 'gesturemove',
464 detail: { type: 'twodrag',
465 clientX: 25.0,
466 clientY: 30.0,
467 magnitudeX: 60.0,
468 magnitudeY: 0.0 } }));
469
470 gestures.resetHistory();
471
472 touchEnd(1);
473
474 expect(gestures).to.have.been.calledOnceWith(
475 sinon.match({ type: 'gestureend',
476 detail: { type: 'twodrag',
477 clientX: 25.0,
478 clientY: 30.0,
479 magnitudeX: 60.0,
480 magnitudeY: 0.0 } }));
481 });
482
483 it('should handle fast and distinct vertical two finger drag', function () {
484 touchStart(1, 20.0, 30.0);
485 touchStart(2, 30.0, 30.0);
486
487 expect(gestures).to.not.have.been.called;
488
489 touchMove(1, 20.0, 100.0);
490 touchMove(2, 30.0, 40.0);
491
492 expect(gestures).to.not.have.been.called;
493
494 touchMove(2, 30.0, 90.0);
495
496 expect(gestures).to.have.been.calledTwice;
497
498 expect(gestures.firstCall).to.have.been.calledWith(
499 sinon.match({ type: 'gesturestart',
500 detail: { type: 'twodrag',
501 clientX: 25.0,
502 clientY: 30.0,
503 magnitudeX: 0.0,
504 magnitudeY: 0.0 } }));
505
506 expect(gestures.secondCall).to.have.been.calledWith(
507 sinon.match({ type: 'gesturemove',
508 detail: { type: 'twodrag',
509 clientX: 25.0,
510 clientY: 30.0,
511 magnitudeX: 0.0,
512 magnitudeY: 65.0 } }));
513
514 gestures.resetHistory();
515
516 touchEnd(1);
517
518 expect(gestures).to.have.been.calledOnceWith(
519 sinon.match({ type: 'gestureend',
520 detail: { type: 'twodrag',
521 clientX: 25.0,
522 clientY: 30.0,
523 magnitudeX: 0.0,
524 magnitudeY: 65.0 } }));
525 });
526
527 it('should handle fast and distinct diagonal two finger drag', function () {
528 touchStart(1, 120.0, 130.0);
529 touchStart(2, 130.0, 130.0);
530
531 expect(gestures).to.not.have.been.called;
532
533 touchMove(1, 80.0, 90.0);
534 touchMove(2, 100.0, 130.0);
535
536 expect(gestures).to.not.have.been.called;
537
538 touchMove(2, 60.0, 70.0);
539
540 expect(gestures).to.have.been.calledTwice;
541
542 expect(gestures.firstCall).to.have.been.calledWith(
543 sinon.match({ type: 'gesturestart',
544 detail: { type: 'twodrag',
545 clientX: 125.0,
546 clientY: 130.0,
547 magnitudeX: 0.0,
548 magnitudeY: 0.0 } }));
549
550 expect(gestures.secondCall).to.have.been.calledWith(
551 sinon.match({ type: 'gesturemove',
552 detail: { type: 'twodrag',
553 clientX: 125.0,
554 clientY: 130.0,
555 magnitudeX: -55.0,
556 magnitudeY: -50.0 } }));
557
558 gestures.resetHistory();
559
560 touchEnd(1);
561
562 expect(gestures).to.have.been.calledOnceWith(
563 sinon.match({ type: 'gestureend',
564 detail: { type: 'twodrag',
565 clientX: 125.0,
566 clientY: 130.0,
567 magnitudeX: -55.0,
568 magnitudeY: -50.0 } }));
569 });
570
571 it('should ignore fast almost two finger dragging', function () {
572 touchStart(1, 20.0, 30.0);
573 touchStart(2, 30.0, 30.0);
574 touchMove(1, 80.0, 30.0);
575 touchMove(2, 70.0, 30.0);
576 touchEnd(1);
577 touchEnd(2);
578
579 expect(gestures).to.not.have.been.called;
580
581 clock.tick(1500);
582
583 expect(gestures).to.not.have.been.called;
584 });
585
586 it('should handle slow horizontal two finger drag', function () {
587 touchStart(1, 50.0, 40.0);
588 touchStart(2, 60.0, 40.0);
589 touchMove(1, 80.0, 40.0);
590 touchMove(2, 110.0, 40.0);
591
592 expect(gestures).to.not.have.been.called;
593
594 clock.tick(60);
595
596 expect(gestures).to.have.been.calledTwice;
597
598 expect(gestures.firstCall).to.have.been.calledWith(
599 sinon.match({ type: 'gesturestart',
600 detail: { type: 'twodrag',
601 clientX: 55.0,
602 clientY: 40.0,
603 magnitudeX: 0.0,
604 magnitudeY: 0.0 } }));
605
606 expect(gestures.secondCall).to.have.been.calledWith(
607 sinon.match({ type: 'gesturemove',
608 detail: { type: 'twodrag',
609 clientX: 55.0,
610 clientY: 40.0,
611 magnitudeX: 40.0,
612 magnitudeY: 0.0 } }));
613 });
614
615 it('should handle slow vertical two finger drag', function () {
616 touchStart(1, 40.0, 40.0);
617 touchStart(2, 40.0, 60.0);
618 touchMove(2, 40.0, 80.0);
619 touchMove(1, 40.0, 100.0);
620
621 expect(gestures).to.not.have.been.called;
622
623 clock.tick(60);
624
625 expect(gestures).to.have.been.calledTwice;
626
627 expect(gestures.firstCall).to.have.been.calledWith(
628 sinon.match({ type: 'gesturestart',
629 detail: { type: 'twodrag',
630 clientX: 40.0,
631 clientY: 50.0,
632 magnitudeX: 0.0,
633 magnitudeY: 0.0 } }));
634
635 expect(gestures.secondCall).to.have.been.calledWith(
636 sinon.match({ type: 'gesturemove',
637 detail: { type: 'twodrag',
638 clientX: 40.0,
639 clientY: 50.0,
640 magnitudeX: 0.0,
641 magnitudeY: 40.0 } }));
642 });
643
644 it('should handle slow diagonal two finger drag', function () {
645 touchStart(1, 50.0, 40.0);
646 touchStart(2, 40.0, 60.0);
647 touchMove(1, 70.0, 60.0);
648 touchMove(2, 90.0, 110.0);
649
650 expect(gestures).to.not.have.been.called;
651
652 clock.tick(60);
653
654 expect(gestures).to.have.been.calledTwice;
655
656 expect(gestures.firstCall).to.have.been.calledWith(
657 sinon.match({ type: 'gesturestart',
658 detail: { type: 'twodrag',
659 clientX: 45.0,
660 clientY: 50.0,
661 magnitudeX: 0.0,
662 magnitudeY: 0.0 } }));
663
664 expect(gestures.secondCall).to.have.been.calledWith(
665 sinon.match({ type: 'gesturemove',
666 detail: { type: 'twodrag',
667 clientX: 45.0,
668 clientY: 50.0,
669 magnitudeX: 35.0,
670 magnitudeY: 35.0 } }));
671 });
672
673 it('should ignore too slow two finger drag', function () {
674 touchStart(1, 20.0, 30.0);
675
676 clock.tick(500);
677
678 touchStart(2, 30.0, 30.0);
679 touchMove(1, 40.0, 30.0);
680 touchMove(2, 50.0, 30.0);
681 touchMove(1, 80.0, 30.0);
682
683 expect(gestures).to.not.have.been.called;
684 });
685 });
686
687 describe('Pinch', function () {
688 it('should handle pinching distinctly and fast inwards', function () {
689 touchStart(1, 0.0, 0.0);
690 touchStart(2, 130.0, 130.0);
691
692 expect(gestures).to.not.have.been.called;
693
694 touchMove(1, 50.0, 40.0);
695 touchMove(2, 100.0, 130.0);
696
697 expect(gestures).to.not.have.been.called;
698
699 touchMove(2, 60.0, 70.0);
700
701 expect(gestures).to.have.been.calledTwice;
702
703 expect(gestures.firstCall).to.have.been.calledWith(
704 sinon.match({ type: 'gesturestart',
705 detail: { type: 'pinch',
706 clientX: 65.0,
707 clientY: 65.0,
708 magnitudeX: 130.0,
709 magnitudeY: 130.0 } }));
710
711 expect(gestures.secondCall).to.have.been.calledWith(
712 sinon.match({ type: 'gesturemove',
713 detail: { type: 'pinch',
714 clientX: 65.0,
715 clientY: 65.0,
716 magnitudeX: 10.0,
717 magnitudeY: 30.0 } }));
718
719 gestures.resetHistory();
720
721 touchEnd(1);
722
723 expect(gestures).to.have.been.calledOnceWith(
724 sinon.match({ type: 'gestureend',
725 detail: { type: 'pinch',
726 clientX: 65.0,
727 clientY: 65.0,
728 magnitudeX: 10.0,
729 magnitudeY: 30.0 } }));
730 });
731
732 it('should handle pinching fast and distinctly outwards', function () {
733 touchStart(1, 100.0, 100.0);
734 touchStart(2, 110.0, 100.0);
735
736 expect(gestures).to.not.have.been.called;
737
738 touchMove(1, 130.0, 70.0);
739 touchMove(2, 0.0, 200.0);
740
741 expect(gestures).to.not.have.been.called;
742
743 touchMove(1, 180.0, 20.0);
744
745 expect(gestures).to.have.been.calledTwice;
746
747 expect(gestures.firstCall).to.have.been.calledWith(
748 sinon.match({ type: 'gesturestart',
749 detail: { type: 'pinch',
750 clientX: 105.0,
751 clientY: 100.0,
752 magnitudeX: 10.0,
753 magnitudeY: 0.0 } }));
754
755 expect(gestures.secondCall).to.have.been.calledWith(
756 sinon.match({ type: 'gesturemove',
757 detail: { type: 'pinch',
758 clientX: 105.0,
759 clientY: 100.0,
760 magnitudeX: 180.0,
761 magnitudeY: 180.0 } }));
762
763 gestures.resetHistory();
764
765 touchEnd(1);
766
767 expect(gestures).to.have.been.calledOnceWith(
768 sinon.match({ type: 'gestureend',
769 detail: { type: 'pinch',
770 clientX: 105.0,
771 clientY: 100.0,
772 magnitudeX: 180.0,
773 magnitudeY: 180.0 } }));
774 });
775
776 it('should ignore fast almost pinching', function () {
777 touchStart(1, 20.0, 30.0);
778 touchStart(2, 130.0, 130.0);
779 touchMove(1, 80.0, 70.0);
780 touchEnd(1);
781 touchEnd(2);
782
783 expect(gestures).to.not.have.been.called;
784
785 clock.tick(1500);
786
787 expect(gestures).to.not.have.been.called;
788 });
789
790 it('should handle pinching inwards slowly', function () {
791 touchStart(1, 0.0, 0.0);
792 touchStart(2, 130.0, 130.0);
793 touchMove(1, 50.0, 40.0);
794 touchMove(2, 100.0, 130.0);
795
796 expect(gestures).to.not.have.been.called;
797
798 clock.tick(60);
799
800 expect(gestures).to.have.been.calledTwice;
801
802 expect(gestures.firstCall).to.have.been.calledWith(
803 sinon.match({ type: 'gesturestart',
804 detail: { type: 'pinch',
805 clientX: 65.0,
806 clientY: 65.0,
807 magnitudeX: 130.0,
808 magnitudeY: 130.0 } }));
809
810 expect(gestures.secondCall).to.have.been.calledWith(
811 sinon.match({ type: 'gesturemove',
812 detail: { type: 'pinch',
813 clientX: 65.0,
814 clientY: 65.0,
815 magnitudeX: 50.0,
816 magnitudeY: 90.0 } }));
817 });
818
819 it('should handle pinching outwards slowly', function () {
820 touchStart(1, 100.0, 130.0);
821 touchStart(2, 110.0, 130.0);
822 touchMove(2, 200.0, 130.0);
823
824 expect(gestures).to.not.have.been.called;
825
826 clock.tick(60);
827
828 expect(gestures).to.have.been.calledTwice;
829
830 expect(gestures.firstCall).to.have.been.calledWith(
831 sinon.match({ type: 'gesturestart',
832 detail: { type: 'pinch',
833 clientX: 105.0,
834 clientY: 130.0,
835 magnitudeX: 10.0,
836 magnitudeY: 0.0 } }));
837
838 expect(gestures.secondCall).to.have.been.calledWith(
839 sinon.match({ type: 'gesturemove',
840 detail: { type: 'pinch',
841 clientX: 105.0,
842 clientY: 130.0,
843 magnitudeX: 100.0,
844 magnitudeY: 0.0 } }));
845 });
846
847 it('should ignore pinching too slowly', function () {
848 touchStart(1, 0.0, 0.0);
849
850 clock.tick(500);
851
852 touchStart(2, 130.0, 130.0);
853 touchMove(2, 100.0, 130.0);
854 touchMove(1, 50.0, 40.0);
855
856 expect(gestures).to.not.have.been.called;
857 });
858 });
859
860 describe('Ignoring', function () {
861 it('should ignore extra touches during gesture', function () {
862 touchStart(1, 20.0, 30.0);
863 touchMove(1, 40.0, 30.0);
864 touchMove(1, 80.0, 30.0);
865
866 expect(gestures).to.have.been.calledTwice;
867
868 expect(gestures.firstCall).to.have.been.calledWith(
869 sinon.match({ type: 'gesturestart',
870 detail: { type: 'drag' } }));
871 expect(gestures.secondCall).to.have.been.calledWith(
872 sinon.match({ type: 'gesturemove',
873 detail: { type: 'drag' } }));
874
875 gestures.resetHistory();
876
877 touchStart(2, 10.0, 10.0);
878
879 expect(gestures).to.not.have.been.called;
880
881 touchMove(1, 100.0, 50.0);
882
883 expect(gestures).to.have.been.calledOnceWith(
884 sinon.match({ type: 'gesturemove',
885 detail: { type: 'drag',
886 clientX: 100.0,
887 clientY: 50.0 } }));
888
889 gestures.resetHistory();
890
891 touchEnd(1);
892
893 expect(gestures).to.have.been.calledOnceWith(
894 sinon.match({ type: 'gestureend',
895 detail: { type: 'drag',
896 clientX: 100.0,
897 clientY: 50.0 } }));
898 });
899
900 it('should ignore extra touches when waiting for gesture to end', function () {
901 touchStart(1, 20.0, 30.0);
902 touchStart(2, 30.0, 30.0);
903 touchMove(1, 40.0, 30.0);
904 touchMove(2, 90.0, 30.0);
905 touchMove(1, 80.0, 30.0);
906
907 expect(gestures).to.have.been.calledTwice;
908
909 expect(gestures.firstCall).to.have.been.calledWith(
910 sinon.match({ type: 'gesturestart',
911 detail: { type: 'twodrag' } }));
912 expect(gestures.secondCall).to.have.been.calledWith(
913 sinon.match({ type: 'gesturemove',
914 detail: { type: 'twodrag' } }));
915
916 gestures.resetHistory();
917
918 touchEnd(1);
919
920 expect(gestures).to.have.been.calledOnceWith(
921 sinon.match({ type: 'gestureend',
922 detail: { type: 'twodrag' } }));
923
924 gestures.resetHistory();
925
926 touchStart(3, 10.0, 10.0);
927 touchEnd(3);
928
929 expect(gestures).to.not.have.been.called;
930 });
931
932 it('should ignore extra touches after gesture', function () {
933 touchStart(1, 20.0, 30.0);
934 touchMove(1, 40.0, 30.0);
935 touchMove(1, 80.0, 30.0);
936
937 expect(gestures).to.have.been.calledTwice;
938
939 expect(gestures.firstCall).to.have.been.calledWith(
940 sinon.match({ type: 'gesturestart',
941 detail: { type: 'drag' } }));
942 expect(gestures.secondCall).to.have.been.calledWith(
943 sinon.match({ type: 'gesturemove',
944 detail: { type: 'drag' } }));
945
946 gestures.resetHistory();
947
948 touchStart(2, 10.0, 10.0);
949
950 expect(gestures).to.not.have.been.called;
951
952 touchMove(1, 100.0, 50.0);
953
954 expect(gestures).to.have.been.calledOnceWith(
955 sinon.match({ type: 'gesturemove',
956 detail: { type: 'drag' } }));
957
958 gestures.resetHistory();
959
960 touchEnd(1);
961
962 expect(gestures).to.have.been.calledOnceWith(
963 sinon.match({ type: 'gestureend',
964 detail: { type: 'drag' } }));
965
966 gestures.resetHistory();
967
968 touchEnd(2);
969
970 expect(gestures).to.not.have.been.called;
971
972 // Check that everything is reseted after trailing ignores are released
973
974 touchStart(3, 20.0, 30.0);
975 touchEnd(3);
976
977 expect(gestures).to.have.been.calledTwice;
978
979 expect(gestures.firstCall).to.have.been.calledWith(
980 sinon.match({ type: 'gesturestart',
981 detail: { type: 'onetap' } }));
982 expect(gestures.secondCall).to.have.been.calledWith(
983 sinon.match({ type: 'gestureend',
984 detail: { type: 'onetap' } }));
985 });
986
987 it('should properly reset after a gesture', function () {
988 touchStart(1, 20.0, 30.0);
989
990 expect(gestures).to.not.have.been.called;
991
992 touchEnd(1);
993
994 expect(gestures).to.have.been.calledTwice;
995
996 expect(gestures.firstCall).to.have.been.calledWith(
997 sinon.match({ type: 'gesturestart',
998 detail: { type: 'onetap',
999 clientX: 20.0,
1000 clientY: 30.0 } }));
1001
1002 expect(gestures.secondCall).to.have.been.calledWith(
1003 sinon.match({ type: 'gestureend',
1004 detail: { type: 'onetap',
1005 clientX: 20.0,
1006 clientY: 30.0 } }));
1007
1008 gestures.resetHistory();
1009
1010 touchStart(2, 70.0, 80.0);
1011
1012 expect(gestures).to.not.have.been.called;
1013
1014 touchEnd(2);
1015
1016 expect(gestures).to.have.been.calledTwice;
1017
1018 expect(gestures.firstCall).to.have.been.calledWith(
1019 sinon.match({ type: 'gesturestart',
1020 detail: { type: 'onetap',
1021 clientX: 70.0,
1022 clientY: 80.0 } }));
1023
1024 expect(gestures.secondCall).to.have.been.calledWith(
1025 sinon.match({ type: 'gestureend',
1026 detail: { type: 'onetap',
1027 clientX: 70.0,
1028 clientY: 80.0 } }));
1029 });
1030 });
1031});