mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-04-10 04:19:25 -07:00
feat(controller): add inline remap modal with descriptor-based bindings (#21)
This commit is contained in:
129
src/renderer/handlers/controller-binding-capture.test.ts
Normal file
129
src/renderer/handlers/controller-binding-capture.test.ts
Normal file
@@ -0,0 +1,129 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import test from 'node:test';
|
||||
|
||||
import { createControllerBindingCapture } from './controller-binding-capture.js';
|
||||
|
||||
function createSnapshot(
|
||||
overrides: {
|
||||
axes?: number[];
|
||||
buttons?: Array<{ value: number; pressed?: boolean; touched?: boolean }>;
|
||||
} = {},
|
||||
) {
|
||||
return {
|
||||
axes: overrides.axes ?? [0, 0, 0, 0, 0],
|
||||
buttons:
|
||||
overrides.buttons ??
|
||||
Array.from({ length: 12 }, () => ({
|
||||
value: 0,
|
||||
pressed: false,
|
||||
touched: false,
|
||||
})),
|
||||
};
|
||||
}
|
||||
|
||||
test('controller binding capture waits for neutral-to-active button edge', () => {
|
||||
const capture = createControllerBindingCapture({
|
||||
triggerDeadzone: 0.5,
|
||||
stickDeadzone: 0.2,
|
||||
});
|
||||
|
||||
const heldButtons = createSnapshot({
|
||||
buttons: [{ value: 1, pressed: true, touched: true }],
|
||||
});
|
||||
|
||||
capture.arm({ actionId: 'toggleLookup', bindingType: 'discrete' }, heldButtons);
|
||||
|
||||
assert.equal(capture.poll(heldButtons), null);
|
||||
|
||||
const neutralButtons = createSnapshot();
|
||||
assert.equal(capture.poll(neutralButtons), null);
|
||||
|
||||
const freshPress = createSnapshot({
|
||||
buttons: [{ value: 1, pressed: true, touched: true }],
|
||||
});
|
||||
assert.deepEqual(capture.poll(freshPress), {
|
||||
actionId: 'toggleLookup',
|
||||
bindingType: 'discrete',
|
||||
binding: { kind: 'button', buttonIndex: 0 },
|
||||
});
|
||||
});
|
||||
|
||||
test('controller binding capture records fresh axis direction for discrete learn mode', () => {
|
||||
const capture = createControllerBindingCapture({
|
||||
triggerDeadzone: 0.5,
|
||||
stickDeadzone: 0.2,
|
||||
});
|
||||
|
||||
capture.arm({ actionId: 'closeLookup', bindingType: 'discrete' }, createSnapshot());
|
||||
|
||||
assert.deepEqual(capture.poll(createSnapshot({ axes: [0, 0, 0, -0.8] })), {
|
||||
actionId: 'closeLookup',
|
||||
bindingType: 'discrete',
|
||||
binding: { kind: 'axis', axisIndex: 3, direction: 'negative' },
|
||||
});
|
||||
});
|
||||
|
||||
test('controller binding capture ignores analog drift inside deadzone', () => {
|
||||
const capture = createControllerBindingCapture({
|
||||
triggerDeadzone: 0.5,
|
||||
stickDeadzone: 0.3,
|
||||
});
|
||||
|
||||
capture.arm({ actionId: 'mineCard', bindingType: 'discrete' }, createSnapshot());
|
||||
|
||||
assert.equal(capture.poll(createSnapshot({ axes: [0.2, 0, 0, 0] })), null);
|
||||
assert.equal(capture.isArmed(), true);
|
||||
});
|
||||
|
||||
test('controller binding capture emits axis binding for continuous learn mode', () => {
|
||||
const capture = createControllerBindingCapture({
|
||||
triggerDeadzone: 0.5,
|
||||
stickDeadzone: 0.2,
|
||||
});
|
||||
|
||||
capture.arm(
|
||||
{
|
||||
actionId: 'leftStickHorizontal',
|
||||
bindingType: 'axis',
|
||||
dpadFallback: 'horizontal',
|
||||
},
|
||||
createSnapshot(),
|
||||
);
|
||||
|
||||
assert.deepEqual(capture.poll(createSnapshot({ axes: [0, 0, 0, 0.9] })), {
|
||||
actionId: 'leftStickHorizontal',
|
||||
bindingType: 'axis',
|
||||
binding: { kind: 'axis', axisIndex: 3, dpadFallback: 'horizontal' },
|
||||
});
|
||||
});
|
||||
|
||||
test('controller binding capture ignores button presses for continuous learn mode', () => {
|
||||
const capture = createControllerBindingCapture({
|
||||
triggerDeadzone: 0.5,
|
||||
stickDeadzone: 0.2,
|
||||
});
|
||||
|
||||
capture.arm(
|
||||
{
|
||||
actionId: 'leftStickHorizontal',
|
||||
bindingType: 'axis',
|
||||
dpadFallback: 'horizontal',
|
||||
},
|
||||
createSnapshot(),
|
||||
);
|
||||
|
||||
assert.equal(
|
||||
capture.poll(
|
||||
createSnapshot({
|
||||
buttons: [{ value: 1, pressed: true, touched: true }],
|
||||
}),
|
||||
),
|
||||
null,
|
||||
);
|
||||
|
||||
assert.deepEqual(capture.poll(createSnapshot({ axes: [0, 0, 0.75, 0, 0] })), {
|
||||
actionId: 'leftStickHorizontal',
|
||||
bindingType: 'axis',
|
||||
binding: { kind: 'axis', axisIndex: 2, dpadFallback: 'horizontal' },
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user