atagen

malice

public
Star0
Watch0
235ce394f90da8ff124691ee4ee2997c979e7d3c
2
ssh://brewery@pls.lobotomise.me:33/atagen/malice.git
web/test/longpress.test.tsTypescript89 lines2.2 KB
1
import assert from 'node:assert/strict';
2
import { test } from 'node:test';
3
import { PressTracker, type Timers } from '../src/lib/longpress.ts';
4
5
function clock() {
6
  let now = 0;
7
  let next = 1;
8
  const queue = new Map<number, { at: number; fn: () => void }>();
9
  const timers: Timers = {
10
    set(fn, ms) {
11
      const id = next++;
12
      queue.set(id, { at: now + ms, fn });
13
      return id;
14
    },
15
    clear(handle) {
16
      queue.delete(handle as number);
17
    }
18
  };
19
  const advance = (ms: number) => {
20
    now += ms;
21
    for (const [id, t] of [...queue]) {
22
      if (t.at <= now) {
23
        queue.delete(id);
24
        t.fn();
25
      }
26
    }
27
  };
28
  return { timers, advance };
29
}
30
31
function setup() {
32
  const c = clock();
33
  const fires: Array<[number, number]> = [];
34
  const tracker = new PressTracker((x, y) => fires.push([x, y]), c.timers);
35
  return { ...c, tracker, fires };
36
}
37
38
test('fires with the press origin after the delay', () => {
39
  const { tracker, advance, fires } = setup();
40
  tracker.start(10, 20);
41
  advance(449);
42
  assert.deepEqual(fires, []);
43
  advance(1);
44
  assert.deepEqual(fires, [[10, 20]]);
45
  assert.equal(tracker.fired, true);
46
});
47
48
test('release before the delay cancels', () => {
49
  const { tracker, advance, fires } = setup();
50
  tracker.start(0, 0);
51
  advance(200);
52
  tracker.cancel();
53
  advance(1000);
54
  assert.deepEqual(fires, []);
55
  assert.equal(tracker.fired, false);
56
});
57
58
test('small jitter is tolerated, a drag cancels', () => {
59
  const a = setup();
60
  a.tracker.start(0, 0);
61
  a.tracker.move(4, 4);
62
  a.advance(450);
63
  assert.equal(a.fires.length, 1);
64
  const b = setup();
65
  b.tracker.start(0, 0);
66
  b.tracker.move(9, 0);
67
  b.advance(450);
68
  assert.equal(b.fires.length, 0);
69
});
70
71
test('a new press clears the fired flag', () => {
72
  const { tracker, advance } = setup();
73
  tracker.start(0, 0);
74
  advance(450);
75
  tracker.start(5, 5);
76
  assert.equal(tracker.fired, false);
77
  assert.equal(tracker.pending, true);
78
});
79
80
test('flush fires a pending press once and ignores an idle tracker', () => {
81
  const { tracker, advance, fires } = setup();
82
  tracker.flush();
83
  assert.equal(fires.length, 0);
84
  tracker.start(3, 4);
85
  tracker.flush();
86
  advance(1000);
87
  assert.deepEqual(fires, [[3, 4]]);
88
  assert.equal(tracker.fired, true);
89
});