first commit
This commit is contained in:
111
apps/miniprogram/pages/terminal/terminalCursorModel.test.ts
Normal file
111
apps/miniprogram/pages/terminal/terminalCursorModel.test.ts
Normal 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);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user