summaryrefslogtreecommitdiffhomepage
path: root/src/features/workspaces/ui/ResizePicker.test.ts
blob: 796a556f23bf7979af523e018054c4b86f403bff (plain)
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);
  });
});