Files

89 lines
2.9 KiB
TypeScript

import { describe, expect, it } from "vitest";
import { step } from "../src/lib/grid";
import type { Rect } from "../src/lib/grid";
/** Three cards per row, 100 wide and 40 tall, the way the tray wraps them. */
function tray(count: number): { id: number; rect: Rect }[] {
return Array.from({ length: count }, (_, index) => ({
id: index,
rect: {
left: (index % 3) * 100,
top: Math.floor(index / 3) * 40,
width: 96,
height: 36,
},
}));
}
const rectOf = (item: { rect: Rect }): Rect => item.rect;
const walk = (
items: ReturnType<typeof tray>,
from: number,
direction: Parameters<typeof step>[2],
): number | null => step(items, items[from], direction, rectOf)?.id ?? null;
describe("step", () => {
it("moves along a row", () => {
const items = tray(6);
expect(walk(items, 0, "right")).toBe(1);
expect(walk(items, 1, "left")).toBe(0);
});
it("moves down a column, not just to the next card", () => {
const items = tray(6);
expect(walk(items, 1, "down")).toBe(4);
expect(walk(items, 4, "up")).toBe(1);
});
it("keeps the column when the last row is short", () => {
const items = tray(5);
expect(walk(items, 1, "down")).toBe(4);
expect(walk(items, 2, "down")).toBe(4);
});
it("carries on to the next row at the end of one", () => {
const items = tray(6);
expect(walk(items, 2, "right")).toBe(3);
expect(walk(items, 3, "left")).toBe(2);
});
it("stops at the top and the bottom", () => {
const items = tray(6);
expect(walk(items, 1, "up")).toBeNull();
expect(walk(items, 4, "down")).toBeNull();
});
it("stops at the very ends of the run", () => {
const items = tray(6);
expect(walk(items, 0, "left")).toBeNull();
expect(walk(items, 5, "right")).toBeNull();
});
it("falls back to the first card when the cursor is off the run", () => {
const items = tray(3);
const stray = { id: 99, rect: { left: 0, top: 0, width: 1, height: 1 } };
expect(step(items, stray, "right", rectOf)?.id).toBe(0);
});
it("reads a row by the band each card fills, not by its centre", () => {
// Top-aligned cards of different heights still sit on one row.
const items = [
{ id: 0, rect: { left: 0, top: 0, width: 96, height: 67 } },
{ id: 1, rect: { left: 100, top: 0, width: 96, height: 67 } },
{ id: 2, rect: { left: 200, top: 0, width: 96, height: 51 } },
{ id: 3, rect: { left: 0, top: 73, width: 96, height: 51 } },
];
expect(step(items, items[0], "up", rectOf)).toBeNull();
expect(step(items, items[0], "right", rectOf)?.id).toBe(1);
expect(step(items, items[2], "left", rectOf)?.id).toBe(1);
expect(step(items, items[0], "down", rectOf)?.id).toBe(3);
expect(step(items, items[3], "up", rectOf)?.id).toBe(0);
});
it("handles a single card without moving", () => {
const items = tray(1);
expect(walk(items, 0, "right")).toBeNull();
expect(walk(items, 0, "down")).toBeNull();
});
});