Files
gnoma/internal/provider/subprocess/agent_test.go
T
vikingowl 44d0bdc032 feat(provider): subprocess CLI provider for claude, gemini, vibe
Adds internal/provider/subprocess — a provider.Provider that spawns CLI
agents (claude, gemini, vibe) as subprocesses and streams their output.

- FormatParser interface + three parsers for claude-stream-json,
  gemini-stream-json, and vibe-streaming formats; fixtures captured from
  real binaries
- subprocessStream: pull-based stream.Stream over subprocess stdout with
  bounded stderr capture (8KB) and guarded reap() to prevent double-Wait
- DiscoverCLIAgents: parallel PATH scan with 10s timeout, stable ordering
- Provider: only the last user message is passed as --prompt; all other
  request fields (history, tools, system prompt) are intentionally ignored
  (see package doc)
- main.go: discover and register CLI arms at startup; TODO(P0c) for
  tier-based routing to enforce preference order explicitly
2026-05-07 14:29:34 +02:00

75 lines
1.7 KiB
Go

package subprocess
import (
"testing"
)
func TestKnownAgents_Defined(t *testing.T) {
if len(knownAgents) == 0 {
t.Fatal("knownAgents must not be empty")
}
for _, a := range knownAgents {
if a.Name == "" {
t.Errorf("agent with empty Name: %+v", a)
}
if a.DisplayName == "" {
t.Errorf("agent %q has empty DisplayName", a.Name)
}
if a.Format == "" {
t.Errorf("agent %q has empty Format", a.Name)
}
if a.PromptArgs == nil {
t.Errorf("agent %q has nil PromptArgs", a.Name)
}
}
}
func TestKnownAgents_UniqueNames(t *testing.T) {
seen := make(map[string]bool)
for _, a := range knownAgents {
if seen[a.Name] {
t.Errorf("duplicate agent name %q", a.Name)
}
seen[a.Name] = true
}
}
func TestKnownAgents_ValidFormats(t *testing.T) {
valid := map[StreamFormat]bool{
FormatClaudeStreamJSON: true,
FormatGeminiStreamJSON: true,
FormatVibeStreaming: true,
}
for _, a := range knownAgents {
if !valid[a.Format] {
t.Errorf("agent %q has unknown format %q", a.Name, a.Format)
}
}
}
func TestKnownAgents_PromptArgsIncludePrompt(t *testing.T) {
const testPrompt = "TESTPROMPT_UNIQUE_SENTINEL"
for _, a := range knownAgents {
args := a.PromptArgs(testPrompt)
found := false
for _, arg := range args {
if arg == testPrompt {
found = true
break
}
}
if !found {
t.Errorf("agent %q PromptArgs(%q) does not include the prompt in args: %v", a.Name, testPrompt, args)
}
}
}
func TestNewParser_ReturnsParserForKnownFormats(t *testing.T) {
for _, f := range []StreamFormat{FormatClaudeStreamJSON, FormatGeminiStreamJSON, FormatVibeStreaming} {
p := newParser(f)
if p == nil {
t.Errorf("newParser(%q) returned nil", f)
}
}
}