// resultshape_test.go:/result 线形状 golden 测试(ITER-1 F1,双端同源)。 // // scheduler(internal/scheduler)与 gateway(internal/gateway)的单测各自 import // 本包常量断言自己的线形状 = 本文件锁定的形状——任何一端漂移立刻双红。 package contract import ( "encoding/json" "testing" ) // TestResultShapeGoldenDone 终态形状:顶层仅 request_id/status/envelope(±position), // envelope 为统一信封嵌套(含 ok/kind/usage/provenance/error 顶层键)。 func TestResultShapeDone(t *testing.T) { var m map[string]any if err := json.Unmarshal([]byte(ResultShapeDone), &m); err != nil { t.Fatalf("ResultShapeDone 非法 JSON: %v", err) } if m["status"] != "done" { t.Errorf("status = %v, 期望 done", m["status"]) } env, ok := m["envelope"].(map[string]any) if !ok { t.Fatalf("envelope 非嵌套对象: %T", m["envelope"]) } for _, k := range []string{"ok", "kind", "request_id", "took_ms", "usage", "provenance", "error"} { if _, has := env[k]; !has { t.Errorf("envelope 缺统一信封顶层键 %q", k) } } if _, has := m["error"]; has { t.Errorf("终态形状顶层不应有 error 键(错误在 envelope 内)") } } // TestResultShapeAccepted 非终态形状:request_id/status 必在;position 可选(引导字段, // 生产实现可省略);无 envelope。 func TestResultShapeAccepted(t *testing.T) { var m map[string]any if err := json.Unmarshal([]byte(ResultShapeAccepted), &m); err != nil { t.Fatalf("ResultShapeAccepted 非法 JSON: %v", err) } if m["status"] != "queued" { t.Errorf("status = %v, 期望 queued", m["status"]) } if _, has := m["request_id"]; !has { t.Errorf("非终态形状缺 request_id") } if _, has := m["envelope"]; has { t.Errorf("非终态形状不应有 envelope") } } // TestResultShapeFailed 失败终态与 done 同构(200 + envelope 嵌套)。 func TestResultShapeFailed(t *testing.T) { var m map[string]any if err := json.Unmarshal([]byte(ResultShapeFailed), &m); err != nil { t.Fatalf("ResultShapeFailed 非法 JSON: %v", err) } if m["status"] != "failed" { t.Errorf("status = %v, 期望 failed", m["status"]) } env, ok := m["envelope"].(map[string]any) if !ok { t.Fatalf("envelope 非嵌套对象") } if env["ok"] != false { t.Errorf("失败信封 ok 应为 false") } if _, has := env["error"]; !has { t.Errorf("失败信封缺 error") } } // TestResultStatuses 覆盖 status 合法值集合。 func TestResultStatuses(t *testing.T) { for _, s := range []string{"queued", "running", "done", "failed", "dead"} { if !ResultStatuses[s] { t.Errorf("ResultStatuses 缺 %q", s) } } if len(ResultStatuses) != 5 { t.Errorf("ResultStatuses 应恰 5 项,实得 %d", len(ResultStatuses)) } }