Files
bot-agents/src/opencode_test.ts
T
Danny Kim ea20f6d629 Show the selected bot profile and add OpenRouter fallback (#18)
Uses Codex first, then Claude, then OpenCode through OpenRouter when quota is exhausted.

Every generated comment and review now identifies the selected profile and model in a final quote. The dependent action interface remains one master key.

Verified formatting, lint, type checks, encrypted profile decryption, current OpenCode CLI flags, and 45 tests.

Reviewed-on: #18
Reviewed-by: bot <noreply@capsulizers.com>
Co-authored-by: Danny Kim <temeddix@gmail.com>
Co-committed-by: Danny Kim <temeddix@gmail.com>
2026-09-24 01:39:49 +00:00

77 lines
2.1 KiB
TypeScript

import { assertEquals, assertRejects } from "jsr:@std/assert@1";
import {
collectOpenCodeOutput,
openCodeArgs,
parseOpenCodeEvents,
} from "./opencode.ts";
Deno.test("builds a non-interactive auto-approved OpenCode command", () => {
assertEquals(
openCodeArgs("openrouter/qwen/qwen3.8-27b", "Review this"),
[
"run",
"--format",
"json",
"--auto",
"--model",
"openrouter/qwen/qwen3.8-27b",
"Review this",
],
);
});
Deno.test("returns the final visible OpenCode text event", () => {
assertEquals(
parseOpenCodeEvents([
JSON.stringify({ type: "step_start", part: { type: "step-start" } }),
JSON.stringify({ type: "text", part: { type: "text", text: "draft" } }),
JSON.stringify({ type: "text", part: { type: "text", text: "done" } }),
JSON.stringify({ type: "step_finish", part: { type: "step-finish" } }),
].join("\n")),
"done",
);
});
Deno.test("rejects a successful OpenCode run without visible text", async () => {
await assertRejects(
async () => {
parseOpenCodeEvents('{"type":"step_start"}');
await Promise.resolve();
},
Error,
"no text output",
);
});
Deno.test("streams OpenCode output while collecting it", async () => {
const encode = (value: string) => new TextEncoder().encode(value);
const stdout = new ReadableStream<Uint8Array>({
start(controller) {
controller.enqueue(encode("first\n"));
controller.enqueue(encode("second\n"));
controller.close();
},
});
const stderr = new ReadableStream<Uint8Array>({
start(controller) {
controller.enqueue(encode("warning\n"));
controller.close();
},
});
const shown: string[] = [];
const result = await collectOpenCodeOutput(
stdout,
stderr,
(chunk: Uint8Array) => {
shown.push(`out:${new TextDecoder().decode(chunk)}`);
},
(chunk: Uint8Array) => {
shown.push(`err:${new TextDecoder().decode(chunk)}`);
},
);
assertEquals(result, { stdout: "first\nsecond\n", stderr: "warning\n" });
assertEquals(shown, ["out:first\n", "err:warning\n", "out:second\n"]);
});