Test internal/drawstate and the module packages each package may import

This commit is contained in:
2026-10-05 11:43:04 +02:00
committed by Lillem4n
parent b1d26cd999
commit 4a680f03b3
6 changed files with 114 additions and 10 deletions
+1 -1
View File
@@ -105,7 +105,7 @@ func TestBuiltinChecksums(t *testing.T) {
// TestBuiltinSeqPerGenerator pins seq's contract: a counter from 1, advancing on
// each call, named counters independent, and the whole thing scoped to one
// generatorState so a fresh Generator restarts at 1.
// draw state so a fresh Generator restarts at 1.
func TestBuiltinSeqPerGenerator(t *testing.T) {
f := engine(1)
for i := 1; i <= 5; i++ {
+4 -6
View File
@@ -7,6 +7,8 @@ import (
"strings"
"testing"
"testing/fstest"
"github.com/larvit/fejkdata/internal/drawstate"
)
// newGenerator creates a generator over a single data directory, failing on
@@ -96,11 +98,7 @@ func fakeTemplate(t *testing.T, f *Generator, s string) string {
// engine builds a seeded generator with no loaded categories, for rendering tests.
func engine(seed uint64) *Generator {
s, err := newRand(seed, true)
if err != nil {
panic(err)
}
return &Generator{rand: s}
return &Generator{draws: drawstate.New(seed)}
}
// parse unmarshals a JSON template fragment into its dynamic form.
@@ -135,5 +133,5 @@ func compiled(t *testing.T, s string) node {
func mustRender(t *testing.T, f *Generator, s string) string {
t.Helper()
return renderOnce(f.rand, compiled(t, s))
return renderOnce(f.draws, compiled(t, s))
}
+66
View File
@@ -0,0 +1,66 @@
package fejkdata
import (
"errors"
"go/build"
"io/fs"
"path/filepath"
"slices"
"strings"
"testing"
)
// TestPackageImports holds each package in the module to the module packages it may import.
func TestPackageImports(t *testing.T) {
const module = "github.com/larvit/fejkdata"
allowed := map[string][]string{
".": {"internal/drawstate"},
"cmd/fejkdata": {"."},
"internal/drawstate": nil,
}
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
}
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)
}
for dir := range allowed {
if !seen[dir] {
t.Errorf("listed package %s does not exist", dir)
}
}
}
+40
View File
@@ -0,0 +1,40 @@
package drawstate
import "testing"
func TestOneSeedDrawsOneSequence(t *testing.T) {
a, b := New(42), New(42)
for i := 0; i < 50; i++ {
if x, y := a.Uint64(), b.Uint64(); x != y {
t.Fatalf("seed 42 diverged at draw %d: %d != %d", i, x, y)
}
}
}
func TestTwoSeedsDrawTwoSequences(t *testing.T) {
a, b := New(1), New(2)
for i := 0; i < 50; i++ {
if a.Uint64() != b.Uint64() {
return
}
}
t.Fatal("seeds 1 and 2 drew identical sequences")
}
func TestCountersCountFromOneEach(t *testing.T) {
s := New(1)
for want := uint64(1); want <= 3; want++ {
if got := s.Next(""); got != want {
t.Fatalf("Next(\"\") = %d, want %d", got, want)
}
}
if got := s.Next("orders"); got != 1 {
t.Fatalf("Next(orders) = %d, want its own count from 1", got)
}
if got := s.Next(""); got != 4 {
t.Fatalf("Next(\"\") after Next(orders) = %d, want 4", got)
}
if got := New(1).Next(""); got != 1 {
t.Fatalf("a new state's Next = %d, want 1", got)
}
}
+1 -1
View File
@@ -35,7 +35,7 @@ func TestDrawStepsPanicsOnAStepItsNodeLacks(t *testing.T) {
t.Errorf("drawSteps(plain, f) recovered %v, want a panic naming the missing field", r)
}
}()
drawSteps(engine(1).rand, compiled(t, `"plain"`), []pathStep{{kind: stepField, name: "f"}}, &pinSet{}, nil, nil)
drawSteps(engine(1).draws, compiled(t, `"plain"`), []pathStep{{kind: stepField, name: "f"}}, &pinSet{}, nil, nil)
}
func TestDeepDottedPath(t *testing.T) {
+2 -2
View File
@@ -43,7 +43,7 @@ func TestGrowIsALowerBound(t *testing.T) {
}
for i := 0; i < 50; i++ {
var frames frameStack
if got := len(expand(f.rand, tmpl, renderScope{frames: &frames})); got < tmpl.compiled.grow {
if got := len(expand(f.draws, tmpl, renderScope{frames: &frames})); got < tmpl.compiled.grow {
t.Errorf("format %q: expand emitted %d bytes, below grow %d", format, got, tmpl.compiled.grow)
}
}
@@ -113,7 +113,7 @@ func TestNodeSwitchesHandleEveryKind(t *testing.T) {
"prove": func(n node) { (&valueProof{}).prove(n) },
"render": func(n node) {
var frames frameStack
render(engine(1).rand, n, renderScope{frames: &frames, row: renderedRow{tbl, 0}})
render(engine(1).draws, n, renderScope{frames: &frames, row: renderedRow{tbl, 0}})
},
"renderEdges": func(n node) { renderEdges(n) },
"stepInto": func(n node) { _, _ = stepInto(n, "x") },