package exec import ( "encoding/json" "strings" "testing" ) // TestProcessEventLegacyOmitempty:零值新字段不出现在 JSON 中,旧消费方 // 忽略未知字段时看到的遗留载荷与仅填 Type/Tool/Text/Detail 一致。 func TestProcessEventLegacyOmitempty(t *testing.T) { legacy := ProcessEvent{Type: "tool_execution_end", Tool: "echo", Text: "ran", Detail: "{}"} withZeros := ProcessEvent{ Type: "tool_execution_end", Tool: "echo", Text: "ran", Detail: "{}", CallID: "", Status: "", ErrorReason: "", } a, err := json.Marshal(legacy) if err != nil { t.Fatal(err) } b, err := json.Marshal(withZeros) if err != nil { t.Fatal(err) } if string(a) != string(b) { t.Fatalf("zero new fields changed JSON:\n legacy=%s\n zeros=%s", a, b) } if strings.Contains(string(a), "call_id") || strings.Contains(string(a), "status") || strings.Contains(string(a), "error_reason") { t.Fatalf("omitempty leaked zero fields: %s", a) } populated := ProcessEvent{ Type: "tool_execution_end", Tool: "echo", Text: "boom", CallID: "c1", Status: "error", ErrorReason: "boom", } raw, err := json.Marshal(populated) if err != nil { t.Fatal(err) } s := string(raw) for _, want := range []string{`"call_id":"c1"`, `"status":"error"`, `"error_reason":"boom"`} { if !strings.Contains(s, want) { t.Fatalf("missing %s in %s", want, s) } } }