/** * 命名模板差分:MP(MetaInfo + TemplateContextBuilder + jinja2.Template)vs 我们的 parseRelease + buildNamingVars + renderNamingPath。 * MP 输出由 gen-naming-mp.py 生成(naming-mp.json)。没有登记 deviation 的样例必须与 MP 逐字一致; * 登记了的必须确实不同(差异消除后删掉登记)。说明见 docs/runbook/naming.md。 */ import { readFileSync } from "node:fs"; import { describe, expect, it } from "vitest"; import { buildNamingVars, MP_DEFAULT_NAMING, type NamingEntityInput, type NamingKind, parseRelease, renderNamingPath, validateNamingTemplate, } from "../../src/index.ts"; interface Case { id: string; kind: NamingKind; fileName: string; entity: NamingEntityInput; template?: string; vars?: Record; expect?: string; expectError?: string; deviation?: { kind: "intentional" | "ours" | "representation"; note: string }; } const dir = new URL(".", import.meta.url); const { cases } = JSON.parse(readFileSync(new URL("naming-cases.json", dir), "utf8")) as { cases: Case[] }; const { mp } = JSON.parse(readFileSync(new URL("naming-mp.json", dir), "utf8")) as { mp: Record; }; function ours(c: Case): { path?: string; error?: string } { const template = c.template ?? MP_DEFAULT_NAMING[c.kind]; const v = validateNamingTemplate(template, c.kind); if (!v.ok) return { error: v.errors[0]!.code }; const ext = c.fileName.slice(c.fileName.lastIndexOf(".")); const vars = { ...buildNamingVars(c.entity, parseRelease(c.fileName), { fileExt: ext }), ...c.vars }; const r = renderNamingPath(template, vars); return r.ok ? { path: r.relativePath } : { error: r.errors[0]!.code }; } describe("命名模板差分(MP ↔ naming 引擎)", () => { it("样例 ≥ 25 且每条都有 MP 输出", () => { expect(cases.length).toBeGreaterThanOrEqual(25); for (const c of cases) expect(mp[c.id], c.id).toBeDefined(); }); for (const c of cases) { it(`${c.id} ${c.template ?? `默认 ${c.kind}`} ← ${c.fileName}`, () => { const got = ours(c); if (c.expectError) expect(got).toEqual({ error: c.expectError }); else expect(got).toEqual({ path: c.expect }); const m = mp[c.id]!; if (c.deviation) expect(m.path, `${c.id} 登记为偏离但与 MP 一致,删掉 deviation`).not.toBe(got.path); else expect(m.path, `${c.id} 与 MP 不一致`).toBe(got.path); }); } });