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,111 @@
import { describe, expect, it } from "vitest";
const {
buildLineCellRenderRuns,
createBlankCell,
cloneTerminalCell,
createContinuationCell,
createTerminalCell,
lineCellsToText,
measureCharDisplayColumns,
measureLineCellsDisplayColumns,
resolveUniformLineBackground
} = require("./terminalCursorModel.js");
describe("terminalCursorModel", () => {
it("按 cell 列宽处理宽字符和组合字符", () => {
expect(measureCharDisplayColumns("a")).toBe(1);
expect(measureCharDisplayColumns("中")).toBe(2);
expect(measureCharDisplayColumns("\u0301")).toBe(0);
expect(measureCharDisplayColumns("😀")).toBe(2);
});
it("按固定列缓冲区统计显示列宽,不把 continuation 重复计数", () => {
const row = [
createTerminalCell("A", null, 1),
createTerminalCell("中", null, 2),
createContinuationCell(null),
createTerminalCell("B", null, 1)
];
expect(lineCellsToText(row)).toBe("A中B");
expect(measureLineCellsDisplayColumns(row)).toBe(4);
});
it("渲染 run 会把宽字符 owner 独立出来,并跳过 continuation 占位格", () => {
const styleA = { fg: "#fff", bg: "", bold: false, underline: false };
const styleB = { fg: "#0f0", bg: "", bold: false, underline: false };
const row = [
createTerminalCell("A", styleA, 1),
createTerminalCell("B", styleA, 1),
createTerminalCell("中", styleA, 2),
createContinuationCell(styleA),
createTerminalCell("C", styleB, 1)
];
expect(buildLineCellRenderRuns(row)).toEqual([
{ text: "AB", style: styleA, columns: 2, fixed: false },
{ text: "中", style: styleA, columns: 2, fixed: true },
{ text: "C", style: styleB, columns: 1, fixed: false }
]);
});
it("placeholder blank cell 会保留列宽背景,但不会把尾随补位写进文本快照", () => {
const style = { fg: "", bg: "#666666", bold: false, underline: false };
const row = [
createBlankCell(style),
createBlankCell(style),
createTerminalCell("X", style, 1),
createBlankCell(style),
createBlankCell(style)
];
expect(lineCellsToText(row)).toBe(" X");
expect(buildLineCellRenderRuns(row)).toEqual([
{ text: "", style, columns: 2, fixed: true },
{ text: "X", style, columns: 1, fixed: false },
{ text: "", style, columns: 2, fixed: true }
]);
});
it("整行 run 若共享同一个非空背景色,会返回可提升到 line 层的背景", () => {
const bg = "#203040";
const styleA = { fg: "#ffffff", bg, bold: false, underline: false };
const styleB = { fg: "#89c2ff", bg, bold: true, underline: false };
const row = [
createBlankCell(styleA),
createTerminalCell(">", styleA, 1),
createTerminalCell(" ", styleA, 1),
createTerminalCell("U", styleB, 1),
createTerminalCell("s", styleB, 1),
createTerminalCell("e", styleB, 1),
createBlankCell(styleB)
];
expect(resolveUniformLineBackground(buildLineCellRenderRuns(row))).toBe(bg);
});
it("只要一行里存在无背景或不同背景的 run就不会提升到 line 层", () => {
const rowWithGap = [
createTerminalCell("A", { fg: "#fff", bg: "#111111", bold: false, underline: false }, 1),
createTerminalCell("B", { fg: "#fff", bg: "", bold: false, underline: false }, 1)
];
const rowWithMixedBg = [
createTerminalCell("A", { fg: "#fff", bg: "#111111", bold: false, underline: false }, 1),
createTerminalCell("B", { fg: "#fff", bg: "#222222", bold: false, underline: false }, 1)
];
expect(resolveUniformLineBackground(buildLineCellRenderRuns(rowWithGap))).toBe("");
expect(resolveUniformLineBackground(buildLineCellRenderRuns(rowWithMixedBg))).toBe("");
});
it("克隆 cell 时会复制样式对象,避免覆盖时污染原对象", () => {
const original = createTerminalCell("A", { fg: "#fff", bold: true }, 1);
const cloned = cloneTerminalCell(original);
cloned.style.fg = "#000";
expect(original.style.fg).toBe("#fff");
expect(cloned.style.fg).toBe("#000");
expect(cloned.width).toBe(1);
});
});