TestGenerateMergesSamePathFiles verifies that when two generators emit content targeting the same output path, Generate merges the sections into a single file rather than overwriting earlier content. This is a regression test for an issue where only a later section (e.g., a union value method) remai
(t *testing.T)
| 18 | // an issue where only a later section (e.g., a union value method) remained and |
| 19 | // the earlier struct definition was lost. |
| 20 | func TestGenerateMergesSamePathFiles(t *testing.T) { |
| 21 | t.Cleanup(func() { Generators = generators }) |
| 22 | |
| 23 | // Fake generators emit two files with identical Path, one containing a |
| 24 | // type definition and the other containing a method. Without merging, the |
| 25 | // second write would overwrite the first. |
| 26 | Generators = func(cmd string) ([]Genfunc, error) { |
| 27 | return []Genfunc{ |
| 28 | func(genpkg string, roots []eval.Root) ([]*codegen.File, error) { |
| 29 | f := &codegen.File{Path: filepath.Join(codegen.Gendir, "types", "merge_test.go")} |
| 30 | f.SectionTemplates = []*codegen.SectionTemplate{ |
| 31 | codegen.Header("User types", "types", nil), |
| 32 | { // struct definition |
| 33 | Name: "struct-type", |
| 34 | Source: "type MergeTest struct{}\n", |
| 35 | }, |
| 36 | } |
| 37 | return []*codegen.File{f}, nil |
| 38 | }, |
| 39 | func(genpkg string, roots []eval.Root) ([]*codegen.File, error) { |
| 40 | f := &codegen.File{Path: filepath.Join(codegen.Gendir, "types", "merge_test.go")} |
| 41 | f.SectionTemplates = []*codegen.SectionTemplate{ |
| 42 | codegen.Header("User types", "types", nil), |
| 43 | { // method on MergeTest |
| 44 | Name: "method", |
| 45 | Source: "func (*MergeTest) Marker() {}\n", |
| 46 | }, |
| 47 | } |
| 48 | return []*codegen.File{f}, nil |
| 49 | }, |
| 50 | }, nil |
| 51 | } |
| 52 | |
| 53 | dir := t.TempDir() |
| 54 | _, err := Generate(dir, "gen", false) |
| 55 | if err != nil { |
| 56 | t.Fatalf("Generate failed: %v", err) |
| 57 | } |
| 58 | // Read the merged output directly from the temp dir regardless of how |
| 59 | // outputs are relativized by Generate. |
| 60 | outpath := filepath.Join(dir, codegen.Gendir, "types", "merge_test.go") |
| 61 | bs, err := os.ReadFile(outpath) |
| 62 | if err != nil { |
| 63 | t.Fatalf("failed reading merged file: %v", err) |
| 64 | } |
| 65 | content := string(bs) |
| 66 | if !strings.Contains(content, "type MergeTest struct{}") { |
| 67 | t.Fatalf("merged file missing struct definition:\n%s", content) |
| 68 | } |
| 69 | if !strings.Contains(content, "func (*MergeTest) Marker() {}") { |
| 70 | t.Fatalf("merged file missing method definition:\n%s", content) |
| 71 | } |
| 72 | } |
| 73 | |
| 74 | // TestGenerateParallelManyFiles verifies that parallel file writing correctly |
| 75 | // handles multiple files (more than runtime.NumCPU()) to exercise the worker |