openclaw / src /commands /models /list.table.test.ts
SaylorTwift's picture
SaylorTwift HF Staff
Add files using upload-large-folder tool
f778c12 verified
Raw History Blame Contribute Delete
3.8 kB
// Model list table tests cover terminal table rendering for model list output.
import { describe, expect, it, vi } from "vitest";
import { visibleWidth } from "../../../packages/terminal-core/src/ansi.js";
import { printModelTable } from "./list.table.js";
import type { ModelRow } from "./list.types.js";
describe("printModelTable", () => {
it("prints an empty model list as valid structured JSON", () => {
const runtime = { log: vi.fn(), error: vi.fn() };
printModelTable([], runtime as never, { json: true });
expect(runtime.log).toHaveBeenCalledTimes(1);
expect(JSON.parse(runtime.log.mock.calls[0]![0] as string)).toEqual({
count: 0,
models: [],
});
});
it("keeps an empty plain model list silent", () => {
const runtime = { log: vi.fn(), error: vi.fn() };
printModelTable([], runtime as never, { plain: true });
expect(runtime.log).not.toHaveBeenCalled();
});
it("writes populated plain model rows directly to stdout", () => {
const runtime = {
log: vi.fn(),
error: vi.fn(),
exit: vi.fn(),
writeStdout: vi.fn(),
writeJson: vi.fn(),
};
const rows: ModelRow[] = [
{
key: "anthropic/claude-sonnet-4-6",
name: "Claude Sonnet",
input: "text",
contextWindow: 200_000,
local: false,
available: true,
tags: [],
},
];
printModelTable(rows, runtime, { plain: true });
expect(runtime.writeStdout).toHaveBeenCalledExactlyOnceWith("anthropic/claude-sonnet-4-6");
expect(runtime.log).not.toHaveBeenCalled();
});
it("prints context caps with sanitized tags in their original order", () => {
const runtime = { log: vi.fn(), error: vi.fn() };
const tags = [
"\u001b[31mdefault\u001b[0m",
"fallback#2",
"img-fallback#1",
"alias:a\tb",
"unknown",
"default",
];
const rows: ModelRow[] = [
{
key: "openai/gpt-5.5",
name: "GPT-5.5",
input: "text+image",
contextWindow: 400_000,
contextTokens: 272_000,
local: false,
available: true,
tags,
},
];
printModelTable(rows, runtime as never);
// Decimal windows render in decimal K: 272000 -> "272k", 400000 -> "400k".
expect(runtime.log.mock.calls).toEqual([
["Model Input Ctx Local Auth Tags"],
[
"openai/gpt-5.5 text+image 272k/400k no yes default,fallback#2,img-fallback#1,alias:a\\tb,unknown,default",
],
]);
expect(rows[0]?.tags).toEqual([
"\u001b[31mdefault\u001b[0m",
"fallback#2",
"img-fallback#1",
"alias:a\tb",
"unknown",
"default",
]);
});
it("keeps fixed-width rows aligned when model keys contain wide graphemes", () => {
const runtime = { log: vi.fn(), error: vi.fn() };
const wideKey = `${"a".repeat(41)}表`;
const rows: ModelRow[] = [
{
key: wideKey,
name: wideKey,
input: "text",
contextWindow: 128_000,
contextTokens: undefined,
local: false,
available: true,
tags: [],
},
];
printModelTable(rows, runtime as never);
const [header, row] = runtime.log.mock.calls.map(([line]) => line);
expect(typeof header).toBe("string");
expect(typeof row).toBe("string");
const headerInputIndex = (header as string).indexOf("Input");
const rowInputIndex = (row as string).indexOf("text");
expect(headerInputIndex).toBeGreaterThan(0);
expect(rowInputIndex).toBeGreaterThan(0);
expect(visibleWidth((row as string).slice(0, rowInputIndex))).toBe(
visibleWidth((header as string).slice(0, headerInputIndex)),
);
});
});