Files
Kilo-Org_kilocode/packages/opencode/test/kilocode/cli/roll-call.test.ts
T
2026-05-13 13:54:51 -03:00

162 lines
4.8 KiB
TypeScript

import { test, expect, describe } from "bun:test"
import { Provider } from "../../../src/provider/provider"
import { formatTable, formatMarkdown, handle, isTextModel } from "../../../src/kilocode/cli/cmd/roll-call"
const base = {
input: { text: false, audio: false, image: false, video: false, pdf: false },
output: { text: false, audio: false, image: false, video: false, pdf: false },
}
function caps(opts: { input?: Partial<typeof base.input>; output?: Partial<typeof base.output> }) {
return {
capabilities: {
...base,
input: { ...base.input, ...opts.input },
output: { ...base.output, ...opts.output },
},
} as Provider.Model
}
describe("formatTable", () => {
test("formats simple table correctly", () => {
const rows = [
["kilo/test-model", "YES", "Hello!", "1000ms"],
["kilo/another-model", "NO", "(Error)", "500ms"],
]
const result = formatTable(rows, 120)
expect(result.header).toContain("Model")
expect(result.header).toContain("Access")
expect(result.header).toContain("Snippet")
expect(result.header).toContain("Latency")
expect(result.separator).toMatch(/^-+$/)
expect(result.rows).toHaveLength(2)
})
test("truncates long snippets", () => {
const rows = [["model", "YES", "A".repeat(200), "100ms"]]
const result = formatTable(rows, 80)
const start = result.rows[0].indexOf("AAA")
expect(start).toBeGreaterThanOrEqual(0)
})
test("strips ANSI codes from cells", () => {
const rows = [["\x1b[31mmodel\x1b[0m", "YES", "text", "100ms"]]
const result = formatTable(rows, 120)
expect(result.rows[0]).not.toContain("\x1b[")
expect(result.rows[0]).toContain("model")
})
test("handles empty rows", () => {
const result = formatTable([], 120)
expect(result.rows).toHaveLength(0)
expect(result.header).toContain("Model")
})
test("handles special characters in cells", () => {
const rows = [
["model\nwith\nnewlines", "YES", "text\ttab", "100ms"],
["model\r\nwindows", "YES", "text", "100ms"],
]
const result = formatTable(rows, 120)
expect(result.rows[0]).not.toContain("\n")
expect(result.rows[0]).not.toContain("\t")
expect(result.rows[1]).not.toContain("\r")
})
test("adjusts column widths for terminal", () => {
const rows = [["very-long-model-name-here", "YES", "short", "100ms"]]
const wide = formatTable(rows, 200)
const narrow = formatTable(rows, 60)
expect(wide.header.indexOf("Snippet")).toBeGreaterThanOrEqual(0)
expect(narrow.header.indexOf("Snippet")).toBeGreaterThanOrEqual(0)
})
})
describe("isTextModel", () => {
test("accepts text-in text-out model", () => {
expect(isTextModel(caps({ input: { text: true }, output: { text: true } }))).toBe(true)
})
test("accepts multimodal model with text capability", () => {
expect(isTextModel(caps({ input: { text: true, image: true }, output: { text: true } }))).toBe(true)
})
test("rejects audio-in text-out model", () => {
expect(isTextModel(caps({ input: { audio: true }, output: { text: true } }))).toBe(false)
})
test("rejects text-in image-out model", () => {
expect(isTextModel(caps({ input: { text: true }, output: { image: true } }))).toBe(false)
})
test("rejects embedding model", () => {
expect(isTextModel(caps({ input: { text: true } }))).toBe(false)
})
})
describe("formatMarkdown", () => {
test("produces valid markdown table", () => {
const rows = [
["openai/gpt-4o", "YES", "Hello!", "500ms"],
["openai/gpt-3.5", "NO", "(timeout)", "25000ms"],
]
const md = formatMarkdown(rows)
const lines = md.split("\n")
expect(lines[0]).toMatch(/^\|.*Model.*\|.*Access.*\|.*Snippet.*\|.*Latency.*\|$/)
expect(lines[1]).toMatch(/^\| -+ \| -+ \| -+ \| -+ \|$/)
expect(lines).toHaveLength(4)
})
test("handles empty rows", () => {
const md = formatMarkdown([])
const lines = md.split("\n")
expect(lines).toHaveLength(2)
})
test("escapes pipe characters in cells", () => {
const rows = [["model", "YES", "hello | world", "100ms"]]
const md = formatMarkdown(rows)
expect(md).toContain("hello \\| world")
expect(md.split("\n")[2].match(/(?<!\\)\|/g)?.length).toBe(5)
})
})
describe("handle", () => {
test("does not print progress before markdown output", async () => {
const logs: string[] = []
const print = console.log
const code = process.exitCode
console.log = (msg?: unknown) => {
logs.push(String(msg))
}
try {
await handle({
prompt: "Hello",
timeout: 1,
filter: "test",
parallel: 1,
output: "md",
verbose: true,
quiet: false,
list: async () => ({}),
})
} finally {
console.log = print
process.exitCode = code
}
expect(logs).toEqual([formatMarkdown([])])
})
})