import { describe, expect, it } from "@suaveplan/testing/runner"; import { encode } from "../encoder/encoder.js"; import { Tagged } from "../tags/tagged.js"; import { bytesToDiagnostic, toDiagnostic } from "./diagnostic.js"; describe("toDiagnostic — primitives", () => { it.each([ [null, "null"], [undefined, "undefined"], [true, "true"], [false, "false"], [0, "0"], [-0, "-0"], [1, "1"], [-1, "-1"], [1.5, "1.5"], [Number.NaN, "NaN"], [Number.POSITIVE_INFINITY, "Infinity"], [Number.NEGATIVE_INFINITY, "-Infinity"], [42n, "42"], [-42n, "-42"], ])("%p → %s", { timeout: 5000 }, (input, expected) => { expect(toDiagnostic(input)).toBe(expected); }); it("strings are quoted + escapes applied", { timeout: 5000 }, () => { expect(toDiagnostic("hello")).toBe('"hello"'); expect(toDiagnostic('he said "hi"')).toBe('"he said \\"hi\\""'); expect(toDiagnostic("a\\b")).toBe('"a\\\\b"'); expect(toDiagnostic("line1\nline2")).toBe('"line1\\nline2"'); expect(toDiagnostic("\t")).toBe('"\\t"'); expect(toDiagnostic("\r")).toBe('"\\r"'); expect(toDiagnostic("")).toBe('"\\u0001"'); }); it("byte strings → h''", { timeout: 5000 }, () => { expect(toDiagnostic(new Uint8Array([0xde, 0xad, 0xbe, 0xef]))).toBe( "h'deadbeef'" ); expect(toDiagnostic(new Uint8Array())).toBe("h''"); }); }); describe("toDiagnostic — composite", () => { it("array", { timeout: 5000 }, () => { expect(toDiagnostic([1, 2, 3])).toBe("[1, 2, 3]"); }); it("nested array", { timeout: 5000 }, () => { expect(toDiagnostic([1, [2, 3]])).toBe("[1, [2, 3]]"); }); it("Map renders keys and values via diagnostic", { timeout: 5000 }, () => { const m = new Map([ [1, "a"], ["b", 2], ]); expect(toDiagnostic(m)).toBe('{1: "a", "b": 2}'); }); it("plain object renders keys as quoted strings", { timeout: 5000 }, () => { expect(toDiagnostic({ a: 1, b: "two" })).toBe('{"a": 1, "b": "two"}'); }); it("Tagged renders as tag(inner)", { timeout: 5000 }, () => { expect(toDiagnostic(new Tagged(0, "2026-05-10T12:00:00Z"))).toBe( '0("2026-05-10T12:00:00Z")' ); }); it("Date renders as tag-0", { timeout: 5000 }, () => { const d = new Date("2026-05-10T12:00:00Z"); expect(toDiagnostic(d)).toBe('0("2026-05-10T12:00:00.000Z")'); }); }); describe("toDiagnostic — non-CBOR-encodable fallback", () => { it("function → ", { timeout: 5000 }, () => { expect(toDiagnostic(() => 1)).toBe(""); }); it("symbol → ", { timeout: 5000 }, () => { expect(toDiagnostic(Symbol("x"))).toBe(""); }); }); describe("bytesToDiagnostic", () => { it("decodes + formats raw tags", { timeout: 5000 }, () => { const wire = encode([new Tagged(99, 42), { x: true }]); expect(bytesToDiagnostic(wire)).toBe('[99(42), {"x": true}]'); }); it("byte strings round-trip through diagnostic notation", { timeout: 5000, }, () => { const wire = encode(new Uint8Array([0x01, 0x02])); expect(bytesToDiagnostic(wire)).toBe("h'0102'"); }); });