Files
mommysgoodpuppy 403fe78cc7 Guided headset check, and word-wrapped toasts
utils/headsetCheck.ts walks through the features only verified in --novr,
one yes/no question at a time: it changes the display in view (curve,
opacity, anchor to head and hand) or a setting (wrist hand and size),
asks as a toast, reads the answer from the left stick, and undoes the
change. Answers land in logs/headset-check-<time>.json.

To support it, the anchor transform maths moves out of the settings UI
into anchoredRootTransform, and the layout store exposes the graph for
reading and editing.

Toast titles and content now word-wrap to the card instead of running
off its edge.

Agent: Claude Code 2.1.296; model claude-opus-5-5; thread 941be8c7-aca1-4664-b284-7cc0eed69e21
2026-10-12 09:34:34 +03:00

67 lines
2.2 KiB
TypeScript

import { assertEquals } from "jsr:@std/assert@^1.0.0";
import { answerFromStick, type CheckStep, runSteps } from "./headsetCheck.ts";
Deno.test("answerFromStick: up yes, down no, left skip, middle nothing", () => {
assertEquals(answerFromStick(0, 0.9), "yes");
assertEquals(answerFromStick(0, -0.9), "no");
assertEquals(answerFromStick(-0.9, 0), "skip");
assertEquals(answerFromStick(0.9, 0), null);
assertEquals(answerFromStick(0.3, -0.5), null);
});
Deno.test("runSteps: undoes each setup after its answer, in order", async () => {
const log: string[] = [];
const step = (id: string): CheckStep => ({
id,
question: id,
setup: () => {
log.push(`setup ${id}`);
return () => log.push(`undo ${id}`);
},
});
const results = await runSteps([step("a"), step("b")], (s) => {
log.push(`ask ${s.id}`);
return Promise.resolve(s.id === "a" ? "yes" : "no");
});
assertEquals(log, ["setup a", "ask a", "undo a", "setup b", "ask b", "undo b"]);
assertEquals(results.map((r) => r.answer), ["yes", "no"]);
});
Deno.test("runSteps: a failing step is a skip, and the run goes on", async () => {
const undone: string[] = [];
const results = await runSteps([
{
id: "broken-setup",
question: "",
setup: () => {
throw new Error("no display");
},
},
{
id: "broken-ask",
question: "",
setup: () => () => undone.push("broken-ask"),
},
{ id: "fine", question: "" },
], (s) => s.id === "broken-ask" ? Promise.reject(new Error("gone")) : Promise.resolve("yes"));
assertEquals(results.map((r) => r.answer), ["skip", "skip", "yes"]);
assertEquals(undone, ["broken-ask"]);
});
Deno.test("runSteps: settles after each undo, before the next setup", async () => {
const log: string[] = [];
const step = (id: string): CheckStep => ({
id,
question: id,
setup: () => {
log.push(`setup ${id}`);
return () => log.push(`undo ${id}`);
},
});
await runSteps([step("a"), step("b")], () => Promise.resolve("yes"), () => {
log.push("settle");
return Promise.resolve();
});
assertEquals(log, ["setup a", "undo a", "settle", "setup b", "undo b", "settle"]);
});