85 lines
3.3 KiB
TypeScript
85 lines
3.3 KiB
TypeScript
import { AnsiColorMode, AnsiTerminalDisplay } from "./ansi.ts";
|
|
import { Buffer, describe, expect, it } from "./testing.ts";
|
|
|
|
function createTestDisplay(): {
|
|
stdout: Buffer;
|
|
stdin: Buffer;
|
|
display: AnsiTerminalDisplay;
|
|
} {
|
|
const stdout = new Buffer();
|
|
const stdin = new Buffer();
|
|
const display = new AnsiTerminalDisplay(stdout, stdin);
|
|
return { stdout, stdin, display };
|
|
}
|
|
|
|
describe(AnsiTerminalDisplay, () => {
|
|
it("clears the screen on init", async () => {
|
|
const { stdout, display } = createTestDisplay();
|
|
await display.init();
|
|
checkSequence(stdout, "![2J");
|
|
await display.uninit();
|
|
checkSequence(stdout, "![2J![2J");
|
|
});
|
|
|
|
it("writes truecolor characters", async () => {
|
|
const { stdout, display } = createTestDisplay();
|
|
await display.setupPalette([
|
|
{ r: 0.0, g: 0.0, b: 0.0 },
|
|
{ r: 0.5, g: 0.1, b: 1.0 },
|
|
], AnsiColorMode.TRUECOLOR);
|
|
await display.setChar({ x: 0, y: 0 }, { ch: "$", fg: 1, bg: 0 });
|
|
checkSequence(stdout, "![38;2;128;26;255m![48;2;0;0;0m![1;1H$");
|
|
});
|
|
|
|
it("falls back to 256 colors", async () => {
|
|
const { stdout, display } = createTestDisplay();
|
|
const palette = await display.setupPalette([
|
|
{ r: 0.0, g: 0.0, b: 0.0 },
|
|
], AnsiColorMode.COLORS256);
|
|
await display.setChar({ x: 0, y: 0 }, { ch: "a", fg: 0, bg: 1 });
|
|
await display.setChar({ x: 0, y: 0 }, { ch: "b", fg: 2, bg: 3 });
|
|
checkSequence(stdout, "![38;5;0m![48;5;1m![1;1Ha![38;5;2m![48;5;3m![1;1Hb");
|
|
|
|
expect(palette[0]).toEqual({ r: 0, g: 0, b: 0 });
|
|
expect(palette[3]).toEqual({ r: 0.5, g: 0.5, b: 0 });
|
|
expect(palette[14]).toEqual({ r: 0, g: 1, b: 1 });
|
|
expect(palette[67]).toEqual({ r: 0.2, g: 0.4, b: 0.6 });
|
|
expect(palette[234]).toEqual({ r: 0.12, g: 0.12, b: 0.12 });
|
|
});
|
|
|
|
it("moves the cursor only when needed", async () => {
|
|
const { stdout, display } = createTestDisplay();
|
|
display.forceSize({ w: 4, h: 3 });
|
|
await display.setChar({ x: 0, y: 0 }, { ch: "a", fg: 0, bg: 0 });
|
|
await display.setChar({ x: 1, y: 0 }, { ch: "b", fg: 0, bg: 0 });
|
|
await display.setChar({ x: 3, y: 0 }, { ch: "c", fg: 0, bg: 0 });
|
|
await display.setChar({ x: 0, y: 1 }, { ch: "d", fg: 0, bg: 0 });
|
|
await display.setChar({ x: 0, y: 2 }, { ch: "e", fg: 0, bg: 0 });
|
|
checkSequence(stdout, "![1;1Hab![1;4Hcd![3;1He");
|
|
});
|
|
|
|
it("changes colors only when needed", async () => {
|
|
const { stdout, display } = createTestDisplay();
|
|
display.forceSize({ w: 10, h: 1 });
|
|
await display.setupPalette([
|
|
{ r: 0.0, g: 0.0, b: 0.0 },
|
|
], AnsiColorMode.COLORS256);
|
|
await display.setChar({ x: 0, y: 0 }, { ch: "a", fg: 1, bg: 0 });
|
|
await display.setChar({ x: 1, y: 0 }, { ch: "b", fg: 1, bg: 0 });
|
|
await display.setChar({ x: 2, y: 0 }, { ch: "c", fg: 2, bg: 0 });
|
|
await display.setChar({ x: 3, y: 0 }, { ch: "d", fg: 0, bg: 2 });
|
|
await display.setChar({ x: 4, y: 0 }, { ch: "e", fg: 0, bg: 2 });
|
|
await display.setChar({ x: 5, y: 0 }, { ch: "f", fg: 0, bg: 3 });
|
|
checkSequence(
|
|
stdout,
|
|
"![38;5;1m![48;5;0m![1;1Hab![38;5;2mc![38;5;0m![48;5;2mde![48;5;3mf",
|
|
);
|
|
});
|
|
});
|
|
|
|
function checkSequence(buffer: Buffer, expected: string) {
|
|
const decoded = new TextDecoder().decode(
|
|
buffer.bytes().map((x) => x == 0x1B ? 0x21 : x),
|
|
);
|
|
expect(decoded).toEqual(expected);
|
|
}
|