package main import ( "testing" ) func TestCheckErrLeak_HttpErrorWithErrError(t *testing.T) { dir := t.TempDir() writeFile(t, dir, "handler.go", `package handler import "net/http" func handle(w http.ResponseWriter, r *http.Request) { err := doSomething() if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) } } `) vs := checkErrLeak(dir) if len(vs) == 0 { t.Fatal("expected errleak violation for http.Error(w, err.Error(), ...)") } found := false for _, v := range vs { if v.file == "handler.go" { found = true } } if !found { t.Fatalf("expected violation in handler.go, got %#v", vs) } } func TestCheckErrLeak_FmtFprintfWithErrError(t *testing.T) { dir := t.TempDir() writeFile(t, dir, "handler.go", `package handler import "fmt" func handle(w interface{}, err error) { fmt.Fprintf(w, "error: %s", err.Error()) } `) vs := checkErrLeak(dir) if len(vs) == 0 { t.Fatal("expected errleak violation for fmt.Fprintf(w, ..., err.Error())") } } func TestCheckErrLeak_FmtFprintlnWithErrError(t *testing.T) { dir := t.TempDir() writeFile(t, dir, "handler.go", `package handler import "fmt" func handle(w interface{}, err error) { fmt.Fprintln(w, err.Error()) } `) vs := checkErrLeak(dir) if len(vs) == 0 { t.Fatal("expected errleak violation for fmt.Fprintln(w, err.Error())") } } func TestCheckErrLeak_WriteWithErrError(t *testing.T) { dir := t.TempDir() writeFile(t, dir, "handler.go", `package handler func handle(w interface{ Write([]byte) (int, error) }, err error) { w.Write([]byte(err.Error())) } `) vs := checkErrLeak(dir) if len(vs) == 0 { t.Fatal("expected errleak violation for w.Write([]byte(err.Error()))") } } func TestCheckErrLeak_SafeErrorHelpers_Clean(t *testing.T) { // Using writeInternalServerError helper — should NOT flag dir := t.TempDir() writeFile(t, dir, "handler.go", `package handler func handle(w http.ResponseWriter, r *http.Request) { err := doSomething() if err != nil { writeInternalServerError(w, err, "handle request") } } `) vs := checkErrLeak(dir) if len(vs) != 0 { t.Fatalf("expected no violations for safe helper usage, got %d: %#v", len(vs), vs) } } func TestCheckErrLeak_HttpErrorWithLiteralMessage_Clean(t *testing.T) { // http.Error with a literal string — NOT a leak dir := t.TempDir() writeFile(t, dir, "handler.go", `package handler import "net/http" func handle(w http.ResponseWriter, r *http.Request) { http.Error(w, "internal server error", http.StatusInternalServerError) } `) vs := checkErrLeak(dir) if len(vs) != 0 { t.Fatalf("expected no violations for http.Error with literal message, got %d: %#v", len(vs), vs) } } func TestCheckErrLeak_TestFile_Skipped(t *testing.T) { dir := t.TempDir() writeFile(t, dir, "handler_test.go", `package handler import "net/http" func TestHandle(t *testing.T) { http.Error(w, err.Error(), 500) } `) vs := checkErrLeak(dir) if len(vs) != 0 { t.Fatalf("expected test files to be skipped, got %d violations", len(vs)) } } func TestCheckErrLeak_RelativeFilePath(t *testing.T) { dir := t.TempDir() writeFile(t, dir, "leak.go", `package handler import "net/http" func f(w http.ResponseWriter, err error) { http.Error(w, err.Error(), 500) } `) vs := checkErrLeak(dir) if len(vs) == 0 { t.Fatal("expected violation") } if vs[0].file != "leak.go" { t.Fatalf("expected relative file 'leak.go', got %q", vs[0].file) } } func TestCheckErrLeak_NonGoFile_Skipped(t *testing.T) { dir := t.TempDir() // Write something that looks like an errleak pattern but in a .ts file writeFile(t, dir, "handler.ts", `// err.Error() leaks http.Error(w, err.Error(), 500) `) vs := checkErrLeak(dir) if len(vs) != 0 { t.Fatalf("expected no violations for non-.go file, got %d", len(vs)) } } func TestCheckErrLeak_SnippetContainsPattern(t *testing.T) { dir := t.TempDir() writeFile(t, dir, "handler.go", `package handler import "net/http" func handle(w http.ResponseWriter, err error) { http.Error(w, err.Error(), http.StatusBadRequest) } `) vs := checkErrLeak(dir) if len(vs) == 0 { t.Fatal("expected violation") } // snippet should mention the pattern name if vs[0].snippet == "" { t.Fatal("expected non-empty snippet") } }