test.social/core/renderers/grid.renderer.test.ts
test.social/core/renderers/grid.renderer.test.ts is a file in Codebase Testing. 75 lines of code and 0 definitions.
import type { CardPage, RegisteredCard } from "@banes-lab/social-share/types/card.types.ts";
import { describe, expect, it } from "vitest";
import { STAGE_HEADING } from "@banes-lab/social-share/configuration/strings/card.strings.ts";
import { createCard } from "@banes-lab/social-share/core/factories/card.factory.ts";
import { renderGrid } from "@banes-lab/social-share/core/renderers/grid.renderer.ts";
type Resize = (entries: readonly unknown[]) => void;
const observers: { resize: Resize; disconnected: boolean }[] = [];
class StubObserver {
private readonly entry: { resize: Resize; disconnected: boolean };
public constructor(callback: Resize) {
this.entry = { disconnected: false, resize: callback };
observers.push(this.entry);
}
public observe(): void {}
public disconnect(): void {
this.entry.disconnected = true;
}
}
Reflect.set(globalThis, "ResizeObserver", StubObserver);
Reflect.set(globalThis, "IntersectionObserver", StubObserver);
const pageOf = function pageOf(id: string, headline: string, icon: string): CardPage {
return {
accent: "page-sky",
address: `lab.example/${id}`,
headline,
icon,
id,
mark: "/mark.gif",
tagline: "Answers",
};
};
const HOME = pageOf("home", "Home", "bi-house");
const FAQ = pageOf("faq", "Questions", "bi-question-circle");
const cardOf = function cardOf(page: CardPage): RegisteredCard {
return {
id: page.id,
origin: `/cards/${page.id}/plugins/${page.id}.plugin.ts`,
spec: createCard({
alt: "A card.",
id: page.id,
layers: [{ id: "title", kind: "text", placement: { x: 0.1, y: 0.1 }, text: page.headline }],
page: page.id,
stylesheet: "",
tone: page.accent,
}),
};
};
describe("renderGrid", () => {
it("lays one spread per card in page order, each titled by its page's icon and headline in its tone", () => {
const host = document.createElement("main");
const stop = renderGrid(
host,
[cardOf(FAQ), cardOf(HOME)],
[HOME, FAQ],
[{ card: "stray", message: "is orphaned." }],
);
expect(host.querySelector(".stage-heading")?.textContent).toBe(STAGE_HEADING);
const spreads = [...host.querySelectorAll(".stage-spread")];
expect(spreads.map((spread) => spread.querySelector(".stage-spread-title")?.textContent)).toStrictEqual([
HOME.headline,
FAQ.headline,
]);
const [first] = spreads;
expect(first?.classList.contains(HOME.accent)).toBe(true);
expect(first?.querySelector(".stage-spread-title i")?.classList.contains(HOME.icon)).toBe(true);
expect(first?.querySelector(".stage-spread-meta")?.textContent).toContain(HOME.address);
expect(first?.querySelectorAll(".stage-tile")).toHaveLength(cardOf(HOME).spec.profiles.length);
expect(host.querySelector(".stage-findings")?.textContent).toContain("stray");
for (const observer of observers) {
observer.resize([]);
}
stop();
expect(observers.every((observer) => observer.disconnected)).toBe(true);
});
});