decision.spec.ts 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. /**
  2. * 3c 写入器统一:裁决回写校验失败不落盘。
  3. *
  4. * writeSettlementDecision(原 novel-tools 工具层裸写,收编进 core):
  5. * 清单缺失/机器态解析失败即失败、零写盘;合法清单才写裁决字段。
  6. */
  7. import { afterAll, describe, expect, it } from 'vitest'
  8. import * as fs from 'node:fs'
  9. import * as nodePath from 'node:path'
  10. import * as os from 'node:os'
  11. import { serializeMachineJson, MACHINE_SCHEMA_VERSION, writeSettlementDecision } from '../src/index'
  12. const roots: string[] = []
  13. function mkBook(): string {
  14. const dir = fs.mkdtempSync(nodePath.join(os.tmpdir(), 'webnovel-decision-'))
  15. roots.push(dir)
  16. return dir
  17. }
  18. afterAll(() => { for (const r of roots) { try { fs.rmSync(r, { recursive: true, force: true, maxRetries: 10, retryDelay: 200 }) } catch { /* Windows 句柄延迟释放 */ } } })
  19. const dir = nodePath.join('草稿区', '定稿准备', '卷01-开篇任务')
  20. const 清单abs = (root: string): string => nodePath.join(root, dir, '清单.json')
  21. describe('裁决回写(写入器统一,校验失败不落盘)', () => {
  22. it('缺清单.json → 失败且不写任何文件', () => {
  23. const root = mkBook()
  24. const r = writeSettlementDecision(root, { 卷: 1, 章名: '开篇任务' }, '已批准')
  25. expect(r.ok).toBe(false)
  26. expect(fs.existsSync(nodePath.join(root, dir))).toBe(false)
  27. })
  28. it('清单非机器态 → 解析失败且原文不被改写', () => {
  29. const root = mkBook()
  30. fs.mkdirSync(nodePath.join(root, dir), { recursive: true })
  31. fs.writeFileSync(清单abs(root), '不是 json', 'utf-8')
  32. const r = writeSettlementDecision(root, { 卷: 1, 章名: '开篇任务' }, '已批准')
  33. expect(r.ok).toBe(false)
  34. expect(fs.readFileSync(清单abs(root), 'utf-8')).toBe('不是 json')
  35. })
  36. it('合法清单 → 裁决写入,机器态可解析', () => {
  37. const root = mkBook()
  38. fs.mkdirSync(nodePath.join(root, dir), { recursive: true })
  39. fs.writeFileSync(清单abs(root), serializeMachineJson({ 文件: [], 校验: '通过' }, MACHINE_SCHEMA_VERSION), 'utf-8')
  40. const r = writeSettlementDecision(root, { 卷: 1, 章名: '开篇任务' }, '已退回')
  41. expect(r.ok).toBe(true)
  42. const text = fs.readFileSync(清单abs(root), 'utf-8')
  43. const parsed = JSON.parse(text)
  44. expect(parsed['裁决']).toBe('已退回')
  45. expect(parsed['schemaVersion']).toBe(MACHINE_SCHEMA_VERSION)
  46. })
  47. })