// Copyright 2026 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package gentools import ( "bytes" "os" "path/filepath" "strings" "testing" ) func TestGoFileFormatting(t *testing.T) { t.Parallel() var outBuf bytes.Buffer var files Files files.Options = &Options{ Txtar: true, Output: &outBuf, } buf := files.NewGoFile("test.go") buf.WriteString("package test\nfunc Foo() int { return 42 }\n") err := files.Flush() if err != nil { t.Fatalf("Flush failed: %v", err) } outStr := outBuf.String() expected := "-- src/test.go --\npackage test\n\nfunc Foo() int { return 42 }\n" if outStr != expected { t.Errorf("got txtar output:\n%q\nwant:\n%q", outStr, expected) } } func TestFormattingError(t *testing.T) { t.Parallel() var errBuf bytes.Buffer var files Files files.Options = &Options{ ErrOutput: &errBuf, } buf := files.NewGoFile("bad.go") buf.WriteString("package test\n\tfunc Foo( {\n") // invalid syntax with tab indentation err := files.Flush() if err == nil { t.Fatalf("expected formatting error, got nil") } if !strings.Contains(err.Error(), "error formatting bad.go") { t.Errorf("unexpected error message: %v", err) } const expectedErrOutput = "package test\n\tfunc Foo( {\n\t ^\n2:12: expected ')', found '{'\n" if errBuf.String() != expectedErrOutput { t.Errorf("got error output:\n%q\nwant:\n%q", errBuf.String(), expectedErrOutput) } } func TestWriteMode(t *testing.T) { t.Parallel() tmpDir := t.TempDir() var files Files files.Options = &Options{ GOROOT: tmpDir, Write: true, } gobuf := files.NewGoFile("pkg/a.go") gobuf.WriteString("package pkg\nconst X = 1\n") const expectedRawContent = "raw content\n" rawbuf := files.NewRawFile("pkg/a.txt") rawbuf.WriteString(expectedRawContent) if err := files.Flush(); err != nil { t.Fatalf("Flush failed: %v", err) } aGo, err := os.ReadFile(filepath.Join(tmpDir, "src", "pkg", "a.go")) if err != nil { t.Fatalf("reading a.go: %v", err) } if string(aGo) != "package pkg\n\nconst X = 1\n" { t.Errorf("unexpected a.go content: %q", string(aGo)) } aTxt, err := os.ReadFile(filepath.Join(tmpDir, "src", "pkg", "a.txt")) if err != nil { t.Fatalf("reading a.txt: %v", err) } if string(aTxt) != expectedRawContent { t.Errorf("unexpected a.txt content: %q", string(aTxt)) } } func TestWriteAsideMode(t *testing.T) { t.Parallel() tmpDir := t.TempDir() tmpDir2 := t.TempDir() var files Files files.Options = &Options{ GOROOT: tmpDir, outDir: tmpDir2, Write: true, } gobuf := files.NewGoFile("pkg/a.go") gobuf.WriteString("package pkg\nconst X = 1\n") const expectedRawContent = "raw content\n" rawbuf := files.NewRawFile("pkg/a.txt") rawbuf.WriteString(expectedRawContent) if err := files.Flush(); err != nil { t.Fatalf("Flush failed: %v", err) } aGo, err := os.ReadFile(filepath.Join(tmpDir2, "src", "pkg", "a.go")) if err != nil { t.Fatalf("reading a.go: %v", err) } if string(aGo) != "package pkg\n\nconst X = 1\n" { t.Errorf("unexpected a.go content: %q", string(aGo)) } aTxt, err := os.ReadFile(filepath.Join(tmpDir2, "src", "pkg", "a.txt")) if err != nil { t.Fatalf("reading a.txt: %v", err) } if string(aTxt) != expectedRawContent { t.Errorf("unexpected a.txt content: %q", string(aTxt)) } } func TestDiffMode(t *testing.T) { t.Parallel() tmpDir := t.TempDir() targetFile := filepath.Join(tmpDir, "src", "pkg", "a.go") os.MkdirAll(filepath.Dir(targetFile), 0755) os.WriteFile(targetFile, []byte("package pkg\n\nconst X = 1\n"), 0644) // Test matching content var files1 Files files1.Options = &Options{ GOROOT: tmpDir, Diff: true, } buf1 := files1.NewGoFile("pkg/a.go") buf1.WriteString("package pkg\nconst X = 1\n") if err := files1.Flush(); err != nil { t.Errorf("expected no diff error, got: %v", err) } // Test non-matching content var outBuf bytes.Buffer var files2 Files files2.Options = &Options{ GOROOT: tmpDir, Diff: true, Output: &outBuf, } buf2 := files2.NewGoFile("pkg/a.go") buf2.WriteString("package pkg\nconst X = 2\n") err := files2.Flush() if err == nil { t.Errorf("expected diff error, got nil") } if !strings.Contains(outBuf.String(), "-const X = 1") || !strings.Contains(outBuf.String(), "+const X = 2") { t.Errorf("unexpected diff output:\n%s", outBuf.String()) } }