107 lines
2.5 KiB
Go
107 lines
2.5 KiB
Go
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)
|
||
}
|
||
}
|
||
})
|
||
}
|
||
}
|