Files
zzet--gortex/cmd/gortex/cli_daemon_test.go
T
wehub-resource-sync a06f331eb8
CI / benchmark (push) Has been skipped
install-script / posix-syntax (push) Successful in 6m1s
CI / build-onnx (push) Failing after 6m43s
init-smoke / dry-run (push) Failing after 15m57s
security / govulncheck (push) Has been cancelled
security / trivy-fs (push) Has been cancelled
CI / test (1.26, ubuntu-latest) (push) Has been cancelled
Scorecard supply-chain security / Scorecard analysis (push) Has been cancelled
CI / test (1.26, macos-latest) (push) Has been cancelled
CI / build-windows (push) Has been cancelled
CI / lint (push) Has been cancelled
install-script / powershell-syntax (push) Has been cancelled
install-script / install (macos-14) (push) Has been cancelled
install-script / install (ubuntu-latest) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:33:42 +08:00

103 lines
3.1 KiB
Go

package main
import (
"encoding/json"
"errors"
"testing"
)
// TestBuildToolCallFrame_PinsJSON asserts every relayed tools/call forces
// format:"json" so the per-tool decode is stable regardless of the
// daemon's client-based wire-format auto-selection.
func TestBuildToolCallFrame_PinsJSON(t *testing.T) {
frame, err := buildToolCallFrame(1, "search_symbols", map[string]any{"query": "Foo"})
if err != nil {
t.Fatal(err)
}
var m struct {
Method string `json:"method"`
Params struct {
Name string `json:"name"`
Arguments map[string]any `json:"arguments"`
} `json:"params"`
}
if err := json.Unmarshal(frame, &m); err != nil {
t.Fatal(err)
}
if m.Method != "tools/call" || m.Params.Name != "search_symbols" {
t.Fatalf("unexpected frame: %s", frame)
}
if m.Params.Arguments["format"] != "json" {
t.Fatalf("format must be pinned to json, got %v", m.Params.Arguments["format"])
}
if m.Params.Arguments["query"] != "Foo" {
t.Fatalf("caller args must be preserved, got %v", m.Params.Arguments)
}
}
// TestBuildToolCallFrame_NilArgs asserts a nil args map still pins json.
func TestBuildToolCallFrame_NilArgs(t *testing.T) {
frame, err := buildToolCallFrame(2, "graph_stats", nil)
if err != nil {
t.Fatal(err)
}
if !contains(frame, `"format":"json"`) {
t.Fatalf("nil args must still pin json: %s", frame)
}
}
func contains(b []byte, sub string) bool {
return len(b) >= len(sub) && (string(b) == sub || indexOf(string(b), sub) >= 0)
}
func indexOf(s, sub string) int {
for i := 0; i+len(sub) <= len(s); i++ {
if s[i:i+len(sub)] == sub {
return i
}
}
return -1
}
// TestExtractToolResult_RepoNotTracked maps the daemon's typed refusal to
// the sentinel so the CLI falls back instead of erroring.
func TestExtractToolResult_RepoNotTracked(t *testing.T) {
resp := []byte(`{"jsonrpc":"2.0","id":1,"error":{"code":-32000,"message":"repository not tracked","data":{"error_code":"repo_not_tracked"}}}`)
_, err := extractToolResult(resp)
if !errors.Is(err, ErrRepoNotTracked) {
t.Fatalf("want ErrRepoNotTracked, got %v", err)
}
}
// TestExtractToolResult_RealErrorSurfaced asserts a genuine tool error is
// surfaced verbatim (not swallowed as "not tracked").
func TestExtractToolResult_RealErrorSurfaced(t *testing.T) {
resp := []byte(`{"jsonrpc":"2.0","id":1,"error":{"code":-32602,"message":"bad symbol id"}}`)
_, err := extractToolResult(resp)
if err == nil || errors.Is(err, ErrRepoNotTracked) {
t.Fatalf("a real error must surface, got %v", err)
}
if err.Error() != "bad symbol id" {
t.Fatalf("error message should be verbatim, got %q", err.Error())
}
}
// TestExtractToolResult_Success returns the tool JSON payload from the
// result content block.
func TestExtractToolResult_Success(t *testing.T) {
resp := []byte(`{"jsonrpc":"2.0","id":1,"result":{"content":[{"type":"text","text":"{\"total\":3}"}]}}`)
out, err := extractToolResult(resp)
if err != nil {
t.Fatal(err)
}
var payload struct {
Total int `json:"total"`
}
if err := json.Unmarshal(out, &payload); err != nil {
t.Fatalf("payload should be the tool json: %v (%s)", err, out)
}
if payload.Total != 3 {
t.Fatalf("want total 3, got %d", payload.Total)
}
}