const { test } = require("node:test"); const assert = require("node:assert"); const { DEFAULT_TOKENS, deepMerge, normalizeTokens, emptyTokens, tokensAreValid, } = require("../lib/themeSchema"); test("normalizeTokens deep-merges a sparse theme over the defaults", () => { const t = normalizeTokens({ colors: { primary: "#123456" } }); assert.equal(t.colors.primary, "#123456"); // override wins assert.equal(t.colors.success, DEFAULT_TOKENS.colors.success); // default preserved assert.equal(t.$tokensVersion, 1); }); test("normalizeTokens never mutates the frozen DEFAULT_TOKENS", () => { const before = DEFAULT_TOKENS.colors.primary; const t = normalizeTokens({ colors: { primary: "#000000" } }); t.colors.primary = "#ffffff"; assert.equal(DEFAULT_TOKENS.colors.primary, before); }); test("normalizeTokens tolerates junk input", () => { assert.equal(normalizeTokens(null).$tokensVersion, 1); assert.equal(normalizeTokens("nope").colors.primary, DEFAULT_TOKENS.colors.primary); }); test("emptyTokens returns a mutable clone of the defaults", () => { const e = emptyTokens(); e.colors.primary = "#abcdef"; assert.notEqual(DEFAULT_TOKENS.colors.primary, "#abcdef"); }); test("deepMerge replaces scalars and merges nested objects", () => { const out = deepMerge({ a: 1, n: { x: 1, y: 2 } }, { a: 2, n: { y: 3 } }); assert.deepEqual(out, { a: 2, n: { x: 1, y: 3 } }); }); test("tokensAreValid accepts strings, rejects non-string leaves", () => { assert.equal(tokensAreValid(normalizeTokens({})).ok, true); const bad = tokensAreValid({ colors: { primary: 123 } }); assert.equal(bad.ok, false); assert.ok(bad.errors.some((e) => e.includes("colors.primary"))); }); test("tokensAreValid rejects non-object input", () => { assert.equal(tokensAreValid(null).ok, false); assert.equal(tokensAreValid([]).ok, false); });