-
Notifications
You must be signed in to change notification settings - Fork 68
Expand file tree
/
Copy pathgesture_handler.test.js
More file actions
92 lines (83 loc) · 3.79 KB
/
Copy pathgesture_handler.test.js
File metadata and controls
92 lines (83 loc) · 3.79 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
import { createGestureHandlers, DOUBLE_TAP_WINDOW_MS, HOLD_TIME_MS } from './gesture_handler';
beforeEach(() => {
vi.useFakeTimers();
});
afterEach(() => {
vi.useRealTimers();
});
describe('createGestureHandlers', () => {
it('dispatches a tap immediately when no double-tap action is configured', () => {
const dispatch = vi.fn();
const { onDown, onUp } = createGestureHandlers(dispatch, { hasHold: true, hasDoubleTap: false });
onDown();
onUp();
expect(dispatch).toHaveBeenCalledExactlyOnceWith(false, false);
});
it('dispatches a tap after the double-tap window elapses when no second tap follows', () => {
const dispatch = vi.fn();
const { onDown, onUp } = createGestureHandlers(dispatch, { hasHold: true, hasDoubleTap: true });
onDown();
onUp();
expect(dispatch).not.toHaveBeenCalled();
vi.advanceTimersByTime(DOUBLE_TAP_WINDOW_MS);
expect(dispatch).toHaveBeenCalledExactlyOnceWith(false, false);
});
it('dispatches a double-tap when a second tap arrives within the window', () => {
const dispatch = vi.fn();
const { onDown, onUp } = createGestureHandlers(dispatch, { hasHold: true, hasDoubleTap: true });
onDown();
onUp();
vi.advanceTimersByTime(DOUBLE_TAP_WINDOW_MS / 2);
onDown();
onUp();
expect(dispatch).toHaveBeenCalledExactlyOnceWith(false, true);
});
it('dispatches a hold when the pointer is held past the hold threshold', () => {
const dispatch = vi.fn();
const { onDown, onUp } = createGestureHandlers(dispatch, { hasHold: true, hasDoubleTap: false });
onDown();
vi.advanceTimersByTime(HOLD_TIME_MS);
onUp();
expect(dispatch).toHaveBeenCalledExactlyOnceWith(true, false);
});
// Matches HA's native rows: without a hold_action, a long-press is just a slow tap.
it('resolves a long-press as a tap when no hold action is configured', () => {
const dispatch = vi.fn();
const { onDown, onUp } = createGestureHandlers(dispatch, { hasHold: false, hasDoubleTap: false });
onDown();
vi.advanceTimersByTime(HOLD_TIME_MS * 2);
onUp();
expect(dispatch).toHaveBeenCalledExactlyOnceWith(false, false);
});
it('does not dispatch a hold if released before the hold threshold', () => {
const dispatch = vi.fn();
const { onDown, onUp } = createGestureHandlers(dispatch, { hasHold: true, hasDoubleTap: false });
onDown();
vi.advanceTimersByTime(HOLD_TIME_MS - 50);
onUp();
expect(dispatch).toHaveBeenCalledExactlyOnceWith(false, false);
});
it('does not dispatch anything on cancel, and does not leave a stale hold pending', () => {
const dispatch = vi.fn();
const { onDown, onCancel } = createGestureHandlers(dispatch, { hasHold: true, hasDoubleTap: false });
onDown();
onCancel();
vi.advanceTimersByTime(HOLD_TIME_MS + DOUBLE_TAP_WINDOW_MS);
expect(dispatch).not.toHaveBeenCalled();
});
it('treats a hold on the second tap of what could have been a double-tap as a hold', () => {
const dispatch = vi.fn();
const { onDown, onUp } = createGestureHandlers(dispatch, { hasHold: true, hasDoubleTap: true });
onDown();
onUp();
vi.advanceTimersByTime(DOUBLE_TAP_WINDOW_MS / 2);
onDown();
vi.advanceTimersByTime(HOLD_TIME_MS);
onUp();
// The pending single-tap from the first press fires once its own window elapses,
// independent of the second press's hold - both are legitimate, distinct gestures here.
vi.runAllTimers();
expect(dispatch).toHaveBeenCalledWith(true, false);
});
});