CI / verify (push) Failing after 5m29s
Estado do disco em 14/10/2026, sem filtrar. Inclui as copias .sync-conflict-* do Syncthing de 07/10 e os 15 arquivos que o Syncthing apagou; todo esse conteudo ja existia em outros commits. So havia fora do Git: AGENTS.md, CLAUDE.md e a alteracao em data/project-health.json.
76 lines
2.8 KiB
TypeScript
76 lines
2.8 KiB
TypeScript
import { getNotebookFrame, getNotebookSeekProgress } from "./notebookTimeline";
|
|
|
|
describe("notebook choreography", () => {
|
|
it("opens and boots before browsing, then blanks the display before closing", () => {
|
|
const frames = Array.from({ length: 1001 }, (_, index) =>
|
|
getNotebookFrame(index / 1000, 4),
|
|
);
|
|
const phases = [...new Set(frames.map((frame) => frame.phase))];
|
|
expect(phases).toEqual([
|
|
"approach",
|
|
"open",
|
|
"boot",
|
|
"cursor-in",
|
|
"browse",
|
|
"hold",
|
|
"close",
|
|
]);
|
|
for (const frame of frames) {
|
|
if (frame.phase === "open") expect(frame.screenOpacity).toBe(0);
|
|
if (frame.cursorVisible) expect(frame.screenOpacity).toBe(1);
|
|
if (frame.phase === "close" && frame.lidAngle < 112)
|
|
expect(frame.screenOpacity).toBe(0);
|
|
}
|
|
expect(getNotebookFrame(-1, 4).lidAngle).toBe(0);
|
|
expect(getNotebookFrame(2, 4).lidAngle).toBe(0);
|
|
});
|
|
|
|
it("keeps the previous project until cursor arrival, including reverse scroll", () => {
|
|
const frames = Array.from({ length: 10001 }, (_, index) =>
|
|
getNotebookFrame(index / 10000, 4),
|
|
);
|
|
for (let selected = 1; selected < 4; selected += 1) {
|
|
const arrival = frames.findIndex(
|
|
(frame) => frame.activeTabIndex === selected,
|
|
);
|
|
const before = getNotebookFrame((arrival - 1) / 10000, 4);
|
|
const atClick = frames[arrival];
|
|
expect(before.activeTabIndex).toBe(selected - 1);
|
|
expect(before.cursorClicking).toBe(false);
|
|
expect(atClick.cursorClicking).toBe(true);
|
|
expect(atClick.cursorX).toBeCloseTo((selected + 0.5) / 4);
|
|
const reversed = getNotebookFrame((arrival - 2) / 10000, 4);
|
|
expect(reversed.activeTabIndex).toBe(selected - 1);
|
|
expect(reversed.cursorX).toBeLessThan(atClick.cursorX);
|
|
expect(reversed.cursorX).toBeGreaterThan((selected - 0.5) / 4);
|
|
}
|
|
});
|
|
|
|
it("seeks directly into a readable hold for the requested project", () => {
|
|
for (const count of [1, 4]) {
|
|
for (let index = 0; index < count; index += 1) {
|
|
const progress = getNotebookSeekProgress(index, count);
|
|
const frame = getNotebookFrame(progress, count);
|
|
expect(frame.activeTabIndex).toBe(index);
|
|
expect(frame.screenOpacity).toBe(1);
|
|
expect(frame.cursorClicking).toBe(false);
|
|
expect(getNotebookFrame(progress + 0.03, count).activeTabIndex).toBe(
|
|
index,
|
|
);
|
|
}
|
|
}
|
|
expect(
|
|
getNotebookFrame(getNotebookSeekProgress(99, 4), 4).activeTabIndex,
|
|
).toBe(3);
|
|
});
|
|
|
|
it("does not expose a tab or cursor for empty or invalid project counts", () => {
|
|
expect(getNotebookFrame(0.6, 0)).toMatchObject({
|
|
activeTabIndex: -1,
|
|
cursorVisible: false,
|
|
cursorClicking: false,
|
|
});
|
|
expect(getNotebookFrame(0.6, Number.NaN).activeTabIndex).toBe(-1);
|
|
});
|
|
});
|