/** * scaffold-theme — `prdSlice` is STRICT (audit 2026-09-24, B-WARN-20): the * schema is `prdSlice.theme.{accent,darkBg,lightBg,radiusCard,radiusControl,dataviz}` * and a flat or misspelt slice used to be silently stripped to the defaults. */ import { describe, it, expect, beforeAll, afterAll } from 'vitest'; import { mkdirSync, mkdtempSync, rmSync } from 'node:fs'; import { tmpdir } from 'node:os'; import path from 'node:path'; import { validate } from '../validate.js'; let root: string; beforeAll(() => { root = mkdtempSync(path.join(tmpdir(), 'ss-theme-strict-')); mkdirSync(path.join(root, 'src'), { recursive: true }); }); afterAll(() => rmSync(root, { recursive: true, force: true })); const spec = (prdSlice: unknown) => ({ projectPath: root, appCode: 'myapp', prdSlice }); describe('prdSlice — strict', () => { it('accepts the documented shape, null and omission', () => { expect(validate(spec({ theme: { accent: '#ff0000', radiusControl: 0 } })).valid).toBe(true); expect(validate(spec(null)).valid).toBe(true); expect(validate({ projectPath: root, appCode: 'myapp' }).valid).toBe(true); }); it('REFUSES a flat slice (the tokens outside `theme`) instead of defaulting silently', () => { const r = validate(spec({ accent: '#ff0000' })); expect(r.valid).toBe(false); expect(r.errors.join('\n')).toMatch(/prdSlice/); }); it('REFUSES an unknown token key', () => { const r = validate(spec({ theme: { accent: '#ff0000', accentDark: '#000000' } })); expect(r.valid).toBe(false); expect(r.errors.join('\n')).toMatch(/prdSlice\.theme/); }); });