dto.test.js 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. import { test } from 'node:test'
  2. import assert from 'node:assert/strict'
  3. import { determineNextState } from '../../src/state-machine/index.js'
  4. import { buildDto } from '../../src/state-machine/dto.js'
  5. import { makeGitBook, chapter } from './_helper.js'
  6. test('序6 起草细纲:dto 含全书近况 + nextChapter,needsAI=true', async () => {
  7. const { ctx, cleanup } = await makeGitBook({
  8. 'book.yaml': 'spec_version: "7.0"\n书名: 测\n卷规模: 40\n体检周期: 50\n',
  9. '大纲/总纲.md': '# 总纲',
  10. '定稿/正文/0001-起.md': chapter(1),
  11. })
  12. try {
  13. const r = await determineNextState(ctx)
  14. assert.equal(r.序, 6)
  15. assert.equal(r.needsAI, true)
  16. assert.equal(r.dto.nextChapter, 2)
  17. assert.match(r.dto.全书近况, /第\s*1\s*卷/)
  18. assert.ok(r.dto.期望产物.includes('细纲'))
  19. } finally {
  20. await cleanup()
  21. }
  22. })
  23. test('序1 建书引导:dto.缺 含 book.yaml,needsAI=true', async () => {
  24. const { ctx, cleanup } = await makeGitBook({ '大纲/占位.md': 'x' })
  25. try {
  26. const r = await determineNextState(ctx)
  27. assert.equal(r.序, 1)
  28. assert.equal(r.needsAI, true)
  29. assert.ok(r.dto.缺.includes('book.yaml'))
  30. } finally {
  31. await cleanup()
  32. }
  33. })
  34. test('序0 修复确认:dto.failures 指向坏文件', async () => {
  35. const { ctx, cleanup } = await makeGitBook({
  36. 'book.yaml': '书名: 测\n',
  37. '大纲/总纲.md': '# 总纲',
  38. '定稿/正文/0001-起.md': chapter(1),
  39. '定稿/正文/0002-坏.md': '---\n章号: 2\n标题: [未闭合\n---\nx',
  40. })
  41. try {
  42. const r = await determineNextState(ctx)
  43. assert.equal(r.序, 0)
  44. assert.ok(r.dto.failures.length >= 1)
  45. assert.ok(r.dto.failures.some((f) => f.file.includes('0002')))
  46. } finally {
  47. await cleanup()
  48. }
  49. })
  50. test('buildDto 默认分支:非 AI 态返回最简 dto', async () => {
  51. const dto = await buildDto({}, 2, { state: 'relink-manual-edits' })
  52. assert.equal(dto.state, 'relink-manual-edits')
  53. })