feat: definir contratos do notebook story
This commit is contained in:
1 parent
d89dde21ee
commit
8b858528f8
4 files changed
+337
No files matched your search
@@ -0,0 +1,89 @@
|
||||
import { getNotebookFrame } from "./notebookTimeline";
|
||||
|
||||
describe("getNotebookFrame", () => {
|
||||
it("clamps progress below zero and starts with a closed device", () => {
|
||||
expect(getNotebookFrame(-1, 4)).toMatchObject({
|
||||
phase: "approach",
|
||||
lidAngle: 0,
|
||||
activeTabIndex: -1,
|
||||
cursorVisible: false,
|
||||
});
|
||||
});
|
||||
|
||||
it("clamps progress above one and ends with a closed device", () => {
|
||||
expect(getNotebookFrame(2, 4)).toMatchObject({
|
||||
phase: "close",
|
||||
lidAngle: 0,
|
||||
activeTabIndex: -1,
|
||||
cursorVisible: false,
|
||||
});
|
||||
});
|
||||
|
||||
it("keeps the phase boundaries deterministic", () => {
|
||||
expect(getNotebookFrame(0.1, 4).phase).toBe("open");
|
||||
expect(getNotebookFrame(0.25, 4).phase).toBe("boot");
|
||||
expect(getNotebookFrame(0.34, 4).phase).toBe("cursor-in");
|
||||
expect(getNotebookFrame(0.44, 4).phase).toBe("browse");
|
||||
expect(getNotebookFrame(0.78, 4).phase).toBe("hold");
|
||||
expect(getNotebookFrame(0.87, 4).phase).toBe("close");
|
||||
});
|
||||
|
||||
it("opens the lid before the browser starts", () => {
|
||||
const frame = getNotebookFrame(0.22, 4);
|
||||
|
||||
expect(frame.phase).toBe("open");
|
||||
expect(frame.lidAngle).toBeGreaterThan(0);
|
||||
expect(frame.screenOpacity).toBe(0);
|
||||
});
|
||||
|
||||
it("boots the screen before the cursor enters", () => {
|
||||
expect(getNotebookFrame(0.25, 4).screenOpacity).toBe(0);
|
||||
expect(getNotebookFrame(0.34, 4).screenOpacity).toBe(1);
|
||||
expect(getNotebookFrame(0.4, 4).cursorVisible).toBe(true);
|
||||
});
|
||||
|
||||
it("selects each tab only inside the browse window", () => {
|
||||
expect(getNotebookFrame(0.43, 4).activeTabIndex).toBe(-1);
|
||||
expect(getNotebookFrame(0.48, 4).activeTabIndex).toBe(0);
|
||||
expect(getNotebookFrame(0.57, 4).activeTabIndex).toBe(1);
|
||||
expect(getNotebookFrame(0.67, 4).activeTabIndex).toBe(2);
|
||||
expect(getNotebookFrame(0.76, 4).activeTabIndex).toBe(3);
|
||||
});
|
||||
|
||||
it("holds the final tab until the closing phase", () => {
|
||||
expect(getNotebookFrame(0.84, 4)).toMatchObject({
|
||||
phase: "hold",
|
||||
activeTabIndex: 3,
|
||||
cursorVisible: true,
|
||||
});
|
||||
expect(getNotebookFrame(0.88, 4)).toMatchObject({
|
||||
phase: "close",
|
||||
activeTabIndex: -1,
|
||||
cursorVisible: false,
|
||||
});
|
||||
});
|
||||
|
||||
it("emits a deterministic cursor click pulse for each tab", () => {
|
||||
const first = getNotebookFrame(0.447, 4);
|
||||
const later = getNotebookFrame(0.53, 4);
|
||||
|
||||
expect(first.cursorClicking).toBe(true);
|
||||
expect(later.cursorClicking).toBe(true);
|
||||
expect(first.cursorX).toBeGreaterThanOrEqual(0);
|
||||
expect(first.cursorX).toBeLessThanOrEqual(1);
|
||||
expect(first.cursorY).toBeGreaterThanOrEqual(0);
|
||||
expect(first.cursorY).toBeLessThanOrEqual(1);
|
||||
});
|
||||
|
||||
it("is deterministic when rewound to the same progress", () => {
|
||||
expect(getNotebookFrame(0.61, 4)).toEqual(getNotebookFrame(0.61, 4));
|
||||
});
|
||||
|
||||
it("does not expose an invalid tab when there are no projects", () => {
|
||||
expect(getNotebookFrame(0.6, 0)).toMatchObject({
|
||||
activeTabIndex: -1,
|
||||
cursorVisible: false,
|
||||
cursorClicking: false,
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user