import assert from 'node:assert/strict'; import test from 'node:test'; import { getUnpassedReviewFiles, getFeatureDirectory, getRequiredFeatureFiles, validateFeatureId, } from './feature-record.mjs'; test('接受带业务域和三位序号的功能编号', () => { assert.equal(validateFeatureId('FEAT-MO-001'), true); assert.equal(validateFeatureId('GOV-001'), true); }); test('拒绝无法追溯或格式含糊的功能编号', () => { assert.equal(validateFeatureId('market-overview'), false); assert.equal(validateFeatureId('FEAT-MO-1'), false); assert.equal(validateFeatureId('../FEAT-MO-001'), false); }); test('将功能编号和短名称解析到固定的功能档案目录', () => { assert.equal( getFeatureDirectory('/repo', 'FEAT-MO-001', 'market-overview'), '/repo/docs/features/FEAT-MO-001-market-overview', ); }); test('返回开发完成前必须存在的完整追溯文件清单', () => { assert.deepEqual(getRequiredFeatureFiles(), [ 'manifest.yaml', 'prd.md', 'requirements.md', 'design.md', 'implementation-plan.md', 'test-plan.md', 'gitnexus/before.md', 'gitnexus/impact-plan.md', 'gitnexus/detected-changes.md', 'gitnexus/after.md', 'gitnexus/comparison.md', 'qa/test-results.md', 'qa/visual-qa.md', 'review/code-review.md', 'review/standards-review.md', 'release-notes.md', 'rollback.md', ]); }); test('只有两份 Review 都明确通过时才允许发布', () => { const reports = new Map([ ['review/code-review.md', '# 代码 Review\n\n最终结论:passed\n'], ['review/standards-review.md', '# 规范 Review\n\n状态:pending\n'], ]); assert.deepEqual(getUnpassedReviewFiles(reports), [ 'review/standards-review.md', ]); reports.set( 'review/standards-review.md', '# 规范 Review\n\n最终结论:passed\n', ); assert.deepEqual(getUnpassedReviewFiles(reports), []); });