import { describe, it, expect, vi, beforeEach, afterEach } from "vitest"; import { createDebugLogger } from "./log"; describe("createDebugLogger", () => { beforeEach(() => { vi.spyOn(console, "debug").mockImplementation(() => {}); }); afterEach(() => { vi.restoreAllMocks(); }); it("returns a function", () => { expect(typeof createDebugLogger("test")).toBe("function"); }); it("prefixes output with [namespace]", () => { const log = createDebugLogger("my-ns"); log("hello"); expect(console.debug).toHaveBeenCalledWith("[my-ns] hello"); }); it("logs plain strings as-is", () => { const log = createDebugLogger("ns"); log("simple message"); expect(console.debug).toHaveBeenCalledWith("[ns] simple message"); }); it("flattens plain objects to key=value pairs", () => { const log = createDebugLogger("ns"); log("msg", { a: 1, b: "hello world" }); expect(console.debug).toHaveBeenCalledWith('[ns] msg a=1 b="hello world"'); }); it("quotes values containing spaces", () => { const log = createDebugLogger("ns"); log({ key: "value with space" }); expect(console.debug).toHaveBeenCalledWith('[ns] key="value with space"'); }); it("leaves bare values unquoted", () => { const log = createDebugLogger("ns"); log({ key: "simple_value" }); expect(console.debug).toHaveBeenCalledWith("[ns] key=simple_value"); }); it("formats null and undefined", () => { const log = createDebugLogger("ns"); log({ a: null, b: undefined }); expect(console.debug).toHaveBeenCalledWith("[ns] a=null b=undefined"); }); it("formats numbers and booleans", () => { const log = createDebugLogger("ns"); log({ count: 42, flag: true }); expect(console.debug).toHaveBeenCalledWith("[ns] count=42 flag=true"); }); it("formats Error objects with name and message", () => { const log = createDebugLogger("ns"); log({ err: new Error("boom") }); expect(console.debug).toHaveBeenCalledWith('[ns] err={"name":"Error","message":"boom"}'); }); it("serializes nested objects as JSON", () => { const log = createDebugLogger("ns"); log({ nested: { x: 1 } }); expect(console.debug).toHaveBeenCalledWith('[ns] nested={"x":1}'); }); it("mixes strings and objects in a single call", () => { const log = createDebugLogger("ns"); log("prefix", { a: 1 }, "suffix"); expect(console.debug).toHaveBeenCalledWith("[ns] prefix a=1 suffix"); }); });