Files
fejkdata/imports_test.go
T

91 lines
2.4 KiB
Go

package fejkdata
import (
"errors"
"go/build"
"io/fs"
"os"
"path/filepath"
"slices"
"strings"
"testing"
)
// TestPackageImports holds each package in the module to the module packages it may import.
func TestPackageImports(t *testing.T) {
mod, err := os.ReadFile("go.mod")
if err != nil {
t.Fatal(err)
}
module := ""
for _, line := range strings.Split(string(mod), "\n") {
if f := strings.Fields(line); len(f) > 1 && f[0] == "module" {
module = strings.Trim(f[1], `"`)
break
}
}
if module == "" {
t.Fatal("go.mod names no module")
}
checked := 0
allowed := map[string][]string{
".": {"internal/builtinfunc", "internal/datafiles", "internal/datatype", "internal/drawstate", "internal/grammar", "internal/proven"},
"cmd/fejkdata": {"."},
"internal/builtinfunc": {"internal/datatype", "internal/drawstate", "internal/grammar", "internal/proven"},
"internal/datafiles": {"internal/grammar"},
"internal/datatype": nil,
"internal/drawstate": nil,
"internal/grammar": nil,
"internal/proven": {"internal/datatype", "internal/grammar"},
}
seen := map[string]bool{}
err = filepath.WalkDir(".", func(dir string, d fs.DirEntry, err error) error {
if err != nil || !d.IsDir() {
return err
}
if dir != "." && (strings.HasPrefix(d.Name(), ".") || d.Name() == "testdata") {
return filepath.SkipDir
}
pkg, err := build.ImportDir(dir, 0)
var noGo *build.NoGoError
if errors.As(err, &noGo) {
return nil
}
if err != nil {
return err
}
dir = filepath.ToSlash(dir)
seen[dir] = true
may, listed := allowed[dir]
if !listed {
t.Errorf("package %s is not listed: add the module packages it may import", dir)
return nil
}
for _, imp := range slices.Concat(pkg.Imports, pkg.TestImports, pkg.XTestImports) {
if imp != module && !strings.HasPrefix(imp, module+"/") {
continue
}
checked++
rel := strings.TrimPrefix(strings.TrimPrefix(imp, module), "/")
if rel == "" {
rel = "."
}
if rel != dir && !slices.Contains(may, rel) {
t.Errorf("package %s imports %s, which its list does not allow", dir, rel)
}
}
return nil
})
if err != nil {
t.Fatal(err)
}
if checked == 0 {
t.Fatalf("no package imports a package of module %s, which go.mod names", module)
}
for dir := range allowed {
if !seen[dir] {
t.Errorf("listed package %s does not exist", dir)
}
}
}