feat(#141): export FileCoveredByDocMap helper in review/docmap.go
Adds FileCoveredByDocMap(cfg *DocMapConfig, file string) bool — a thin wrapper over the existing unexported mappingMatches that lets cmd/ check per-file docmap coverage without duplicating glob logic. Also adds unit tests covering matched globs, non-matching paths, empty file, and empty config.
This commit is contained in:
@@ -66,6 +66,18 @@ func ParseDocMapConfig(localPath string) (*DocMapConfig, error) {
|
||||
return &cfg, nil
|
||||
}
|
||||
|
||||
// FileCoveredByDocMap reports whether at least one paths: glob in any mapping
|
||||
// of cfg matches the given file path. It is used by static validation tooling
|
||||
// (e.g. the validate-docmap subcommand) to check per-file docmap coverage.
|
||||
func FileCoveredByDocMap(cfg *DocMapConfig, file string) bool {
|
||||
for _, mapping := range cfg.Mappings {
|
||||
if mappingMatches(mapping.Paths, []string{file}) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// MatchDocs returns deduplicated doc paths for the given changed file paths.
|
||||
// A mapping matches if any of its path globs matches any of the changed files.
|
||||
func MatchDocs(cfg *DocMapConfig, changedFiles []string) []string {
|
||||
|
||||
@@ -436,3 +436,52 @@ func writeTempYAML(t *testing.T, content string) string {
|
||||
}
|
||||
return filepath.Clean(f.Name())
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// FileCoveredByDocMap
|
||||
// ============================================================
|
||||
|
||||
func TestFileCoveredByDocMap(t *testing.T) {
|
||||
cfg := &DocMapConfig{
|
||||
Mappings: []DocMapping{
|
||||
{
|
||||
Paths: []string{"lib/foo/**", "lib/bar/*.go"},
|
||||
Docs: []string{"docs/foo.md"},
|
||||
},
|
||||
{
|
||||
Paths: []string{"cmd/**"},
|
||||
Docs: []string{"docs/cmd.md"},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
cases := []struct {
|
||||
file string
|
||||
covered bool
|
||||
}{
|
||||
{"lib/foo/baz.ex", true},
|
||||
{"lib/foo/sub/deep.ex", true},
|
||||
{"lib/bar/util.go", true},
|
||||
{"lib/bar/sub/util.go", false}, // *.go only matches one level
|
||||
{"cmd/main.go", true},
|
||||
{"cmd/sub/main.go", true},
|
||||
{"internal/secret.go", false},
|
||||
{"", false},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.file, func(t *testing.T) {
|
||||
got := FileCoveredByDocMap(cfg, tc.file)
|
||||
if got != tc.covered {
|
||||
t.Errorf("FileCoveredByDocMap(%q) = %v, want %v", tc.file, got, tc.covered)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestFileCoveredByDocMap_EmptyConfig(t *testing.T) {
|
||||
cfg := &DocMapConfig{}
|
||||
if FileCoveredByDocMap(cfg, "lib/foo/bar.go") {
|
||||
t.Error("expected false for empty config, got true")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user