| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768 |
- import { test } from 'node:test'
- import assert from 'node:assert/strict'
- import os from 'node:os'
- import path from 'node:path'
- import { promises as fs } from 'node:fs'
- import { fileURLToPath } from 'node:url'
- import { execFile } from 'node:child_process'
- import { promisify } from 'node:util'
- import { tempV6, inlineFixture } from '../migrate/_v6.js'
- const exec = promisify(execFile)
- const __dirname = path.dirname(fileURLToPath(import.meta.url))
- const BIN = path.join(__dirname, '../../bin/webnovel-writer.js')
- const fixtureRoot = path.join(__dirname, '../fixtures/sample-book')
- /**
- * G-6:M6/M7 新命令的 bin spawn 冒烟——参数解析、exitCode、错误人话(不带栈)。
- * 全走真子进程;finally 的 rm 兼作 cache.close 探针(db 未关 Windows 会 EBUSY/EPERM)。
- */
- test('bin spawn 冒烟:export 单章(书仓库直启)+ 坏参数人话退出', async () => {
- const repo = await fs.mkdtemp(path.join(os.tmpdir(), 'wnw-spawn-book-'))
- await fs.cp(fixtureRoot, repo, { recursive: true })
- const run = (args) => exec(process.execPath, [BIN, ...args], { cwd: repo, encoding: 'utf8' })
- try {
- const r = await run(['export', '1'])
- assert.match(r.stdout, /第0001章-开局\.txt/)
- const exported = await fs.readFile(path.join(repo, '工作区', '导出', '第0001章-开局.txt'), 'utf8')
- assert.ok(exported.length > 0)
- assert.ok(!exported.startsWith('---'), '导出应剥 front matter')
- const err = await run(['export', 'abc']).then(
- () => null,
- (e) => e
- )
- assert.ok(err, '坏参数应非零退出')
- assert.equal(err.code, 1)
- assert.match(err.stderr, /用法/)
- assert.ok(!/\n\s+at /.test(err.stderr), `错误不带栈:${err.stderr}`)
- } finally {
- await fs.rm(repo, { recursive: true, force: true })
- }
- })
- test('bin spawn 冒烟:migrate v6 项目(工作目录)+ 缺参数人话退出', async () => {
- const workdir = await fs.mkdtemp(path.join(os.tmpdir(), 'wnw-spawn-workdir-'))
- await fs.mkdir(path.join(workdir, '.webnovel'), { recursive: true })
- const v6 = await tempV6(inlineFixture)
- const run = (args) => exec(process.execPath, [BIN, ...args], { cwd: workdir, encoding: 'utf8' })
- try {
- const r = await run(['migrate', v6.v6Path])
- assert.match(r.stdout, /迁移报告/)
- await fs.access(path.join(workdir, '剑碎虚空', 'book.yaml'))
- await fs.access(path.join(workdir, '剑碎虚空', '工作区', '迁移报告.md'))
- const err = await run(['migrate']).then(
- () => null,
- (e) => e
- )
- assert.ok(err, '缺参数应非零退出')
- assert.equal(err.code, 1)
- assert.match(err.stderr, /用法/)
- assert.ok(!/\n\s+at /.test(err.stderr), `错误不带栈:${err.stderr}`)
- } finally {
- await fs.rm(workdir, { recursive: true, force: true })
- await v6.cleanup()
- }
- })
|