deepseek-harness/scripts/translation-prompt.spec.ts
ZiyaZhang 64d70670e8 docs(i18n): address ds-review-bot on the v4 restoration
解析器:三段闭合标签改为行首锚定(正文提及 </translation> 不再截
断)、重复段全文扫描并校验段序(补两条回归测试)。切换行:v4 模板
保持字面占位不变,资产文档写明全新配对由流水线在解析后按目标文件
名机械插入、配对门禁兜底。加粗后空格限定于字母/数字/汉字、标点前
一律不加;RFC 2119 关键词改为保留源侧强调标记(斜体归斜体、加粗
归加粗)。i18n README 双侧同步 v4 契约描述(不再承诺 CDATA 协议与
规则注入)并重录配对。
2026-07-20 19:46:46 -07:00

61 lines
3.1 KiB
TypeScript

/** Unit tests for the prompt-v4 renderer and three-section response parser. */
import { readFileSync } from 'node:fs'
import { join, resolve } from 'node:path'
import { describe, expect, it } from 'vitest'
import {
parseTranslationResponse,
renderTranslationPrompt,
renderTranslationResponse,
} from './translation-prompt.ts'
const root = resolve(import.meta.dirname, '..')
const document = readFileSync(join(root, 'docs/i18n/translation-prompt.md'), 'utf8')
const terminology = '| English | 中文 |\n|---|---|\n| agent | agent |'
describe('translation prompt rendering', () => {
it('renders both directions with every placeholder resolved', () => {
const en = renderTranslationPrompt(document, { sourceLanguage: 'English', terminology })
expect(en).toContain('from English to Chinese')
expect(en).toContain(terminology)
expect(en).not.toContain('{{')
const zh = renderTranslationPrompt(document, { sourceLanguage: 'Chinese', terminology })
expect(zh).toContain('from Chinese to English')
})
it('rejects a template with unknown or missing placeholders', () => {
const alien = document.replaceAll('{{terminology}}', '{{terms_prompt}}')
expect(() => renderTranslationPrompt(alien, { sourceLanguage: 'English', terminology })).toThrow(/unsupported placeholder/)
const missing = document.replaceAll('{{terminology}}', '')
expect(() => renderTranslationPrompt(missing, { sourceLanguage: 'English', terminology })).toThrow(/required placeholder/)
})
})
describe('translation response sections', () => {
it('round-trips Markdown bodies', () => {
const response = { translation: '# 标题\n\n正文 **加粗**。', review: '- [Tone] 修正一处。\n- 无修正', final: '# 标题\n\n定稿。' }
expect(parseTranslationResponse(renderTranslationResponse(response))).toEqual(response)
})
it('tolerates a fenced xml wrapper around the whole response', () => {
const fenced = '```xml\n<translation>\nA\n</translation>\n\n<review>\n- 无修正\n</review>\n\n<final>\nA\n</final>\n```'
expect(parseTranslationResponse(fenced).final).toBe('A')
})
it('keeps an inline close tag inside prose from terminating the section', () => {
const doc = { translation: 'the wire format uses </translation> as its close tag', review: '- 无修正', final: 'F' }
expect(parseTranslationResponse(renderTranslationResponse(doc))).toEqual(doc)
})
it('rejects a duplicate section appearing before final', () => {
const early = '<translation>\nA\n</translation>\n<translation>\nB\n</translation>\n<review>\nR\n</review>\n<final>\nF\n</final>'
expect(() => parseTranslationResponse(early)).toThrow(/duplicate <translation>/)
})
it('rejects missing, unterminated, or duplicated sections', () => {
expect(() => parseTranslationResponse('<translation>\nA\n</translation>')).toThrow(/missing or unterminated <review>/)
expect(() => parseTranslationResponse('<translation>\nA')).toThrow(/missing or unterminated <translation>/)
const dup = '<translation>\nA\n</translation>\n<review>\nR\n</review>\n<final>\nF\n</final>\n<final>\nG\n</final>'
expect(() => parseTranslationResponse(dup)).toThrow(/duplicate <final>/)
})
})