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
|
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.
|
// 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.
|
// A mapping matches if any of its path globs matches any of the changed files.
|
||||||
func MatchDocs(cfg *DocMapConfig, changedFiles []string) []string {
|
func MatchDocs(cfg *DocMapConfig, changedFiles []string) []string {
|
||||||
|
|||||||
@@ -436,3 +436,52 @@ func writeTempYAML(t *testing.T, content string) string {
|
|||||||
}
|
}
|
||||||
return filepath.Clean(f.Name())
|
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