diff options
| author | Craig Jennings <c@cjennings.net> | 2026-06-19 11:42:52 -0400 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2026-06-19 11:42:52 -0400 |
| commit | 7ef4737d3a06fb8b39eab3342658be76219ac6dc (patch) | |
| tree | 5c90acb2d69a809ff970b4055ea654ff37df2b49 /scripts/theme-studio/test-app-core.mjs | |
| parent | 3bdf9b23204f4f908d3ef0353b2fe2eb5f9f3d2c (diff) | |
| download | dotemacs-7ef4737d3a06fb8b39eab3342658be76219ac6dc.tar.gz dotemacs-7ef4737d3a06fb8b39eab3342658be76219ac6dc.zip | |
test(theme-studio): cover defensive branches and the palette generator
Added the uncovered fallback branches in app-core (migrateLegacyFace null input, normalizePkgFace's source fallback chain, mergePackagesInto's null/new-app guards, boxCss shading a relief from the bg when no box color is set) and in colormath (apca's equal-luminance return-0 and low-contrast clamp, isPureEndpointHex). New test-palette-generator-core.mjs drives planPaletteGenerator across every scheme, vibe, source mode, and the fill-gaps intents, since those internals are only reachable through the public planner. colormath branch 96 -> 99%, palette-generator-core funcs 97 -> 100%, node suite 237 tests. The remaining gaps are the deep palette-column edge branches, deferred as diminishing returns on already line-covered code.
Diffstat (limited to 'scripts/theme-studio/test-app-core.mjs')
| -rw-r--r-- | scripts/theme-studio/test-app-core.mjs | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/scripts/theme-studio/test-app-core.mjs b/scripts/theme-studio/test-app-core.mjs index e0d3c321a..c6473ae96 100644 --- a/scripts/theme-studio/test-app-core.mjs +++ b/scripts/theme-studio/test-app-core.mjs @@ -1103,3 +1103,35 @@ test('faceCss: Error — opts omitted still works', () => { assert.equal(faceCss({}, '#111', null), 'color:#111;font-weight:normal;font-style:normal;text-decoration:none'); }); + +// --- defensive / fallback branches ------------------------------------------- + +test('migrateLegacyFace: Boundary — null/undefined input yields an empty object', () => { + assert.deepEqual(migrateLegacyFace(null), {}); + assert.deepEqual(migrateLegacyFace(undefined), {}); +}); + +test('normalizePkgFace: Normal — source falls back through arg, d.source, then "user"', () => { + assert.equal(normalizePkgFace({}, 'default').source, 'default'); // arg wins + assert.equal(normalizePkgFace({source: 'cleared'}).source, 'cleared'); // d.source + assert.equal(normalizePkgFace({}).source, 'user'); // default +}); + +test('mergePackagesInto: Boundary — null packages is a no-op', () => { + const map = {existing: {f: {fg: '#111'}}}; + mergePackagesInto(map, null); + assert.deepEqual(Object.keys(map), ['existing']); +}); +test('mergePackagesInto: Normal — a new app key is created', () => { + const map = {}; + mergePackagesInto(map, {newapp: {'face-a': {fg: '#112233', source: 'user'}}}); + assert.ok(map.newapp && map.newapp['face-a']); + assert.equal(map.newapp['face-a'].fg, '#112233'); +}); + +test('boxCss: Boundary — released with no color but a bg shades from the bg', () => { + const fromBg = boxCss({style: 'released'}, '#808080'); + // not the translucent no-bg fallback, and a real two-edge relief + assert.notEqual(fromBg, 'inset 1px 1px 0 #ffffff33,inset -1px -1px 0 #00000066'); + assert.match(fromBg, /^inset 1px 1px 0 \S+,inset -1px -1px 0 \S+$/); +}); |
