Apply module scope to file validation checks
This commit is contained in:
125
internal/validation/scope_checks_test.go
Normal file
125
internal/validation/scope_checks_test.go
Normal file
@@ -0,0 +1,125 @@
|
||||
package validation
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestRunFileChecksUseSelectedInputsAndFullReferenceLookup(t *testing.T) {
|
||||
repository := newTreeRepository(t)
|
||||
writeTreeFile(t, repository, "go.mod", []byte("module example.com/root\n\ngo 1.25.0\nreplace example.com/rootdep => ./missing\n"))
|
||||
writeTreeFile(t, repository, "go.work", []byte("go 1.25.0\n"))
|
||||
writeTreeFile(t, repository, "outside.go", []byte("package outside\nfunc broken( ){}\n"))
|
||||
writeTreeFile(t, repository, "outside.bin", []byte(strings.Repeat("x", 160)))
|
||||
writeTreeFile(t, repository, "nested/go.mod", []byte("module example.com/nested\n\ngo 1.25.0\n"))
|
||||
writeTreeFile(t, repository, "nested/source.go", []byte("package nested\n\nfunc ready() {}\n"))
|
||||
writeTreeFile(t, repository, "nested/ignored.bin", []byte(strings.Repeat("x", 160)))
|
||||
writeTreeFile(t, repository, "nested/docs/guide.md", []byte("# Guide\n\n[details](../../sibling/docs/target.md#details)\n"))
|
||||
writeTreeFile(t, repository, "nested/child/go.mod", []byte("module example.com/nested/child\n"))
|
||||
writeTreeFile(t, repository, "nested/child/broken.go", []byte("package child\nfunc broken( ){}\n"))
|
||||
writeTreeFile(t, repository, "nested/child/go.work", []byte("go 1.25.0\n"))
|
||||
writeTreeFile(t, repository, "sibling/go.mod", []byte("module example.com/sibling\n\nreplace example.com/siblingdep => ./missing\n"))
|
||||
writeTreeFile(t, repository, "sibling/go.work", []byte("go 1.25.0\n"))
|
||||
writeTreeFile(t, repository, "sibling/broken.go", []byte("package sibling\nfunc broken( ){}\n"))
|
||||
writeTreeFile(t, repository, "sibling/outside.bin", []byte(strings.Repeat("x", 160)))
|
||||
writeTreeFile(t, repository, "sibling/docs/target.md", []byte("# Details\n\n[broken](missing.md)\n"))
|
||||
writeTreeFile(t, repository, "shared/broken.go", []byte("package shared\nfunc broken( ){}\n"))
|
||||
commit := commitCandidateTree(t, repository)
|
||||
installGoShim(t, "", false)
|
||||
moduleDir := filepath.Join(repository, "nested")
|
||||
settings := Settings{
|
||||
GoFormat: true,
|
||||
ModuleDistribution: ModuleDistributionSettings{
|
||||
WorkspaceFiles: true,
|
||||
LocalReplacements: true,
|
||||
},
|
||||
FileSize: &FileSizeSettings{LimitBytes: int64Pointer(100), Exclusions: []string{"ignored.bin"}},
|
||||
Markdown: &MarkdownSettings{EnforceCheckoutBoundary: true},
|
||||
}
|
||||
request := Request{RepositoryDir: repository, ModuleDir: moduleDir, Commit: commit, Settings: settings}
|
||||
if err := Run(context.Background(), request); err != nil {
|
||||
t.Fatalf("selected module checks = %v, want out-of-scope violations ignored and cross-module anchor resolved", err)
|
||||
}
|
||||
|
||||
request.Settings.FileSize.Exclusions = nil
|
||||
err := Run(context.Background(), request)
|
||||
assertScopedFailure(t, err, FileSize, "nested/ignored.bin")
|
||||
|
||||
writeTreeFile(t, repository, "nested/broken.go", []byte("package nested\nfunc broken( ){}\n"))
|
||||
request.Commit = commitCandidateTree(t, repository)
|
||||
request.Settings = Settings{GoFormat: true}
|
||||
assertScopedFailure(t, Run(context.Background(), request), GoFormat, "nested/broken.go")
|
||||
|
||||
writeTreeFile(t, repository, "nested/go.work", []byte("go 1.25.0\n"))
|
||||
request.Commit = commitCandidateTree(t, repository)
|
||||
request.Settings = Settings{ModuleDistribution: ModuleDistributionSettings{WorkspaceFiles: true}}
|
||||
assertScopedFailure(t, Run(context.Background(), request), WorkspaceFiles, "nested/go.work")
|
||||
|
||||
writeTreeFile(t, repository, "nested/go.mod", []byte("module example.com/nested\n\ngo 1.25.0\nreplace example.com/nesteddep => ./missing\n"))
|
||||
request.Commit = commitCandidateTree(t, repository)
|
||||
request.Settings = Settings{ModuleDistribution: ModuleDistributionSettings{LocalReplacements: true}}
|
||||
assertScopedFailure(t, Run(context.Background(), request), LocalReplacements, "nested/go.mod")
|
||||
|
||||
writeTreeFile(t, repository, "nested/docs/guide.md", []byte("# Guide\n\n[details](../../sibling/docs/target.md#details)\n\n[missing](absent.md)\n"))
|
||||
request.Commit = commitCandidateTree(t, repository)
|
||||
request.Settings = Settings{Markdown: &MarkdownSettings{}}
|
||||
assertScopedFailure(t, Run(context.Background(), request), MarkdownLinks, "nested/docs/guide.md")
|
||||
|
||||
request.Settings = Settings{GoFormat: true, SharedFiles: []string{"shared/broken.go"}}
|
||||
assertScopedFailure(t, Run(context.Background(), request), GoFormat, "shared/broken.go")
|
||||
}
|
||||
|
||||
func assertScopedFailure(t *testing.T, err error, check Check, path string) {
|
||||
t.Helper()
|
||||
failure, ok := err.(*Failure)
|
||||
if !ok || failure.Check != check {
|
||||
t.Fatalf("validation error = %v, want %s failure", err, check)
|
||||
}
|
||||
for _, finding := range failure.Findings {
|
||||
if finding.Path == path {
|
||||
return
|
||||
}
|
||||
}
|
||||
t.Fatalf("%s findings = %#v, want path %q", check, failure.Findings, path)
|
||||
}
|
||||
|
||||
func TestFileSizeExclusionsAreModuleRelative(t *testing.T) {
|
||||
repository := newTreeRepository(t)
|
||||
writeTreeFile(t, repository, "nested/go.mod", []byte("module example.com/nested\n"))
|
||||
writeTreeFile(t, repository, "nested/dist/output.bin", []byte(strings.Repeat("x", 20)))
|
||||
writeTreeFile(t, repository, "nested/dist-old/output.bin", []byte(strings.Repeat("x", 20)))
|
||||
commit := commitCandidateTree(t, repository)
|
||||
tree, err := ReadCandidateTreeForScope(context.Background(), repository, commit, TreeScope{ModuleDir: filepath.Join(repository, "nested")})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
cleanupCandidateTree(t, tree)
|
||||
settings := fileSizeSettingsForModule(&FileSizeSettings{LimitBytes: int64Pointer(10), Exclusions: []string{"./dist/"}}, tree.modulePath)
|
||||
err = checkFileSize(tree, settings)
|
||||
var failure *Failure
|
||||
if !errors.As(err, &failure) || failure.Check != FileSize || len(failure.Findings) != 1 || failure.Findings[0].Path != "nested/dist-old/output.bin" {
|
||||
t.Fatalf("module-relative file-size exclusion error = %v, want only nested/dist-old/output.bin", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSharedFileSelectionFailureCarriesCauseAndPresentation(t *testing.T) {
|
||||
repository := newTreeRepository(t)
|
||||
writeTreeFile(t, repository, "go.mod", []byte("module example.com/root\n"))
|
||||
commit := commitCandidateTree(t, repository)
|
||||
installGoShim(t, "", false)
|
||||
err := Run(context.Background(), Request{
|
||||
RepositoryDir: repository,
|
||||
Commit: commit,
|
||||
Settings: Settings{SharedFiles: []string{"missing.txt"}},
|
||||
})
|
||||
var failure *Failure
|
||||
if !errors.As(err, &failure) || failure.Check != SharedFiles || failure.Cause == nil || len(failure.Findings) != 1 || failure.Findings[0].Path != "missing.txt" {
|
||||
t.Fatalf("shared-file selection error = %#v, want path, cause, and shared-files identity", err)
|
||||
}
|
||||
if !strings.Contains(err.Error(), "shared-files") || !strings.Contains(err.Error(), "missing.txt") {
|
||||
t.Fatalf("shared-file error text = %q, want existing check/path presentation", err)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user