1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
|
import { render, screen } from "@testing-library/svelte";
import userEvent from "@testing-library/user-event";
import { describe, expect, it, vi } from "vitest";
import { geometryFor } from "../logic/tile-layout";
import ResizePicker from "./ResizePicker.svelte";
const WIDE = geometryFor(1920, 1080);
const TALL = geometryFor(390, 844);
function props() {
return {
onPreview: vi.fn(),
onCommit: vi.fn(),
onCancel: vi.fn(),
};
}
describe("ResizePicker", () => {
it("renders one small square per cap (4×2 wide, 2×2 tall)", () => {
const p = props();
const wide = render(ResizePicker, {
props: { geometry: WIDE, initial: { colSpan: 1, rowSpan: 1 }, ...p },
});
expect(screen.getAllByRole("button")).toHaveLength(8);
wide.unmount();
render(ResizePicker, {
props: { geometry: TALL, initial: { colSpan: 1, rowSpan: 1 }, ...p },
});
expect(screen.getAllByRole("button")).toHaveLength(4);
});
it("hovering square (r, c) previews that rectangle", async () => {
const user = userEvent.setup();
const p = props();
render(ResizePicker, {
props: { geometry: WIDE, initial: { colSpan: 1, rowSpan: 1 }, ...p },
});
await user.hover(screen.getByRole("button", { name: "Resize to 3 by 2" }));
expect(p.onPreview).toHaveBeenCalledWith({ colSpan: 3, rowSpan: 2 });
});
it("clicking a square commits that size", async () => {
const user = userEvent.setup();
const p = props();
render(ResizePicker, {
props: { geometry: WIDE, initial: { colSpan: 1, rowSpan: 1 }, ...p },
});
await user.click(screen.getByRole("button", { name: "Resize to 2 by 1" }));
expect(p.onCommit).toHaveBeenCalledWith(2, 1);
});
it("arrow keys move within the picker, Enter commits, Escape cancels", async () => {
const user = userEvent.setup();
const p = props();
render(ResizePicker, {
props: { geometry: WIDE, initial: { colSpan: 2, rowSpan: 1 }, ...p },
});
await user.keyboard("{ArrowRight}");
expect(p.onPreview).toHaveBeenLastCalledWith({ colSpan: 3, rowSpan: 1 });
await user.keyboard("{ArrowDown}");
expect(p.onPreview).toHaveBeenLastCalledWith({ colSpan: 3, rowSpan: 2 });
await user.keyboard("{ArrowLeft}");
expect(p.onPreview).toHaveBeenLastCalledWith({ colSpan: 2, rowSpan: 2 });
await user.keyboard("{Enter}");
expect(p.onCommit).toHaveBeenCalledWith(2, 2);
expect(p.onCancel).not.toHaveBeenCalled();
await user.keyboard("{Escape}");
expect(p.onCancel).toHaveBeenCalledTimes(1);
});
it("leaving the picker clears the preview", async () => {
const user = userEvent.setup();
const p = props();
render(ResizePicker, {
props: { geometry: WIDE, initial: { colSpan: 1, rowSpan: 1 }, ...p },
});
await user.hover(screen.getByRole("button", { name: "Resize to 4 by 2" }));
await user.unhover(screen.getByRole("button", { name: "Resize to 4 by 2" }));
expect(p.onPreview).toHaveBeenLastCalledWith(null);
});
});
|