Files
remoteconn-gitea/apps/miniprogram/pages/terminal/terminalSpeakableText.test.ts
2026-03-21 18:57:10 +08:00

124 lines
4.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { describe, expect, it } from "vitest";
const {
buildSpeakableTerminalText,
isSpeakableTextLikelyComplete,
splitSpeakableTextForTts,
stripTerminalAnsi
} = require("./terminalSpeakableText.js");
describe("terminalSpeakableText", () => {
it("应提取最近一段自然语言并跳过命令与代码", () => {
const source = [
"$ codex ask",
"正在分析项目结构...",
"const answer = computeResult();",
"",
"请先检查 gateway 的环境变量配置。",
"确认 TTS_SECRET_ID、TTS_SECRET_KEY 与 TTS_REGION 是否一致。"
].join("\n");
expect(buildSpeakableTerminalText(source)).toBe(
"请先检查 gateway 的环境变量配置。确认 TTS_SECRET_ID、TTS_SECRET_KEY 与 TTS_REGION 是否一致。"
);
});
it("只有命令、路径和进度条时应返回空文本", () => {
const source = [
"$ npm run build",
"/Users/demo/project/src/index.ts",
"[====== ] 60%",
"spinner loading"
].join("\n");
expect(buildSpeakableTerminalText(source)).toBe("");
});
it("应跳过 Codex 输入行、状态行与底部 footer只保留回答正文", () => {
const source = [
" Summarize recent commits",
"Working (0s · esc to interrupt)",
"■ Conversation interrupted - tell the model what to do differently.",
"Something went wrong? Hit `/feedback` to report the issue.",
"本次修改主要收口了 TTS 播放链路。",
"同时移除了小程序侧重复下载缓存文件的绕路实现。",
"gpt-5.4 xhigh · 100% left · ~/remoteconn"
].join("\n");
expect(buildSpeakableTerminalText(source)).toBe(
"本次修改主要收口了 TTS 播放链路。同时移除了小程序侧重复下载缓存文件的绕路实现。"
);
});
it("应跳过被终端换行拆开的 footer 残片", () => {
const source = [
"本次修改已经完成。",
"42% left · ~/remoteconn"
].join("\n");
expect(buildSpeakableTerminalText(source)).toBe("本次修改已经完成。");
});
it("应去掉列表项目符号,避免 TTS 在首句前卡住", () => {
const source = [
"• 第一条消息。",
" 第二条消息。",
" 第三条消息。",
" 第四条消息。"
].join("\n");
expect(buildSpeakableTerminalText(source)).toBe("第一条消息。第二条消息。第三条消息。第四条消息。");
});
it("应去掉紧贴正文的项目符号前缀", () => {
const source = ["•第一条消息。", "•第二条消息。"].join("\n");
expect(buildSpeakableTerminalText(source)).toBe("第一条消息。第二条消息。");
});
it("中间夹杂代码块时应继续向上回收同轮正文,而不是只读最后一小段", () => {
const source = [
"第一段说明,先交代修复背景。",
"第二段说明,描述影响范围。",
"```ts",
"const demo = true;",
"```",
"第三段说明,给出处理方式。",
"第四段说明,提醒重启服务。"
].join("\n");
expect(buildSpeakableTerminalText(source, { maxChars: 200 })).toBe(
"第一段说明,先交代修复背景。第二段说明,描述影响范围。第三段说明,给出处理方式。第四段说明,提醒重启服务。"
);
});
it("长中文文本应保留到总量配置上限,并支持后续分段", () => {
const source = "这是一个较长的测试输出。".repeat(40);
const result = buildSpeakableTerminalText(source);
const segments = splitSpeakableTextForTts(result);
expect(Buffer.byteLength(result, "utf8")).toBeLessThanOrEqual(1500);
expect(result.length).toBeLessThanOrEqual(500);
expect(result.length).toBeGreaterThan(0);
expect(segments.length).toBeGreaterThan(1);
segments.forEach((segment: string) => {
expect(Buffer.byteLength(segment, "utf8")).toBeLessThanOrEqual(240);
expect(segment.length).toBeLessThanOrEqual(80);
});
});
it("应支持按自定义总长度提取正文", () => {
const source = "这是一个较长的测试输出。".repeat(40);
const result = buildSpeakableTerminalText(source, { maxChars: 120 });
expect(result.length).toBeLessThanOrEqual(120);
expect(Buffer.byteLength(result, "utf8")).toBeLessThanOrEqual(360);
});
it("应支持去除 ANSI 并判断句子是否收束", () => {
expect(stripTerminalAnsi("\u001b[32m请先检查配置。\u001b[0m")).toBe("请先检查配置。");
expect(isSpeakableTextLikelyComplete("请先检查配置。")).toBe(true);
expect(isSpeakableTextLikelyComplete("请先检查配置")).toBe(false);
});
});