// Black-box tests for the Go bundle coverage-summary script. // // The script ships into a project's .claude/scripts/ and runs via `go run`, so // these tests exercise the real CLI rather than importing it: build a throwaway // module (go.mod + source files + a cover.out profile), run the script against // it, and assert on stdout. Keeping the test in its own module here means the // shipped script dir stays test-free. // // Normal / Boundary / Error coverage at the behavior level: missing-file // detection, the file-weighted number, all-tracked, ignoring _test.go, and a // missing-report error. package gocovtest import ( "os" "os/exec" "path/filepath" "runtime" "strings" "testing" ) // scriptPath resolves coverage-summary.go relative to this test file. func scriptPath(t *testing.T) string { t.Helper() _, thisFile, _, ok := runtime.Caller(0) if !ok { t.Fatal("cannot locate test file") } p := filepath.Join(filepath.Dir(thisFile), "..", "claude", "scripts", "coverage-summary.go") abs, err := filepath.Abs(p) if err != nil { t.Fatal(err) } return abs } // fixture writes a go.mod, the given source files, and a cover.out under a temp // module root. sources maps relpath -> contents; profile is the raw cover.out. func fixture(t *testing.T, sources map[string]string, profile string) string { t.Helper() root := t.TempDir() write := func(rel, body string) { full := filepath.Join(root, rel) if err := os.MkdirAll(filepath.Dir(full), 0o755); err != nil { t.Fatal(err) } if err := os.WriteFile(full, []byte(body), 0o644); err != nil { t.Fatal(err) } } write("go.mod", "module example.com/m\n\ngo 1.26\n") for rel, body := range sources { write(rel, body) } write("cover.out", profile) return root } // run executes the script against a fixture root, returning combined output + err. func run(t *testing.T, root, sourceDir string) (string, error) { t.Helper() cmd := exec.Command("go", "run", scriptPath(t), filepath.Join(root, "cover.out"), filepath.Join(root, sourceDir), root) out, err := cmd.CombinedOutput() return string(out), err } func TestMissingFileSurfacedAndCountedZero(t *testing.T) { root := fixture(t, map[string]string{ "calc/calc.go": "package calc\n\nfunc Add(a, b int) int { return a + b }\n", "calc/untested.go": "package calc\n\nfunc Mul(a, b int) int { return a * b }\n", }, // calc.go fully covered (2/2 stmts); untested.go absent from the profile. "mode: set\nexample.com/m/calc/calc.go:3.40,3.56 2 1\n", ) out, err := run(t, root, ".") if err != nil { t.Fatalf("script failed: %v\n%s", err, out) } if !strings.Contains(out, "calc/untested.go") { t.Errorf("missing file not surfaced:\n%s", out) } if !strings.Contains(out, "0%") { t.Errorf("missing-as-0%% note absent:\n%s", out) } // calc.go = 100%, untested.go missing = 0% -> 50.0% if !strings.Contains(out, "50.0%") { t.Errorf("expected project number 50.0%%:\n%s", out) } } func TestAllTrackedNoMissing(t *testing.T) { root := fixture(t, map[string]string{"calc/calc.go": "package calc\n\nfunc Add(a, b int) int { return a + b }\n"}, "mode: set\nexample.com/m/calc/calc.go:3.40,3.56 2 1\n", ) out, err := run(t, root, ".") if err != nil { t.Fatalf("script failed: %v\n%s", err, out) } if !strings.Contains(out, "Not in coverage report: 0 file") { t.Errorf("expected zero missing files:\n%s", out) } if !strings.Contains(out, "100.0%") { t.Errorf("expected 100.0%% project number:\n%s", out) } } func TestTestFilesAreNotCountedAsSource(t *testing.T) { root := fixture(t, map[string]string{ "calc/calc.go": "package calc\n\nfunc Add(a, b int) int { return a + b }\n", "calc/calc_test.go": "package calc\n\nimport \"testing\"\n\nfunc TestX(t *testing.T) {}\n", }, "mode: set\nexample.com/m/calc/calc.go:3.40,3.56 2 1\n", ) out, err := run(t, root, ".") if err != nil { t.Fatalf("script failed: %v\n%s", err, out) } if strings.Contains(out, "calc_test.go") { t.Errorf("_test.go wrongly counted as source:\n%s", out) } if !strings.Contains(out, "100.0%") { t.Errorf("expected 100.0%% (test file excluded):\n%s", out) } } func TestMissingReportErrors(t *testing.T) { root := fixture(t, map[string]string{"calc/calc.go": "package calc\n"}, "mode: set\n", ) cmd := exec.Command("go", "run", scriptPath(t), filepath.Join(root, "does-not-exist.out"), root, root) out, err := cmd.CombinedOutput() if err == nil { t.Errorf("expected non-zero exit for missing report; output:\n%s", out) } }