mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-23 15:36:33 +00:00
117 lines
4.0 KiB
TypeScript
117 lines
4.0 KiB
TypeScript
// FE-MAP-PRESS-001 to FE-MAP-PRESS-008: only a real click on the map places a point, never a drag or a long hold.
|
|
import { describe, expect, it } from 'vitest';
|
|
import { createPressTracker, isPlacementTap, TAP_MAX_DURATION_MS, TAP_MAX_TRAVEL_PX } from './mapPress';
|
|
|
|
function pointer(type: string, x: number, y: number, pointerId = 1): Event {
|
|
const event = new Event(type, { bubbles: true, cancelable: true });
|
|
Object.defineProperties(event, {
|
|
clientX: { value: x },
|
|
clientY: { value: y },
|
|
pointerId: { value: pointerId },
|
|
});
|
|
return event;
|
|
}
|
|
|
|
/** A tracker on a fresh element, with a clock the test moves. */
|
|
function setup() {
|
|
const el = document.createElement('div');
|
|
let clock = 0;
|
|
const tracker = createPressTracker(el, () => clock);
|
|
return {
|
|
el,
|
|
tracker,
|
|
at: (ms: number) => {
|
|
clock = ms;
|
|
},
|
|
send: (type: string, x: number, y: number, id = 1) => el.dispatchEvent(pointer(type, x, y, id)),
|
|
};
|
|
}
|
|
|
|
describe('isPlacementTap', () => {
|
|
it('FE-MAP-PRESS-001: a short press that barely moved places', () => {
|
|
expect(isPlacementTap({ travelPx: 0, durationMs: 80, pointers: 1 })).toBe(true);
|
|
expect(
|
|
isPlacementTap({ travelPx: TAP_MAX_TRAVEL_PX - 0.5, durationMs: TAP_MAX_DURATION_MS - 1, pointers: 1 })
|
|
).toBe(true);
|
|
});
|
|
|
|
it('FE-MAP-PRESS-002: 4 px of travel, 300 ms of hold or a second finger never place', () => {
|
|
expect(isPlacementTap({ travelPx: TAP_MAX_TRAVEL_PX, durationMs: 50, pointers: 1 })).toBe(false);
|
|
expect(isPlacementTap({ travelPx: 0, durationMs: TAP_MAX_DURATION_MS, pointers: 1 })).toBe(false);
|
|
expect(isPlacementTap({ travelPx: 0, durationMs: 50, pointers: 2 })).toBe(false);
|
|
});
|
|
|
|
it("FE-MAP-PRESS-003: a click no press was seen for (keyboard, synthetic) is the map's own call", () => {
|
|
expect(isPlacementTap(null)).toBe(true);
|
|
});
|
|
});
|
|
|
|
describe('createPressTracker', () => {
|
|
it('FE-MAP-PRESS-004: hands out the finished press once, with its travel and length', () => {
|
|
const { tracker, at, send } = setup();
|
|
at(1000);
|
|
send('pointerdown', 10, 10);
|
|
at(1100);
|
|
send('pointerup', 12, 11);
|
|
const press = tracker.take();
|
|
expect(press?.durationMs).toBe(100);
|
|
expect(press?.travelPx).toBeCloseTo(Math.hypot(2, 1));
|
|
expect(press?.pointers).toBe(1);
|
|
expect(isPlacementTap(press)).toBe(true);
|
|
expect(tracker.take()).toBeNull();
|
|
});
|
|
|
|
it('FE-MAP-PRESS-005: a drag that came back to where it started still counts as a drag', () => {
|
|
const { tracker, at, send } = setup();
|
|
at(0);
|
|
send('pointerdown', 100, 100);
|
|
send('pointermove', 140, 100);
|
|
at(120);
|
|
send('pointerup', 100, 100);
|
|
const press = tracker.take();
|
|
expect(press?.travelPx).toBe(40);
|
|
expect(isPlacementTap(press)).toBe(false);
|
|
});
|
|
|
|
it('FE-MAP-PRESS-006: a pinch or a two-finger rotate is no tap, and ends with the last finger', () => {
|
|
const { tracker, at, send } = setup();
|
|
at(0);
|
|
send('pointerdown', 10, 10, 1);
|
|
send('pointerdown', 50, 50, 2);
|
|
at(80);
|
|
send('pointerup', 50, 50, 2);
|
|
expect(tracker.take()).toBeNull();
|
|
send('pointerup', 10, 10, 1);
|
|
const press = tracker.take();
|
|
expect(press?.pointers).toBe(2);
|
|
expect(isPlacementTap(press)).toBe(false);
|
|
});
|
|
|
|
it('FE-MAP-PRESS-007: a cancelled press (the browser took it for a gesture) never places', () => {
|
|
const { tracker, at, send } = setup();
|
|
at(0);
|
|
send('pointerdown', 10, 10);
|
|
at(50);
|
|
send('pointercancel', 10, 10);
|
|
expect(isPlacementTap(tracker.take())).toBe(false);
|
|
});
|
|
|
|
it('FE-MAP-PRESS-008: a new press drops the one nobody read, and dispose stops listening', () => {
|
|
const { tracker, at, send } = setup();
|
|
at(0);
|
|
send('pointerdown', 0, 0);
|
|
at(500);
|
|
send('pointerup', 0, 0);
|
|
send('pointerdown', 0, 0);
|
|
expect(tracker.take()).toBeNull();
|
|
at(550);
|
|
send('pointerup', 0, 0);
|
|
expect(tracker.take()?.durationMs).toBe(50);
|
|
|
|
tracker.dispose();
|
|
send('pointerdown', 0, 0);
|
|
send('pointerup', 0, 0);
|
|
expect(tracker.take()).toBeNull();
|
|
});
|
|
});
|