stage-chapter.test.js 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. import { test } from 'node:test'
  2. import assert from 'node:assert/strict'
  3. import path from 'node:path'
  4. import { promises as fs } from 'node:fs'
  5. import { run as stageChapterCmd } from '../../src/commands/stage-chapter.js'
  6. import { run as batchStatusCmd } from '../../src/commands/batch-status.js'
  7. import { repoCtx } from './_helper.js'
  8. const 定稿章 = (num) =>
  9. `---\n章号: ${num}\n标题: 第${num}章\n卷: 1\n书内时间: 春月初${num}\n字数: 100\n章定位: 推进\n钩子: 危机钩-强\n情绪定位: 铺垫\n---\n\n第${num}章正文。`
  10. const files = {
  11. 'book.yaml': 'spec_version: "7.0"\n书名: 测\n类型: 玄幻\n每章目标字数: 3000\n卷规模: 40\n连写批次大小: 3\n',
  12. '定稿/正文/0001-第1章.md': 定稿章(1),
  13. '定稿/正文/0002-第2章.md': 定稿章(2),
  14. '大纲/卷纲/第01卷.md': '# 第01卷\n后三章追查黑影。\n',
  15. '工作区/审稿.md': '# 第 3 章审稿单\n\n> 完整两审模式。\n> 共 2 个问题:0 阻断。\n',
  16. }
  17. test('stage-chapter 命令:--payload 文件暂存 + 人话输出;batch-status 出全貌', async () => {
  18. const { ctx, cleanup } = await repoCtx(null, files)
  19. try {
  20. const payload = {
  21. frontMatter: {
  22. 章号: 3,
  23. 标题: '追影',
  24. 卷: 1,
  25. 书内时间: '春月初三',
  26. 字数: 100,
  27. 章定位: '推进',
  28. 钩子: '危机钩-强',
  29. 情绪定位: '铺垫',
  30. 伏笔: ['推进 伏笔-001'],
  31. },
  32. body: '林晚追到后山。',
  33. workspaceFiles: ['工作区/细纲.md'],
  34. }
  35. const payloadPath = path.join(ctx.repoPath, '定稿包-3.json')
  36. await fs.writeFile(payloadPath, JSON.stringify(payload), 'utf8')
  37. const r = await stageChapterCmd(['3'], { payload: payloadPath }, ctx)
  38. assert.equal(r.ok, true, r.error)
  39. assert.match(r.output, /第 3 章已暂存/)
  40. assert.match(r.output, /未入档/)
  41. assert.match(r.output, /可继续写批内下一章/)
  42. const s = await batchStatusCmd([], {}, ctx)
  43. assert.equal(s.ok, true, s.error)
  44. assert.match(s.output, /第 3-3 章,共 1 章/)
  45. assert.match(s.output, /待审收/)
  46. assert.match(s.output, /审稿:2 个问题(0 阻断)/)
  47. assert.match(s.output, /停止条件未命中/)
  48. const j = await batchStatusCmd([], { json: true }, ctx)
  49. const data = JSON.parse(j.output)
  50. assert.equal(data.章[0].章号, 3)
  51. assert.equal(data.停止.stop, false)
  52. } finally {
  53. await cleanup()
  54. }
  55. })
  56. test('stage-chapter 命令:章号不是数字 / 缺 payload / 无批次 status 友好错', async () => {
  57. const { ctx, cleanup } = await repoCtx(null, files)
  58. try {
  59. assert.equal((await stageChapterCmd(['abc'], {}, ctx)).ok, false)
  60. const noPayload = await stageChapterCmd(['3'], {}, ctx)
  61. assert.equal(noPayload.ok, false)
  62. assert.match(noPayload.error, /--payload/)
  63. const st = await batchStatusCmd([], {}, ctx)
  64. assert.equal(st.ok, false)
  65. assert.match(st.error, /没有进行中的待定稿批次/)
  66. } finally {
  67. await cleanup()
  68. }
  69. })