Loading packages/client/src/lib/__tests__/banner.test.ts 0 → 100644 +37 −0 Original line number Diff line number Diff line import { describe, it, expect, vi, beforeEach, afterEach } from "vitest"; describe("banner", () => { let consoleSpy: ReturnType<typeof vi.spyOn>; beforeEach(() => { consoleSpy = vi.spyOn(console, "log").mockImplementation(() => {}); }); afterEach(() => { consoleSpy.mockRestore(); }); it("printBanner calls console.log", async () => { // Dynamic import so the template literal with __BUILD_YEAR__ resolves const { printBanner } = await import("../banner"); printBanner(); expect(consoleSpy).toHaveBeenCalled(); }); it("printBanner passes formatting arguments", async () => { const { printBanner } = await import("../banner"); printBanner(); // First arg should be the banner string, rest are formatting strings const call = consoleSpy.mock.calls[0]; expect(call[0]).toContain("canvas.fediverse.events"); // Should have at least 2 arguments (string + format specifiers) expect(call.length).toBeGreaterThanOrEqual(2); }); it("banner includes copyright text", async () => { const { printBanner } = await import("../banner"); printBanner(); const call = consoleSpy.mock.calls[0]; expect(call[0]).toMatch(/Copyright/); }); }); No newline at end of file packages/client/src/lib/__tests__/canvasUtils.test.ts 0 → 100644 +40 −0 Original line number Diff line number Diff line import { describe, it, expect } from "vitest"; import { CanvasUtils } from "../canvas.utils"; describe("CanvasUtils", () => { describe("canvasToPanZoomTransform", () => { it("returns transform centered on the middle of the canvas", () => { const result = CanvasUtils.canvasToPanZoomTransform(50, 50, [100, 100]); expect(result.transformX).toBe(0); expect(result.transformY).toBe(0); }); it("returns positive transform when coordinates are in the top-left", () => { const result = CanvasUtils.canvasToPanZoomTransform(0, 0, [100, 100]); expect(result.transformX).toBe(50); expect(result.transformY).toBe(50); }); it("returns negative transform when coordinates are in the bottom-right", () => { const result = CanvasUtils.canvasToPanZoomTransform(100, 100, [100, 100]); expect(result.transformX).toBe(-50); expect(result.transformY).toBe(-50); }); it("works with non-square canvas dimensions", () => { const result = CanvasUtils.canvasToPanZoomTransform(200, 50, [400, 100]); expect(result.transformX).toBe(0); expect(result.transformY).toBe(0); }); it("handles large coordinates", () => { const result = CanvasUtils.canvasToPanZoomTransform( 5000, 3000, [10000, 6000], ); expect(result.transformX).toBe(0); expect(result.transformY).toBe(0); }); }); }); No newline at end of file packages/client/src/lib/__tests__/constants.test.ts 0 → 100644 +58 −0 Original line number Diff line number Diff line import { describe, it, expect } from "vitest"; import { RECOMMENDED_INSTANCES, DISCORD_INVITE, MATRIX_ALIAS, MATRIX_INVITE, MATRIX_URL, } from "../constants"; describe("constants", () => { describe("RECOMMENDED_INSTANCES", () => { it("each instance has required fields", () => { for (const instance of RECOMMENDED_INSTANCES) { expect(instance.name).toBeTruthy(); expect(instance.url).toMatch(/^https:\/\//); expect(instance.software).toBeTruthy(); expect(instance.software.name).toBeTruthy(); expect(instance.software.like).toBeTruthy(); } }); it("all instance URLs are valid https URLs", () => { for (const instance of RECOMMENDED_INSTANCES) { expect(() => new URL(instance.url)).not.toThrow(); expect(instance.url.startsWith("https://")).toBe(true); } }); }); describe("DISCORD_INVITE", () => { it("is a valid discord.gg URL", () => { expect(DISCORD_INVITE).toMatch(/^https:\/\/discord\.gg\//); }); }); describe("MATRIX_ALIAS", () => { it("valid matrix alias", () => { expect(MATRIX_ALIAS.startsWith("#")).toBe(true); expect(MATRIX_ALIAS.includes(":")); }); }); describe("MATRIX_INVITE", () => { it("is a matrix.to URL", () => { expect(MATRIX_INVITE).toMatch(/^https:\/\/matrix\.to\/#\//); }); it("includes the alias", () => { expect(MATRIX_INVITE).toContain(MATRIX_ALIAS); }); }); describe("MATRIX_URL", () => { it("is a matrix:r/ URI", () => { expect(MATRIX_URL).toMatch(/^matrix:r\//); }); }); }); packages/client/src/lib/__tests__/keybinds.test.ts 0 → 100644 +249 −0 Original line number Diff line number Diff line import { describe, it, expect, vi, beforeEach, afterEach } from "vitest"; // KeybindManager is a singleton whose constructor registers document listeners. // We test handleInteraction directly — it's the pure keybind-matching logic. describe("KeybindManager", () => { let manager: typeof import("../keybinds").KeybindManager; let emitSpy: ReturnType<typeof vi.spyOn>; beforeEach(async () => { // Dynamic import to avoid interference from other tests const mod = await import("../keybinds"); manager = mod.KeybindManager; emitSpy = vi.spyOn(manager, "emit").mockImplementation(() => true); }); afterEach(() => { emitSpy.mockRestore(); }); /* ─── Keyboard keybinds ─── */ it("TOGGLE_TEMPLATE on pressing T", () => { manager.handleInteraction( { key: "KeyT" }, { clientX: -1, clientY: -1 }, ); expect(emitSpy).toHaveBeenCalledWith("TOGGLE_TEMPLATE", { clientX: -1, clientY: -1, }); }); it("TOGGLE_TEMPLATE with extra shift modifier still matches", () => { // Keybind doesn't specify shift, so shift doesn't block the match manager.handleInteraction( { key: "KeyT", shift: true }, { clientX: -1, clientY: -1 }, ); expect(emitSpy).toHaveBeenCalledWith("TOGGLE_TEMPLATE", { clientX: -1, clientY: -1, }); }); it("TOGGLE_BLANK on pressing V", () => { manager.handleInteraction( { key: "KeyV" }, { clientX: -1, clientY: -1 }, ); expect(emitSpy).toHaveBeenCalledWith("TOGGLE_BLANK", { clientX: -1, clientY: -1, }); }); it("TOGGLE_BLANK on pressing B (alternative keybind)", () => { manager.handleInteraction( { key: "KeyB" }, { clientX: -1, clientY: -1 }, ); expect(emitSpy).toHaveBeenCalledWith("TOGGLE_BLANK", { clientX: -1, clientY: -1, }); }); it("TOGGLE_HEATMAP on pressing H", () => { manager.handleInteraction( { key: "KeyH" }, { clientX: -1, clientY: -1 }, ); expect(emitSpy).toHaveBeenCalledWith("TOGGLE_HEATMAP", { clientX: -1, clientY: -1, }); }); it("TOGGLE_GRID on pressing G", () => { manager.handleInteraction( { key: "KeyG" }, { clientX: -1, clientY: -1 }, ); expect(emitSpy).toHaveBeenCalledWith("TOGGLE_GRID", { clientX: -1, clientY: -1, }); }); it("TOGGLE_MOD_MENU on pressing M", () => { manager.handleInteraction( { key: "KeyM" }, { clientX: -1, clientY: -1 }, ); expect(emitSpy).toHaveBeenCalledWith("TOGGLE_MOD_MENU", { clientX: -1, clientY: -1, }); }); it("DESELECT_COLOR on pressing Escape", () => { manager.handleInteraction( { key: "Escape" }, { clientX: -1, clientY: -1 }, ); expect(emitSpy).toHaveBeenCalledWith("DESELECT_COLOR", { clientX: -1, clientY: -1, }); }); it("SNAPSHOT on pressing P", () => { manager.handleInteraction( { key: "KeyP" }, { clientX: -1, clientY: -1 }, ); expect(emitSpy).toHaveBeenCalledWith("SNAPSHOT", { clientX: -1, clientY: -1, }); }); it("KEYBINDS on pressing Shift+/", () => { manager.handleInteraction( { key: "Slash", shift: true }, { clientX: -1, clientY: -1 }, ); expect(emitSpy).toHaveBeenCalledWith("KEYBINDS", { clientX: -1, clientY: -1, }); }); it("Slash without shift does not trigger KEYBINDS", () => { manager.handleInteraction( { key: "Slash" }, { clientX: -1, clientY: -1 }, ); expect(emitSpy).not.toHaveBeenCalled(); }); /* ─── Mouse keybinds ─── */ it("PIXEL_WHOIS on Shift+LCLICK", () => { manager.handleInteraction( { key: "LCLICK", shift: true }, { clientX: 100, clientY: 200 }, ); expect(emitSpy).toHaveBeenCalledWith("PIXEL_WHOIS", { clientX: 100, clientY: 200, }); }); it("PIXEL_WHOIS on LONG_PRESS", () => { manager.handleInteraction( { key: "LONG_PRESS" }, { clientX: 50, clientY: 60 }, ); expect(emitSpy).toHaveBeenCalledWith("PIXEL_WHOIS", { clientX: 50, clientY: 60, }); }); it("plain LCLICK does not trigger PIXEL_WHOIS", () => { manager.handleInteraction( { key: "LCLICK" }, { clientX: -1, clientY: -1 }, ); expect(emitSpy).not.toHaveBeenCalledWith( "PIXEL_WHOIS", expect.anything(), ); }); it("TEMPLATE_MOVE on Alt+LCLICK", () => { manager.handleInteraction( { key: "LCLICK", alt: true }, { clientX: 30, clientY: 40 }, ); expect(emitSpy).toHaveBeenCalledWith("TEMPLATE_MOVE", { clientX: 30, clientY: 40, }); }); it("PICK_COLOR on MCLICK (middle click)", () => { manager.handleInteraction( { key: "MCLICK" }, { clientX: -1, clientY: -1 }, ); expect(emitSpy).toHaveBeenCalledWith("PICK_COLOR", { clientX: -1, clientY: -1, }); }); it("MOD_SELECT on Ctrl+LCLICK", () => { manager.handleInteraction( { key: "LCLICK", ctrl: true }, { clientX: 10, clientY: 20 }, ); expect(emitSpy).toHaveBeenCalledWith("MOD_SELECT", { clientX: 10, clientY: 20, }); }); /* ─── Modifier-specific tests ─── */ it("Shift+LCLICK does not also trigger TEMPLATE_MOVE (no alt)", () => { manager.handleInteraction( { key: "LCLICK", shift: true }, { clientX: -1, clientY: -1 }, ); // PIXEL_WHOIS requires shift expect(emitSpy).toHaveBeenCalledWith("PIXEL_WHOIS", expect.anything()); // TEMPLATE_MOVE requires alt — should not fire expect(emitSpy).not.toHaveBeenCalledWith( "TEMPLATE_MOVE", expect.anything(), ); // MOD_SELECT requires ctrl — should not fire expect(emitSpy).not.toHaveBeenCalledWith( "MOD_SELECT", expect.anything(), ); }); /* ─── Unknown / non-matching ─── */ it("unknown key returns false and emits nothing", () => { const result = manager.handleInteraction( { key: "F12" }, { clientX: -1, clientY: -1 }, ); expect(result).toBe(false); expect(emitSpy).not.toHaveBeenCalled(); }); it("returns true when at least one keybind matches", () => { const result = manager.handleInteraction( { key: "KeyT" }, { clientX: -1, clientY: -1 }, ); expect(result).toBe(true); }); }); No newline at end of file packages/client/src/lib/__tests__/utils.test.ts 0 → 100644 +42 −0 Original line number Diff line number Diff line import { describe, it, expect } from "vitest"; import { rgbToHex } from "../utils"; describe("rgbToHex", () => { it('returns "#FF0000" for red', () => { expect(rgbToHex(255, 0, 0)).toBe("#FF0000"); }); it('returns "#00FF00" for green', () => { expect(rgbToHex(0, 255, 0)).toBe("#00FF00"); }); it('returns "#0000FF" for blue', () => { expect(rgbToHex(0, 0, 255)).toBe("#0000FF"); }); it('returns "#000000" for black', () => { expect(rgbToHex(0, 0, 0)).toBe("#000000"); }); it('returns "#FFFFFF" for white', () => { expect(rgbToHex(255, 255, 255)).toBe("#FFFFFF"); }); it("handles leading zeros in components", () => { expect(rgbToHex(15, 15, 15)).toBe("#0F0F0F"); }); it("returns uppercase hex", () => { const result = rgbToHex(171, 205, 239); expect(result).toBe("#ABCDEF"); expect(result).toEqual(result.toUpperCase()); }); it("pads single-digit hex components with leading zero", () => { expect(rgbToHex(1, 2, 3)).toBe("#010203"); }); it("handles mid-range values", () => { expect(rgbToHex(128, 128, 128)).toBe("#808080"); }); }); No newline at end of file Loading
packages/client/src/lib/__tests__/banner.test.ts 0 → 100644 +37 −0 Original line number Diff line number Diff line import { describe, it, expect, vi, beforeEach, afterEach } from "vitest"; describe("banner", () => { let consoleSpy: ReturnType<typeof vi.spyOn>; beforeEach(() => { consoleSpy = vi.spyOn(console, "log").mockImplementation(() => {}); }); afterEach(() => { consoleSpy.mockRestore(); }); it("printBanner calls console.log", async () => { // Dynamic import so the template literal with __BUILD_YEAR__ resolves const { printBanner } = await import("../banner"); printBanner(); expect(consoleSpy).toHaveBeenCalled(); }); it("printBanner passes formatting arguments", async () => { const { printBanner } = await import("../banner"); printBanner(); // First arg should be the banner string, rest are formatting strings const call = consoleSpy.mock.calls[0]; expect(call[0]).toContain("canvas.fediverse.events"); // Should have at least 2 arguments (string + format specifiers) expect(call.length).toBeGreaterThanOrEqual(2); }); it("banner includes copyright text", async () => { const { printBanner } = await import("../banner"); printBanner(); const call = consoleSpy.mock.calls[0]; expect(call[0]).toMatch(/Copyright/); }); }); No newline at end of file
packages/client/src/lib/__tests__/canvasUtils.test.ts 0 → 100644 +40 −0 Original line number Diff line number Diff line import { describe, it, expect } from "vitest"; import { CanvasUtils } from "../canvas.utils"; describe("CanvasUtils", () => { describe("canvasToPanZoomTransform", () => { it("returns transform centered on the middle of the canvas", () => { const result = CanvasUtils.canvasToPanZoomTransform(50, 50, [100, 100]); expect(result.transformX).toBe(0); expect(result.transformY).toBe(0); }); it("returns positive transform when coordinates are in the top-left", () => { const result = CanvasUtils.canvasToPanZoomTransform(0, 0, [100, 100]); expect(result.transformX).toBe(50); expect(result.transformY).toBe(50); }); it("returns negative transform when coordinates are in the bottom-right", () => { const result = CanvasUtils.canvasToPanZoomTransform(100, 100, [100, 100]); expect(result.transformX).toBe(-50); expect(result.transformY).toBe(-50); }); it("works with non-square canvas dimensions", () => { const result = CanvasUtils.canvasToPanZoomTransform(200, 50, [400, 100]); expect(result.transformX).toBe(0); expect(result.transformY).toBe(0); }); it("handles large coordinates", () => { const result = CanvasUtils.canvasToPanZoomTransform( 5000, 3000, [10000, 6000], ); expect(result.transformX).toBe(0); expect(result.transformY).toBe(0); }); }); }); No newline at end of file
packages/client/src/lib/__tests__/constants.test.ts 0 → 100644 +58 −0 Original line number Diff line number Diff line import { describe, it, expect } from "vitest"; import { RECOMMENDED_INSTANCES, DISCORD_INVITE, MATRIX_ALIAS, MATRIX_INVITE, MATRIX_URL, } from "../constants"; describe("constants", () => { describe("RECOMMENDED_INSTANCES", () => { it("each instance has required fields", () => { for (const instance of RECOMMENDED_INSTANCES) { expect(instance.name).toBeTruthy(); expect(instance.url).toMatch(/^https:\/\//); expect(instance.software).toBeTruthy(); expect(instance.software.name).toBeTruthy(); expect(instance.software.like).toBeTruthy(); } }); it("all instance URLs are valid https URLs", () => { for (const instance of RECOMMENDED_INSTANCES) { expect(() => new URL(instance.url)).not.toThrow(); expect(instance.url.startsWith("https://")).toBe(true); } }); }); describe("DISCORD_INVITE", () => { it("is a valid discord.gg URL", () => { expect(DISCORD_INVITE).toMatch(/^https:\/\/discord\.gg\//); }); }); describe("MATRIX_ALIAS", () => { it("valid matrix alias", () => { expect(MATRIX_ALIAS.startsWith("#")).toBe(true); expect(MATRIX_ALIAS.includes(":")); }); }); describe("MATRIX_INVITE", () => { it("is a matrix.to URL", () => { expect(MATRIX_INVITE).toMatch(/^https:\/\/matrix\.to\/#\//); }); it("includes the alias", () => { expect(MATRIX_INVITE).toContain(MATRIX_ALIAS); }); }); describe("MATRIX_URL", () => { it("is a matrix:r/ URI", () => { expect(MATRIX_URL).toMatch(/^matrix:r\//); }); }); });
packages/client/src/lib/__tests__/keybinds.test.ts 0 → 100644 +249 −0 Original line number Diff line number Diff line import { describe, it, expect, vi, beforeEach, afterEach } from "vitest"; // KeybindManager is a singleton whose constructor registers document listeners. // We test handleInteraction directly — it's the pure keybind-matching logic. describe("KeybindManager", () => { let manager: typeof import("../keybinds").KeybindManager; let emitSpy: ReturnType<typeof vi.spyOn>; beforeEach(async () => { // Dynamic import to avoid interference from other tests const mod = await import("../keybinds"); manager = mod.KeybindManager; emitSpy = vi.spyOn(manager, "emit").mockImplementation(() => true); }); afterEach(() => { emitSpy.mockRestore(); }); /* ─── Keyboard keybinds ─── */ it("TOGGLE_TEMPLATE on pressing T", () => { manager.handleInteraction( { key: "KeyT" }, { clientX: -1, clientY: -1 }, ); expect(emitSpy).toHaveBeenCalledWith("TOGGLE_TEMPLATE", { clientX: -1, clientY: -1, }); }); it("TOGGLE_TEMPLATE with extra shift modifier still matches", () => { // Keybind doesn't specify shift, so shift doesn't block the match manager.handleInteraction( { key: "KeyT", shift: true }, { clientX: -1, clientY: -1 }, ); expect(emitSpy).toHaveBeenCalledWith("TOGGLE_TEMPLATE", { clientX: -1, clientY: -1, }); }); it("TOGGLE_BLANK on pressing V", () => { manager.handleInteraction( { key: "KeyV" }, { clientX: -1, clientY: -1 }, ); expect(emitSpy).toHaveBeenCalledWith("TOGGLE_BLANK", { clientX: -1, clientY: -1, }); }); it("TOGGLE_BLANK on pressing B (alternative keybind)", () => { manager.handleInteraction( { key: "KeyB" }, { clientX: -1, clientY: -1 }, ); expect(emitSpy).toHaveBeenCalledWith("TOGGLE_BLANK", { clientX: -1, clientY: -1, }); }); it("TOGGLE_HEATMAP on pressing H", () => { manager.handleInteraction( { key: "KeyH" }, { clientX: -1, clientY: -1 }, ); expect(emitSpy).toHaveBeenCalledWith("TOGGLE_HEATMAP", { clientX: -1, clientY: -1, }); }); it("TOGGLE_GRID on pressing G", () => { manager.handleInteraction( { key: "KeyG" }, { clientX: -1, clientY: -1 }, ); expect(emitSpy).toHaveBeenCalledWith("TOGGLE_GRID", { clientX: -1, clientY: -1, }); }); it("TOGGLE_MOD_MENU on pressing M", () => { manager.handleInteraction( { key: "KeyM" }, { clientX: -1, clientY: -1 }, ); expect(emitSpy).toHaveBeenCalledWith("TOGGLE_MOD_MENU", { clientX: -1, clientY: -1, }); }); it("DESELECT_COLOR on pressing Escape", () => { manager.handleInteraction( { key: "Escape" }, { clientX: -1, clientY: -1 }, ); expect(emitSpy).toHaveBeenCalledWith("DESELECT_COLOR", { clientX: -1, clientY: -1, }); }); it("SNAPSHOT on pressing P", () => { manager.handleInteraction( { key: "KeyP" }, { clientX: -1, clientY: -1 }, ); expect(emitSpy).toHaveBeenCalledWith("SNAPSHOT", { clientX: -1, clientY: -1, }); }); it("KEYBINDS on pressing Shift+/", () => { manager.handleInteraction( { key: "Slash", shift: true }, { clientX: -1, clientY: -1 }, ); expect(emitSpy).toHaveBeenCalledWith("KEYBINDS", { clientX: -1, clientY: -1, }); }); it("Slash without shift does not trigger KEYBINDS", () => { manager.handleInteraction( { key: "Slash" }, { clientX: -1, clientY: -1 }, ); expect(emitSpy).not.toHaveBeenCalled(); }); /* ─── Mouse keybinds ─── */ it("PIXEL_WHOIS on Shift+LCLICK", () => { manager.handleInteraction( { key: "LCLICK", shift: true }, { clientX: 100, clientY: 200 }, ); expect(emitSpy).toHaveBeenCalledWith("PIXEL_WHOIS", { clientX: 100, clientY: 200, }); }); it("PIXEL_WHOIS on LONG_PRESS", () => { manager.handleInteraction( { key: "LONG_PRESS" }, { clientX: 50, clientY: 60 }, ); expect(emitSpy).toHaveBeenCalledWith("PIXEL_WHOIS", { clientX: 50, clientY: 60, }); }); it("plain LCLICK does not trigger PIXEL_WHOIS", () => { manager.handleInteraction( { key: "LCLICK" }, { clientX: -1, clientY: -1 }, ); expect(emitSpy).not.toHaveBeenCalledWith( "PIXEL_WHOIS", expect.anything(), ); }); it("TEMPLATE_MOVE on Alt+LCLICK", () => { manager.handleInteraction( { key: "LCLICK", alt: true }, { clientX: 30, clientY: 40 }, ); expect(emitSpy).toHaveBeenCalledWith("TEMPLATE_MOVE", { clientX: 30, clientY: 40, }); }); it("PICK_COLOR on MCLICK (middle click)", () => { manager.handleInteraction( { key: "MCLICK" }, { clientX: -1, clientY: -1 }, ); expect(emitSpy).toHaveBeenCalledWith("PICK_COLOR", { clientX: -1, clientY: -1, }); }); it("MOD_SELECT on Ctrl+LCLICK", () => { manager.handleInteraction( { key: "LCLICK", ctrl: true }, { clientX: 10, clientY: 20 }, ); expect(emitSpy).toHaveBeenCalledWith("MOD_SELECT", { clientX: 10, clientY: 20, }); }); /* ─── Modifier-specific tests ─── */ it("Shift+LCLICK does not also trigger TEMPLATE_MOVE (no alt)", () => { manager.handleInteraction( { key: "LCLICK", shift: true }, { clientX: -1, clientY: -1 }, ); // PIXEL_WHOIS requires shift expect(emitSpy).toHaveBeenCalledWith("PIXEL_WHOIS", expect.anything()); // TEMPLATE_MOVE requires alt — should not fire expect(emitSpy).not.toHaveBeenCalledWith( "TEMPLATE_MOVE", expect.anything(), ); // MOD_SELECT requires ctrl — should not fire expect(emitSpy).not.toHaveBeenCalledWith( "MOD_SELECT", expect.anything(), ); }); /* ─── Unknown / non-matching ─── */ it("unknown key returns false and emits nothing", () => { const result = manager.handleInteraction( { key: "F12" }, { clientX: -1, clientY: -1 }, ); expect(result).toBe(false); expect(emitSpy).not.toHaveBeenCalled(); }); it("returns true when at least one keybind matches", () => { const result = manager.handleInteraction( { key: "KeyT" }, { clientX: -1, clientY: -1 }, ); expect(result).toBe(true); }); }); No newline at end of file
packages/client/src/lib/__tests__/utils.test.ts 0 → 100644 +42 −0 Original line number Diff line number Diff line import { describe, it, expect } from "vitest"; import { rgbToHex } from "../utils"; describe("rgbToHex", () => { it('returns "#FF0000" for red', () => { expect(rgbToHex(255, 0, 0)).toBe("#FF0000"); }); it('returns "#00FF00" for green', () => { expect(rgbToHex(0, 255, 0)).toBe("#00FF00"); }); it('returns "#0000FF" for blue', () => { expect(rgbToHex(0, 0, 255)).toBe("#0000FF"); }); it('returns "#000000" for black', () => { expect(rgbToHex(0, 0, 0)).toBe("#000000"); }); it('returns "#FFFFFF" for white', () => { expect(rgbToHex(255, 255, 255)).toBe("#FFFFFF"); }); it("handles leading zeros in components", () => { expect(rgbToHex(15, 15, 15)).toBe("#0F0F0F"); }); it("returns uppercase hex", () => { const result = rgbToHex(171, 205, 239); expect(result).toBe("#ABCDEF"); expect(result).toEqual(result.toUpperCase()); }); it("pads single-digit hex components with leading zero", () => { expect(rgbToHex(1, 2, 3)).toBe("#010203"); }); it("handles mid-range values", () => { expect(rgbToHex(128, 128, 128)).toBe("#808080"); }); }); No newline at end of file