Files
ReleaseKit/internal/validation/scope_checks_test.go

126 lines
6.5 KiB
Go

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)
}
}