feat(engine): add project template cloning factory and unit tests

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
WeiCHEN
2026-09-13 02:50:19 +00:00
committed by weichen
co-authored by Cursor
parent 2faddab7ac
commit 258a8dacd2
2 changed files with 372 additions and 0 deletions
+64
View File
@@ -0,0 +1,64 @@
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);
// 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}}'));
});