package codegen import ( "testing" "github.com/zzet/gortex/internal/graph" ) func TestScan_Variants(t *testing.T) { cases := []struct { name string src string generated bool tool string source string }{ { name: "protoc-go", src: "// Code generated by protoc-gen-go. DO NOT EDIT.\n// source: github.com/foo/bar/baz.proto\n\npackage bar\n", generated: true, tool: "protoc-gen-go", source: "github.com/foo/bar/baz.proto", }, { name: "stringer", src: "// Code generated by \"stringer -type=Color\". DO NOT EDIT.\n\npackage colors\n", generated: true, tool: `"stringer -type=Color"`, }, { name: "at-generated", src: "// @generated by graphql-codegen\n\nexport const x = 1;\n", generated: true, tool: "graphql-codegen", }, { name: "at-generated-bare", src: "// @generated\nimport foo\n", generated: true, }, { name: "no-marker", src: "package main\n\nfunc main() {}\n", generated: false, }, { name: "below-window", src: "// 1\n// 2\n// 3\n// 4\n// 5\n// 6\n// 7\n// 8\n// 9\n// 10\n// 11\n// Code generated by foo. DO NOT EDIT.\n", generated: false, }, { name: "case-sensitive", src: "// code generated automatically\n", generated: false, }, { name: "marker-in-prose-not-flagged", src: "// Recognises the conventional Go \"Code generated by ...\" header in prose docs of this package.\n", generated: false, }, { name: "tree-sitter-inline-marker", src: "/* Automatically @generated by tree-sitter */\n\n#include\n", // tree-sitter wraps the marker in a /* */ block with a // short "Automatically" prefix; the maxMarkerOffset // threshold accepts it. generated: true, tool: "tree-sitter", }, } for _, tc := range cases { t.Run(tc.name, func(t *testing.T) { got := Scan([]byte(tc.src)) if got.Generated != tc.generated { t.Fatalf("Generated = %v, want %v", got.Generated, tc.generated) } if got.Tool != tc.tool { t.Errorf("Tool = %q, want %q", got.Tool, tc.tool) } if got.Source != tc.source { t.Errorf("Source = %q, want %q", got.Source, tc.source) } }) } } func TestBuildGraphArtifacts(t *testing.T) { t.Run("with source path", func(t *testing.T) { edges := BuildGraphArtifacts("pkg/foo.pb.go", Marker{ Generated: true, Tool: "protoc-gen-go", Source: "github.com/x/y/foo.proto", }) if len(edges) != 1 { t.Fatalf("expected 1 edge, got %d", len(edges)) } e := edges[0] if e.Kind != graph.EdgeGeneratedBy { t.Errorf("edge kind = %q", e.Kind) } if e.From != "pkg/foo.pb.go" { t.Errorf("from = %q", e.From) } if e.To != "external::generator-source:github.com/x/y/foo.proto" { t.Errorf("to = %q", e.To) } }) t.Run("tool only", func(t *testing.T) { edges := BuildGraphArtifacts("pkg/foo.go", Marker{ Generated: true, Tool: "stringer", }) if edges[0].To != "external::generator-tool:stringer" { t.Errorf("to = %q", edges[0].To) } }) t.Run("bare @generated", func(t *testing.T) { edges := BuildGraphArtifacts("pkg/foo.ts", Marker{Generated: true}) if edges[0].To != "external::generator-unknown" { t.Errorf("to = %q", edges[0].To) } }) t.Run("not generated", func(t *testing.T) { edges := BuildGraphArtifacts("pkg/foo.go", Marker{}) if len(edges) != 0 { t.Errorf("expected nil, got %+v", edges) } }) } func TestMarkFileNode(t *testing.T) { meta := map[string]any{} MarkFileNode(meta, Marker{ Generated: true, Tool: "stringer", Source: "color.go", }) if v, _ := meta["generated"].(bool); !v { t.Errorf("generated meta missing") } if meta["generated_by"] != "stringer" { t.Errorf("generated_by = %v", meta["generated_by"]) } if meta["generated_from"] != "color.go" { t.Errorf("generated_from = %v", meta["generated_from"]) } } func TestMarkFileNode_NoOpWhenNotGenerated(t *testing.T) { meta := map[string]any{} MarkFileNode(meta, Marker{}) if len(meta) != 0 { t.Errorf("meta should stay empty, got %+v", meta) } }