Add terminal.test.ts unit tests
This commit is contained in:
parent
0366e459f5
commit
6c7de2332b
1 changed files with 100 additions and 0 deletions
100
src/terminal.test.ts
Normal file
100
src/terminal.test.ts
Normal file
|
|
@ -0,0 +1,100 @@
|
||||||
|
import { describe, expect, test } from "bun:test";
|
||||||
|
import { createTerminal, disposeTerminal, serializeAsHTML } from "./terminal";
|
||||||
|
|
||||||
|
// Helper to write to terminal and wait for completion
|
||||||
|
function writeSync(
|
||||||
|
term: ReturnType<typeof createTerminal>,
|
||||||
|
data: string,
|
||||||
|
): Promise<void> {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
term.terminal.write(data, resolve);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
describe("terminal", () => {
|
||||||
|
test("creates terminal with correct dimensions", () => {
|
||||||
|
const term = createTerminal(80, 24);
|
||||||
|
expect(term.terminal.cols).toBe(80);
|
||||||
|
expect(term.terminal.rows).toBe(24);
|
||||||
|
disposeTerminal(term);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("writes data to terminal buffer", async () => {
|
||||||
|
const term = createTerminal(80, 24);
|
||||||
|
await writeSync(term, "Hello, world!");
|
||||||
|
const html = serializeAsHTML(term);
|
||||||
|
expect(html).toContain("Hello, world!");
|
||||||
|
disposeTerminal(term);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("handles ANSI cursor movement", async () => {
|
||||||
|
const term = createTerminal(80, 24);
|
||||||
|
await writeSync(term, "AAA\x1b[3D"); // Write AAA, move cursor back 3
|
||||||
|
await writeSync(term, "BBB"); // Overwrite with BBB
|
||||||
|
const html = serializeAsHTML(term);
|
||||||
|
expect(html).toContain("BBB");
|
||||||
|
expect(html).not.toContain("AAA");
|
||||||
|
disposeTerminal(term);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("handles carriage return correctly", async () => {
|
||||||
|
const term = createTerminal(80, 24);
|
||||||
|
await writeSync(term, "Old text\rNew"); // CR should move to col 0
|
||||||
|
const html = serializeAsHTML(term);
|
||||||
|
expect(html).toContain("New");
|
||||||
|
expect(html).not.toContain("Old");
|
||||||
|
disposeTerminal(term);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("handles incomplete ANSI sequences across writes", async () => {
|
||||||
|
const term = createTerminal(80, 24);
|
||||||
|
await writeSync(term, "Hello\x1b["); // Incomplete CSI
|
||||||
|
await writeSync(term, "31mRed\x1b[0m"); // Complete it
|
||||||
|
const html = serializeAsHTML(term);
|
||||||
|
expect(html).toContain("Red");
|
||||||
|
// Check for red styling (color may vary in format)
|
||||||
|
expect(html).toMatch(/color|red|#[a-f0-9]{6}/i);
|
||||||
|
disposeTerminal(term);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("handles screen clearing", async () => {
|
||||||
|
const term = createTerminal(80, 24);
|
||||||
|
await writeSync(term, "First line\n");
|
||||||
|
await writeSync(term, "Second line");
|
||||||
|
await writeSync(term, "\x1b[2J"); // Clear screen
|
||||||
|
await writeSync(term, "\x1b[H"); // Cursor home
|
||||||
|
await writeSync(term, "After clear");
|
||||||
|
const html = serializeAsHTML(term);
|
||||||
|
expect(html).toContain("After clear");
|
||||||
|
// "First line" should be in scrollback but not current screen
|
||||||
|
disposeTerminal(term);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("handles cursor position command", async () => {
|
||||||
|
const term = createTerminal(80, 24);
|
||||||
|
await writeSync(term, "\x1b[5;10H"); // Move cursor to row 5, col 10
|
||||||
|
await writeSync(term, "Positioned");
|
||||||
|
const html = serializeAsHTML(term);
|
||||||
|
expect(html).toContain("Positioned");
|
||||||
|
// CSI H should not leak through as literal characters
|
||||||
|
expect(html).not.toMatch(/^[HJ]$/m);
|
||||||
|
disposeTerminal(term);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("handles resize", () => {
|
||||||
|
const term = createTerminal(80, 24);
|
||||||
|
term.terminal.resize(120, 40);
|
||||||
|
expect(term.terminal.cols).toBe(120);
|
||||||
|
expect(term.terminal.rows).toBe(40);
|
||||||
|
disposeTerminal(term);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("serialize returns valid HTML structure", async () => {
|
||||||
|
const term = createTerminal(80, 24);
|
||||||
|
await writeSync(term, "Test content");
|
||||||
|
const html = serializeAsHTML(term);
|
||||||
|
// Should be valid HTML (has span structure from xterm serialize addon)
|
||||||
|
expect(html).toMatch(/<span|<div|Test content/);
|
||||||
|
disposeTerminal(term);
|
||||||
|
});
|
||||||
|
});
|
||||||
Loading…
Reference in a new issue