package tools import ( "context" "os" "os/exec" "path/filepath" "strings" "testing" ) // gofmt ships with the Go toolchain, so it is the one formatter guaranteed to // exist wherever these tests run. func requireGofmt(t *testing.T) { t.Helper() if _, err := exec.LookPath("gofmt"); err != nil { t.Skip("gofmt not on PATH") } } func TestFormatOnWriteDisabledByDefault(t *testing.T) { requireGofmt(t) t.Setenv("ZERO_FORMAT_ON_WRITE", "") dir := t.TempDir() ugly := "package a\n\nfunc A( ) { }\n" result := NewWriteFileTool(dir).(optionsAwareTool).RunWithOptions(context.Background(), map[string]any{ "path": "a.go", "content": ugly, }, RunOptions{}) if result.Status != StatusOK { t.Fatalf("write failed: %q", result.Output) } onDisk, err := os.ReadFile(filepath.Join(dir, "a.go")) if err != nil { t.Fatal(err) } if string(onDisk) != ugly { t.Fatalf("formatting must be off by default, got %q", onDisk) } } func TestFormatOnWriteFormatsAndKeepsTrackerConsistent(t *testing.T) { requireGofmt(t) t.Setenv("ZERO_FORMAT_ON_WRITE", "1") dir := t.TempDir() tracker := NewFileTracker() write := NewWriteFileTool(dir).(optionsAwareTool).RunWithOptions(context.Background(), map[string]any{ "path": "a.go", "content": "package a\n\nfunc A( ) { }\n", }, RunOptions{FileTracker: tracker}) if write.Status != StatusOK { t.Fatalf("write failed: %q", write.Output) } onDisk, err := os.ReadFile(filepath.Join(dir, "a.go")) if err != nil { t.Fatal(err) } if !strings.Contains(string(onDisk), "func A() {") { t.Fatalf("expected gofmt-formatted content, got %q", onDisk) } // The tracker must have been re-baselined to the POST-format content: a // follow-up edit must not trip the external-modification conflict guard. edit := NewEditFileTool(dir).(optionsAwareTool).RunWithOptions(context.Background(), map[string]any{ "path": "a.go", "old_string": "func A() {", "new_string": "func B() {", }, RunOptions{FileTracker: tracker}) if edit.Status != StatusOK { t.Fatalf("follow-up edit must not conflict after formatting: %q", edit.Output) } } func TestFormatOnWriteSkipsUnknownExtensions(t *testing.T) { t.Setenv("ZERO_FORMAT_ON_WRITE", "1") content := maybeFormatWrittenFile(context.Background(), filepath.Join(t.TempDir(), "notes.xyz"), "raw text") if content != "raw text" { t.Fatalf("unknown extension must pass through: %q", content) } }