import test from 'node:test'; import assert from 'node:assert'; import { createProjectTemplateDeliverables, STANDARD_WORKFLOW_TEMPLATES, } from './templateFactory'; test('createProjectTemplateDeliverables: 必须精确生成 7 份全生命周期受控文档副本', () => { assert.strictEqual(STANDARD_WORKFLOW_TEMPLATES.length, 7); const result = createProjectTemplateDeliverables({ projectId: 999, projectName: '微创智能吻合吻合器系统', deviceType: '腔镜吻合器', creatorId: 10, creatorName: '赵工程师', }); // 1. 验证数量与任务映射 assert.strictEqual(result.deliverables.length, 7); assert.strictEqual(Object.keys(result.docASTMap).length, 7); const expectedTaskKeys = [ 'intake', 'research', 'feasibility_reg', 'feasibility_dev', 'user_requirements', 'prelim_design', 'cdo_quote', ]; const actualTaskKeys = result.deliverables.map((d) => d.taskKey); assert.deepStrictEqual(actualTaskKeys, expectedTaskKeys); const prelim = result.deliverables.find((d) => d.taskKey === 'prelim_design'); assert.ok(prelim, 'prelim_design template must exist'); assert.strictEqual(prelim.title, '系统初步设计方案'); assert.strictEqual( STANDARD_WORKFLOW_TEMPLATES.find((t) => t.taskKey === 'prelim_design')?.title, '系统初步设计方案', ); // 2. 验证阶段覆盖 (V0.1, V0.5, V1.0) const stages = new Set(result.deliverables.map((d) => d.stage)); assert.ok(stages.has('V0.1')); assert.ok(stages.has('V0.5')); assert.ok(stages.has('V1.0')); // 3. 验证元数据装配与模板标记 result.deliverables.forEach((doc) => { assert.strictEqual(doc.projectId, 999); assert.strictEqual(doc.isTemplateOnly, true); assert.strictEqual(doc.lifecycleState, 'template'); assert.strictEqual(doc.isFixedWorkflow, true); assert.strictEqual(doc.creatorId, 10); assert.strictEqual(doc.creatorName, '赵工程师'); assert.ok(doc.docId.startsWith('doc-p999-')); const ast = result.docASTMap[doc.docId]; assert.ok(ast, `AST for ${doc.docId} should exist`); assert.ok(ast.rootBlock.children && ast.rootBlock.children.length > 0, `AST for ${doc.docId} should have blocks`); }); // 4. 验证变量注入 (项目名、器械类型注入成功,无裸露的宏占位符) const intakeDoc = result.deliverables.find((d) => d.taskKey === 'intake')!; const intakeAst = result.docASTMap[intakeDoc.docId]; const fullText = JSON.stringify(intakeAst); assert.ok(fullText.includes('微创智能吻合吻合器系统')); assert.ok(fullText.includes('腔镜吻合器')); assert.ok(!fullText.includes('{{project_name}}')); assert.ok(!fullText.includes('{{device_type}}')); });