Files
ratatoskr-go/internal/opencode/extract_test.go
Hermes 4ebafc48d0
All checks were successful
build-test / build (push) Successful in 1m21s
internal/opencode: runner (idle/hard timeout, process-group kill, resume-fallback) + verdict/json parsing
2026-08-14 13:29:05 +05:00

116 lines
2.7 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package opencode
import (
"strings"
"testing"
)
func TestExtractVerdict(t *testing.T) {
cases := []struct {
name string
in string
want string
}{
{
name: "один text-парт NDJSON",
in: `{"type":"text","part":{"text":"hello"}}`,
want: "hello",
},
{
name: "несколько партов — берём последний text",
in: "{\"type\":\"step_start\",\"part\":{}}\n{\"type\":\"text\",\"part\":{\"text\":\"первый\"}}\n{\"type\":\"reasoning\",\"part\":{}}\n{\"type\":\"text\",\"part\":{\"text\":\"финал\"}}",
want: "финал",
},
{
name: "нет JSON — возвращаем строку как есть",
in: "простой текст без json",
want: "простой текст без json",
},
{
name: "пустая строка",
in: "",
want: "",
},
{
name: "text с пустым текстом пропускается",
in: "{\"type\":\"text\",\"part\":{\"text\":\"\"}}\n{\"type\":\"text\",\"part\":{\"text\":\"вал\"}}",
want: "вал",
},
}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
if got := ExtractVerdict(c.in); got != c.want {
t.Errorf("ExtractVerdict(%q) = %q, want %q", c.in, got, c.want)
}
})
}
}
func TestExtractJSON(t *testing.T) {
cases := []struct {
name string
in string
want map[string]string
ok bool
}{
{
name: "fenced json",
in: "Вот ответ:\n```json\n{\"decision\":\"go\"}\n```",
want: map[string]string{"decision": "go"},
ok: true,
},
{
name: "fenced json без тега",
in: "```\n{\"a\":1}\n```",
want: map[string]string{"a": "1"},
ok: true,
},
{
name: "голый json-объект в тексте",
in: "Решение: {\"phase\":\"propose\"}",
want: map[string]string{"phase": "propose"},
ok: true,
},
{
name: "нет json",
in: "просто текст",
ok: false,
},
{
name: "невалидный json в fence",
in: "```json\n{no:json}\n```",
ok: false,
},
{
name: "пустая строка",
in: " ",
ok: false,
},
}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
got, ok := ExtractJSON(c.in)
if ok != c.ok {
t.Fatalf("ExtractJSON(%q) ok = %v, want %v", c.in, ok, c.ok)
}
if !ok {
return
}
for k, v := range c.want {
if !strings.Contains(string(got[k]), v) {
t.Errorf("ExtractJSON(%q)[%s] = %s, want to contain %s", c.in, k, got[k], v)
}
}
})
}
}
func TestSessionIDFromOutput(t *testing.T) {
if s, ok := SessionIDFromOutput(`{"session_id":"abc123"}`); !ok || s != "abc123" {
t.Fatalf("got %q %v", s, ok)
}
if _, ok := SessionIDFromOutput("no session here"); ok {
t.Fatal("expected no match")
}
}