first commit

This commit is contained in:
douboer
2026-03-21 18:57:10 +08:00
commit c49aa1a5e9
570 changed files with 107167 additions and 0 deletions

View File

@@ -0,0 +1,132 @@
import { describe, expect, it } from "vitest";
const {
consumeTerminalSyncUpdateFrames,
createTerminalSyncUpdateState,
extractLooseAnsiSgr,
takeTerminalReplaySlice
} = require("./vtParser.js");
describe("vtParser", () => {
it("不会把 CSI 控制序列从中间切开", () => {
const result = takeTerminalReplaySlice("ab\u001b[31mcd", 4);
expect(result).toEqual({
slice: "ab",
rest: "\u001b[31mcd"
});
});
it("不会把 CRLF 从中间拆开", () => {
expect(takeTerminalReplaySlice("ab\r\ncd", 3)).toEqual({
slice: "ab",
rest: "\r\ncd"
});
expect(takeTerminalReplaySlice("ab\r\ncd", 4)).toEqual({
slice: "ab\r\n",
rest: "cd"
});
});
it("文本开头是完整长控制序列时会整段前进,避免卡死在零进度", () => {
const result = takeTerminalReplaySlice("\u001b]10;?\u001b\\X", 3);
expect(result).toEqual({
slice: "\u001b]10;?\u001b\\",
rest: "X"
});
});
it("文本前缀是不完整控制序列时会返回空 slice交由上层缓存尾巴", () => {
const result = takeTerminalReplaySlice("\u001b[31", 16);
expect(result).toEqual({
slice: "",
rest: "\u001b[31"
});
});
it("会识别不带 ESC 的松散 SGR 复位片段", () => {
expect(extractLooseAnsiSgr("39mtext", 0)).toEqual({
end: 2,
codes: [39]
});
expect(extractLooseAnsiSgr("[1;31mtext", 0)).toEqual({
end: 5,
codes: [1, 31]
});
});
it("非可信 SGR 数字串不会被误识别成样式序列", () => {
expect(extractLooseAnsiSgr("123mtext", 0)).toBeNull();
});
it("会把 `CSI ? 2026 h/l` 包裹的同步刷新窗口延后到结束时一次性吐出", () => {
const first = consumeTerminalSyncUpdateFrames(
"ab\u001b[?2026hcd",
createTerminalSyncUpdateState()
);
expect(first.text).toBe("ab");
expect(first.state).toEqual({
depth: 1,
carryText: "",
bufferedText: "cd"
});
const second = consumeTerminalSyncUpdateFrames("ef\u001b[?2026lg", first.state);
expect(second.text).toBe("cdefg");
expect(second.state).toEqual({
depth: 0,
carryText: "",
bufferedText: ""
});
});
it("同步刷新起始序列若被 chunk 边界截断,会保留到下一帧继续拼", () => {
const first = consumeTerminalSyncUpdateFrames(
"ab\u001b[?2026",
createTerminalSyncUpdateState()
);
expect(first.text).toBe("ab");
expect(first.state).toEqual({
depth: 0,
carryText: "\u001b[?2026",
bufferedText: ""
});
const second = consumeTerminalSyncUpdateFrames("hcd\u001b[?2026l", first.state);
expect(second.text).toBe("cd");
expect(second.state).toEqual({
depth: 0,
carryText: "",
bufferedText: ""
});
});
it("会按和 web 端一致的口径收口 `DCS = 1 s / = 2 s` 同步刷新窗口", () => {
const first = consumeTerminalSyncUpdateFrames(
"ab\u001bP=1s\u001b\\cd",
createTerminalSyncUpdateState()
);
expect(first.text).toBe("ab");
expect(first.state).toEqual({
depth: 1,
carryText: "",
bufferedText: "cd"
});
const second = consumeTerminalSyncUpdateFrames("ef\u001bP=2s\u001b\\g", first.state);
expect(second.text).toBe("cdefg");
expect(second.state).toEqual({
depth: 0,
carryText: "",
bufferedText: ""
});
});
});