From 5459a6d6148a8f2a24e0b400bd7ea3d8e9fc6aaf Mon Sep 17 00:00:00 2001 From: bendtherules Date: Thu, 12 Mar 2026 21:31:18 +0530 Subject: [PATCH] plan: testing setup --- .opencode/plans/1773330460043-shiny-wolf.md | 111 ++++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 .opencode/plans/1773330460043-shiny-wolf.md diff --git a/.opencode/plans/1773330460043-shiny-wolf.md b/.opencode/plans/1773330460043-shiny-wolf.md new file mode 100644 index 0000000..9812cfa --- /dev/null +++ b/.opencode/plans/1773330460043-shiny-wolf.md @@ -0,0 +1,111 @@ +--- +model: google/gemini-3.1-pro-preview +--- + +# Plan: Lightweight Testing for `multi-model.ts` + +## Overview +To test `.opencode/tools/multi-model.ts` without executing actual commands on your filesystem or Git repository, we will use **`bun:test`**. +Since your project is already utilizing Bun (evident from `Bun.$`), `bun:test` is the perfect built-in, zero-dependency, and lightweight testing framework. It comes with Jest-compatible mocking out of the box. + +## Mocking Strategy +The tool interacts with the system via three main avenues, all of which we will mock: +1. **Filesystem checks (`node:fs`)**: The tool only uses `fs.existsSync`. We will mock this using `spyOn(fs, 'existsSync')`. +2. **OS details (`node:os`)**: We will mock `os.homedir()` using `spyOn(os, 'homedir')` to return a safe, fake path. +3. **Shell commands (`Bun.$`)**: The tool extensively executes `git`, `tmux`, and `opencode` commands via `Bun.$`${parts}`.quiet().nothrow()`. We can override `globalThis.Bun.$` with a custom mock function that inspects the command parts and returns simulated deterministic outputs (exit code, stdout, stderr). + +## Implementation Details + +Create a new file `.opencode/tools/multi-model.test.ts` and set up the mocks as follows: + +```typescript +import { expect, test, mock, spyOn, beforeEach, afterEach } from "bun:test"; +import * as fs from "node:fs"; +import * as os from "node:os"; +import multiModelTool from "./multi-model"; + +// 1. Mock OS and FS +spyOn(os, "homedir").mockReturnValue("/mock/home"); +const existsSyncMock = spyOn(fs, "existsSync").mockReturnValue(false); + +// 2. Mock Bun.$ +const originalBun$ = Bun.$; +let mockCommandResponses: Record = {}; + +function setupMockBun$() { + (globalThis as any).Bun.$ = mock((strings: TemplateStringsArray, ...values: any[]) => { + // In Bun.$`${parts}`, parts is an array passed as the first value + const parts = values[0] as string[]; + const commandSignature = parts.join(" "); + + return { + quiet: () => ({ + nothrow: async () => { + // You can define specific responses for specific commands + if (mockCommandResponses[commandSignature]) { + return mockCommandResponses[commandSignature]; + } + + // Default successful response + return { + exitCode: 0, + stdout: { toString: () => "" }, + stderr: { toString: () => "" }, + }; + }, + }), + }; + }); +} + +beforeEach(() => { + setupMockBun$(); + existsSyncMock.mockClear(); + mockCommandResponses = { + // Provide a default opencode models list for tests + "opencode models": { + exitCode: 0, + stdout: { toString: () => "openai/gpt-4\nanthropic/claude-3" }, + stderr: { toString: () => "" } + }, + // Mock that session does not exist by default + "tmux has-session -t test-session": { + exitCode: 1, // 1 means session does not exist in tmux + stdout: { toString: () => "" }, + stderr: { toString: () => "session not found" } + } + }; +}); + +afterEach(() => { + // Restore original Bun.$ + (globalThis as any).Bun.$ = originalBun$; +}); + +// 3. Write Tests +test("fails if duplicate models are provided", async () => { + const result = await multiModelTool.execute( + { sessionName: "test-session", models: ["openai/gpt-4", "openai/gpt-4"] }, + { metadata: mock() } as any + ); + + expect(result).toContain("Duplicate model names are not allowed"); +}); + +test("successfully plans and executes tmux launch", async () => { + const result = await multiModelTool.execute( + { sessionName: "test-session", models: ["openai/gpt-4", "anthropic/claude-3"] }, + { metadata: mock() } as any + ); + + expect(result).toContain("Use `tmux attach -t test-session` to join session"); + // You can also assert that Bun.$ was called with specific commands + // by inspecting (globalThis as any).Bun$.mock.calls +}); +``` + +## Verification +You can verify and run these tests safely without any system side-effects by running: +```bash +bun test .opencode/tools/multi-model.test.ts +``` \ No newline at end of file