package contracts import "testing" // TestExtractTSShape_NestedAnonymousObject is the regression for the // React duplicate-key warning that the dashboard fired on // /v1/dashboard. The web `DashboardSnapshot` type literal contains // an inline anonymous `stats: { ... }` whose fields collide with // the outer ones (`repos`, `caveats`). The pre-fix extractor walked // every line in the body, so the inner Stats fields were emitted // alongside the outer arrays — producing duplicate `repos` / // `caveats` rows in the shape and two React children with the same // key in the rendered table. // // Fix: track brace depth and only emit fields at depth 0 (direct // members of the outer `{`). Inline-object fields drop their nested // members; the parent field itself still appears with type `{...}` // so the structure isn't lost. func TestExtractTSShape_NestedAnonymousObject(t *testing.T) { src := []byte(`export type DashboardSnapshot = { stats: { total_nodes: number total_edges: number repos: number caveats: number version: string } kinds: KindCount[] languages: LanguageCount[] repos: Repo[] activity: Activity[] caveats: Caveat[] processes: Process[] } `) shape := extractTSShape(src, 1, 15) if shape == nil { t.Fatal("expected non-nil shape") } seen := map[string]int{} for _, f := range shape.Fields { seen[f.Name]++ } for name, count := range seen { if count > 1 { t.Errorf("field %q appears %d times — duplicate names hoist nested object into parent", name, count) } } wantTopLevel := []string{"stats", "kinds", "languages", "repos", "activity", "caveats", "processes"} for _, name := range wantTopLevel { if seen[name] != 1 { t.Errorf("top-level field %q expected once, got %d", name, seen[name]) } } // total_nodes is unique to the inner Stats object — its presence // proves the bug recurred. if seen["total_nodes"] > 0 { t.Errorf("inner Stats.total_nodes leaked into outer shape (hoisting regression)") } // The parent `stats` field MUST be recorded with the normalised // inline-object label rather than a stray opening brace, so the // dashboard renders something readable. for _, f := range shape.Fields { if f.Name == "stats" { if f.Type != "{...}" { t.Errorf("stats type: want %q, got %q", "{...}", f.Type) } } } } // TestExtractTSShape_FlatInterfaceUnchanged guards against the // brace-depth tracking accidentally suppressing fields in a normal // flat interface — the hot path that has to keep working. func TestExtractTSShape_FlatInterfaceUnchanged(t *testing.T) { src := []byte(`export interface User { id: string name: string email?: string } `) shape := extractTSShape(src, 1, 5) if shape == nil { t.Fatal("expected non-nil shape") } if len(shape.Fields) != 3 { t.Fatalf("want 3 fields, got %d", len(shape.Fields)) } want := []string{"id", "name", "email"} for i, w := range want { if shape.Fields[i].Name != w { t.Errorf("field %d: want %q, got %q", i, w, shape.Fields[i].Name) } } if shape.Fields[2].Required { t.Errorf("email should be optional (?:)") } }