Test that shipped categories load when first reached, from a current index, and render as the whole load
This commit is contained in:
+209
@@ -0,0 +1,209 @@
|
||||
package fejkdata
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"go/format"
|
||||
"io/fs"
|
||||
"os"
|
||||
"reflect"
|
||||
"slices"
|
||||
"sort"
|
||||
"sync"
|
||||
"testing"
|
||||
)
|
||||
|
||||
const shippedIndexFile = "shippedindex.go"
|
||||
|
||||
// newShippedWhole loads every shipped category in New, as a --data-path load does, so a test
|
||||
// reads the whole shipped tree.
|
||||
func newShippedWhole(t testing.TB, opts ...Option) *Generator {
|
||||
t.Helper()
|
||||
data, err := fs.Sub(shippedFS, "data")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
f, err := New(append([]Option{WithoutShippedData(), WithDataFS(data)}, opts...)...)
|
||||
if err != nil {
|
||||
t.Fatalf("New() = %v", err)
|
||||
}
|
||||
return f
|
||||
}
|
||||
|
||||
// loadedCategories is the dot path of every category f has parsed and linked.
|
||||
func loadedCategories(f *Generator) []string {
|
||||
var out []string
|
||||
var walk func(prefix string, g *folder)
|
||||
walk = func(prefix string, g *folder) {
|
||||
for _, name := range sortedNames(g.children) {
|
||||
if sub, isFolder := g.children[name].(*folder); isFolder {
|
||||
walk(join(prefix, name), sub)
|
||||
continue
|
||||
}
|
||||
out = append(out, join(prefix, name))
|
||||
}
|
||||
}
|
||||
walk("", &f.root)
|
||||
return out
|
||||
}
|
||||
|
||||
// REPIN=1 rewrites the index.
|
||||
func TestShippedIndexIsCurrent(t *testing.T) {
|
||||
got, err := shippedIndexSource(newShippedWhole(t))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if os.Getenv("REPIN") == "1" {
|
||||
if err := os.WriteFile(shippedIndexFile, got, 0o644); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
return
|
||||
}
|
||||
want, err := os.ReadFile(shippedIndexFile)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if string(got) != string(want) {
|
||||
t.Fatalf("%s is stale for data/; rewrite it with REPIN=1", shippedIndexFile)
|
||||
}
|
||||
}
|
||||
|
||||
func shippedIndexSource(whole *Generator) ([]byte, error) {
|
||||
var b bytes.Buffer
|
||||
b.WriteString("// Code generated by TestShippedIndexIsCurrent with REPIN=1. DO NOT EDIT.\n\npackage fejkdata\n\nvar shippedIndex = map[string]shippedCategory{\n")
|
||||
for _, s := range categorySites(&whole.root) {
|
||||
fmt.Fprintf(&b, "%q: {", s.path)
|
||||
if t, isTable := s.n.(*table); isTable && t.parentIndex >= 0 {
|
||||
fmt.Fprintf(&b, "parent: %q, ", t.header[t.parentIndex])
|
||||
}
|
||||
ps := paths(s.n)
|
||||
sort.Strings(ps)
|
||||
fmt.Fprintf(&b, "paths: %#v},\n", ps)
|
||||
}
|
||||
b.WriteString("}\n")
|
||||
return format.Source(b.Bytes())
|
||||
}
|
||||
|
||||
func TestNewLoadsNoShippedCategory(t *testing.T) {
|
||||
f, err := New()
|
||||
if err != nil {
|
||||
t.Fatalf("New() = %v", err)
|
||||
}
|
||||
if got := loadedCategories(f); len(got) > 0 {
|
||||
t.Fatalf("New() loaded %v", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestReachingACategoryLoadsWhatItReads(t *testing.T) {
|
||||
for _, tc := range []struct {
|
||||
reach func(f *Generator) error
|
||||
want, absent []string
|
||||
}{
|
||||
{
|
||||
reach: func(f *Generator) error { _, err := f.Fake("sv_SE.person.first"); return err },
|
||||
want: []string{"sv_SE.first-name", "sv_SE.last-name", "sv_SE.person", "sv_SE.sex", "sv_SE.title"},
|
||||
},
|
||||
{
|
||||
reach: func(f *Generator) error { _, err := f.Fake("geo.SE.region"); return err },
|
||||
want: []string{"geo.SE.locality", "geo.SE.municipality", "geo.SE.postal-code", "geo.SE.region", "geo.SE.street"},
|
||||
absent: []string{"geo.SE.address", "geo.US.region"},
|
||||
},
|
||||
{
|
||||
reach: func(f *Generator) error { _, err := f.FakeTemplate("{/misc.territory[SE].name}"); return err },
|
||||
want: []string{"misc.territory", "misc.timezone"},
|
||||
absent: []string{"misc.tld"},
|
||||
},
|
||||
{
|
||||
reach: func(f *Generator) error { _, err := f.FakeRecord("misc.uuid"); return err },
|
||||
want: []string{"misc.uuid"},
|
||||
absent: []string{"misc.objectid"},
|
||||
},
|
||||
{
|
||||
reach: func(f *Generator) error {
|
||||
var v struct {
|
||||
Name string `fake:"sv_SE.first-name"`
|
||||
}
|
||||
return f.FakeStruct(&v)
|
||||
},
|
||||
want: []string{"sv_SE.first-name"},
|
||||
absent: []string{"sv_SE.person"},
|
||||
},
|
||||
} {
|
||||
f, err := New()
|
||||
if err != nil {
|
||||
t.Fatalf("New() = %v", err)
|
||||
}
|
||||
if err := tc.reach(f); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
got := loadedCategories(f)
|
||||
for _, w := range tc.want {
|
||||
if !slices.Contains(got, w) {
|
||||
t.Errorf("loaded %v, want %s among them", got, w)
|
||||
}
|
||||
}
|
||||
for _, a := range tc.absent {
|
||||
if slices.Contains(got, a) {
|
||||
t.Errorf("loaded %v, want %s left unloaded", got, a)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestADataPathLoadsTheShippedSetWhole(t *testing.T) {
|
||||
f, err := New(WithDataPath(writeData(t, map[string]string{"x": `"y"`})))
|
||||
if err != nil {
|
||||
t.Fatalf("New() = %v", err)
|
||||
}
|
||||
if got, want := loadedCategories(f), loadedCategories(newShippedWhole(t, WithDataPath(writeData(t, map[string]string{"x": `"y"`})))); !reflect.DeepEqual(got, want) {
|
||||
t.Fatalf("loaded %v, want %v", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestOnDemandRendersAsTheWholeLoad(t *testing.T) {
|
||||
whole := newShippedWhole(t)
|
||||
paths := whole.List()
|
||||
lazy, err := New()
|
||||
if err != nil {
|
||||
t.Fatalf("New() = %v", err)
|
||||
}
|
||||
if got := lazy.List(); !reflect.DeepEqual(got, paths) {
|
||||
t.Fatalf("List() on demand = %v, want %v", got, paths)
|
||||
}
|
||||
a, err := New(WithSeed(7))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
b := newShippedWhole(t, WithSeed(7))
|
||||
for _, p := range paths {
|
||||
for range 3 {
|
||||
got, gotErr := a.Fake(p)
|
||||
want, wantErr := b.Fake(p)
|
||||
if got != want || (gotErr == nil) != (wantErr == nil) {
|
||||
t.Fatalf("Fake(%q) on demand = %q, %v; whole = %q, %v", p, got, gotErr, want, wantErr)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestListRunsBesideAnOnDemandLoad(t *testing.T) {
|
||||
f, err := New()
|
||||
if err != nil {
|
||||
t.Fatalf("New() = %v", err)
|
||||
}
|
||||
var wg sync.WaitGroup
|
||||
for _, p := range []string{"sv_SE.person", "geo.US.address", "misc.territory"} {
|
||||
wg.Add(2)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
if _, err := f.Fake(p); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}()
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
f.List()
|
||||
}()
|
||||
}
|
||||
wg.Wait()
|
||||
}
|
||||
Reference in New Issue
Block a user