mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-24 16:03:02 +00:00
feat(tours): tidy the tour editor and tour list, set points only on purpose, name waypoints on the map
This commit is contained in:
@@ -0,0 +1,116 @@
|
||||
// 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();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user