perf: enforce journey budgets and reference traces
This commit is contained in:
101
tests/performance/physical-drive.test.ts
Normal file
101
tests/performance/physical-drive.test.ts
Normal file
@@ -0,0 +1,101 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import {
|
||||
buildPhysicalDriveProtocol,
|
||||
buildTargetActivation,
|
||||
buildVolumeKeySequence,
|
||||
buildSwipeCycle,
|
||||
chooseCycleDirection,
|
||||
computeSafeViewport,
|
||||
physicalCycleOffsets,
|
||||
roundHalfUp,
|
||||
} from './physical-drive.protocol';
|
||||
|
||||
describe('physical-drive.v1 protocol', () => {
|
||||
it('uses round-half-up safe viewport coordinates', () => {
|
||||
expect(roundHalfUp(1.5)).toBe(2);
|
||||
expect(computeSafeViewport({ offsetLeft: 2, offsetTop: 3, width: 390, height: 844 }, { left: 10, right: 12, top: 20, bottom: 22 })).toEqual({
|
||||
safeX: 12,
|
||||
safeY: 23,
|
||||
width: 368,
|
||||
height: 802,
|
||||
});
|
||||
expect(() => computeSafeViewport({ offsetLeft: 0, offsetTop: 0, width: 10, height: 10 }, { left: 5, right: 5, top: 0, bottom: 0 })).toThrow(/positive/u);
|
||||
});
|
||||
|
||||
it('generates the literal 15-step synchronized touch cycle', () => {
|
||||
const cycle = buildSwipeCycle('forward', { safeX: 0, safeY: 0, width: 100, height: 200 });
|
||||
expect(cycle.pointer.id).toBe('driveTouch');
|
||||
expect(cycle.keyboard.id).toBe('driveKeys');
|
||||
expect(cycle.pointer.actions).toHaveLength(19);
|
||||
expect(cycle.pointer.actions[0]).toEqual({ type: 'pointerMove', duration: 0, origin: 'viewport', x: 50, y: 160 });
|
||||
expect(cycle.pointer.actions[2]).toEqual({ type: 'pointerMove', duration: 40, origin: 'viewport', x: 50, y: 151 });
|
||||
expect(cycle.pointer.actions[16]).toEqual({ type: 'pointerMove', duration: 40, origin: 'viewport', x: 50, y: 20 });
|
||||
expect(cycle.pointer.actions.at(-1)).toEqual({ type: 'pause', duration: 400 });
|
||||
expect(cycle.keyboard.actions).toEqual([{ type: 'pause', duration: 1_000 }]);
|
||||
});
|
||||
|
||||
it('switches direction only at the two-pixel boundaries', () => {
|
||||
expect(chooseCycleDirection('forward', 98, 100)).toBe('reverse');
|
||||
expect(chooseCycleDirection('forward', 97.99, 100)).toBe('forward');
|
||||
expect(chooseCycleDirection('reverse', 2, 100)).toBe('forward');
|
||||
expect(chooseCycleDirection('reverse', 2.01, 100)).toBe('reverse');
|
||||
});
|
||||
|
||||
it('builds exact stable-box activation and synchronized volume input sources', () => {
|
||||
const activation = buildTargetActivation(
|
||||
{ left: 10, top: 20, right: 110, bottom: 70 },
|
||||
{ left: 10.5, top: 20.5, right: 110.5, bottom: 70.5 },
|
||||
{ safeX: 0, safeY: 0, width: 100, height: 100 },
|
||||
);
|
||||
expect(activation.pointer.actions).toEqual([
|
||||
{ type: 'pointerMove', duration: 0, origin: 'viewport', x: 55, y: 46 },
|
||||
{ type: 'pause', duration: 60 },
|
||||
{ type: 'pointerDown', button: 0 },
|
||||
{ type: 'pause', duration: 60 },
|
||||
{ type: 'pointerUp', button: 0 },
|
||||
]);
|
||||
expect(activation.keyboard.actions).toEqual([{ type: 'pause', duration: 120 }]);
|
||||
expect(() => buildTargetActivation(
|
||||
{ left: 10, top: 20, right: 110, bottom: 70 },
|
||||
{ left: 11, top: 20, right: 110, bottom: 70 },
|
||||
{ safeX: 0, safeY: 0, width: 100, height: 100 },
|
||||
)).toThrow(/stable/u);
|
||||
|
||||
const volume = buildVolumeKeySequence();
|
||||
expect(volume.keyboard.actions).toEqual([
|
||||
{ type: 'pause', duration: 15_900 },
|
||||
{ type: 'keyDown', value: '\uE004' },
|
||||
{ type: 'pause', duration: 20 },
|
||||
{ type: 'keyUp', value: '\uE004' },
|
||||
{ type: 'pause', duration: 80 },
|
||||
{ type: 'keyDown', value: '\uE012' },
|
||||
{ type: 'pause', duration: 40 },
|
||||
{ type: 'keyUp', value: '\uE012' },
|
||||
]);
|
||||
expect(volume.pointer.actions).toEqual([{ type: 'pause', duration: 16_040 }]);
|
||||
});
|
||||
|
||||
it('uses every specified cycle except the excluded 389/390-second cycles', () => {
|
||||
const offsets = physicalCycleOffsets();
|
||||
expect(offsets).toContain(388);
|
||||
expect(offsets).not.toContain(389);
|
||||
expect(offsets).not.toContain(390);
|
||||
expect(offsets).toContain(391);
|
||||
expect(offsets).toContain(509);
|
||||
expect(offsets).not.toContain(510);
|
||||
});
|
||||
|
||||
it('preserves normative event order and terminal-Static branches', () => {
|
||||
const protocol = buildPhysicalDriveProtocol();
|
||||
expect(protocol.version).toBe('physical-drive.v1');
|
||||
expect(protocol.durationMs).toBe(600_000);
|
||||
expect(protocol.events.filter((event) => event.offsetMs === 390_000).map((event) => event.action)).toEqual([
|
||||
'arm-navigation-settlement-barrier',
|
||||
'navigate-infrastructure',
|
||||
]);
|
||||
expect(protocol.events.find((event) => event.offsetMs === 391_000)?.assertions).toContain('cancel-exact-pending-navigation-epoch');
|
||||
expect(protocol.branches.live.find((event) => event.offsetMs === 550_000)?.action).toBe('pause-motion');
|
||||
expect(protocol.branches.static.find((event) => event.offsetMs === 550_000)?.action).toBe('assert-static-without-input');
|
||||
expect(protocol.events.at(-1)).toMatchObject({ offsetMs: 600_000, action: 'finish' });
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user