Files
audita/internal/core/config/glossary_test.go

140 lines
4.6 KiB
Go

package config
import (
"os"
"path/filepath"
"slices"
"testing"
ck "go.maximumdirect.net/configkit"
)
func TestGlossarySourcesComposeAndRetainExtensions(t *testing.T) {
dir := t.TempDir()
write := func(name, data string) {
t.Helper()
file := filepath.Join(dir, name)
if err := os.MkdirAll(filepath.Dir(file), 0755); err != nil {
t.Fatal(err)
}
if err := os.WriteFile(file, []byte(data), 0644); err != nil {
t.Fatal(err)
}
}
write("config.yml", `version: 3
config:
imports: []
glossary_collections:
party:
entries:
- id: hero
name: Revised
category: character
level: 5
`)
write("glossary.yml", `config:
imports:
- path: shared/extra.yml
required: true
party:
entries:
- id: hero
name: Original
category: character
aliases: [Old]
- id: other
name: Other
category: place
`)
write("shared/extra.yml", "lore:\n entries:\n - id: hero\n name: Ancient\n category: lore\n")
write("glossary/nested/spells.yaml", "spells:\n entries:\n - id: bolt\n name: Bolt\n category: spell\n aliases: [Spark]\n plural: Bolts\n extra: {rank: 2}\n")
result, err := Load(ck.Input{Source: ck.File(filepath.Join(dir, "config.yml"))}, "")
if err != nil {
t.Fatalf("%v: %+v", err, err.(*ck.LoadError).Diagnostics())
}
party := result.Config.GlossaryCollections["party"].Entries
if len(party) != 2 || party[0].Name != "Revised" || len(party[0].Aliases) != 0 || party[1].ID != "other" {
t.Fatalf("party=%+v", party)
}
if party[0].Extra["level"] == nil {
t.Fatalf("extension missing: %+v", party[0])
}
if got := result.Config.GlossaryCollections["lore"].Entries; len(got) != 1 || got[0].ID != "hero" {
t.Fatalf("lore=%+v", got)
}
discovered, err := Load(ck.Input{Source: ck.SearchConfig("audita", ck.SearchDirectory(dir))}, "")
if err != nil || len(discovered.Config.GlossaryCollections["party"].Entries) != 2 {
t.Fatalf("discovered glossary: %+v %v", discovered, err)
}
spells := result.Config.GlossaryCollections["spells"].Entries
if len(spells) != 1 || spells[0].Plural == nil || *spells[0].Plural != "Bolts" || spells[0].Extra["extra"] == nil {
t.Fatalf("spells=%+v", spells)
}
var paths []string
for _, source := range result.Sources() {
if source.Kind == ck.SourceKindFile {
paths = append(paths, source.Path)
}
}
for _, name := range []string{"glossary.yml", "shared/extra.yml", "glossary/nested/spells.yaml"} {
if !slices.Contains(paths, filepath.Join(dir, name)) {
t.Errorf("missing source %s: %v", name, paths)
}
}
}
func TestGlossaryValidationAndPeerConflicts(t *testing.T) {
dir := t.TempDir()
main := filepath.Join(dir, "config.yml")
write := func(path, data string) {
t.Helper()
if err := os.WriteFile(path, []byte(data), 0644); err != nil {
t.Fatal(err)
}
}
for _, data := range []string{
"glossary_collections:\n empty: {entries: []}\n",
"glossary_collections:\n x:\n entries:\n - {id: 'id with spaces', name: N, category: C}\n",
} {
write(main, data)
if _, err := Load(ck.Input{Source: ck.File(main)}, ""); err != nil {
t.Fatalf("valid %q: %v", data, err)
}
}
for _, data := range []string{
"glossary_collections:\n x:\n entries:\n - {id: '', name: N, category: C}\n",
"glossary_collections:\n x:\n entries:\n - {id: x, name: '', category: C}\n",
"glossary_collections:\n x:\n entries:\n - {id: x, name: N, category: C, aliases: ['']}\n",
"glossary_collections:\n x:\n entries:\n - {id: x, name: N, category: C, plural: ''}\n",
} {
write(main, data)
if _, err := Load(ck.Input{Source: ck.File(main)}, ""); err == nil {
t.Fatalf("accepted %q", data)
}
}
write(main, "version: 3\n")
write(filepath.Join(dir, "glossary.yml"), "x:\n entries:\n - {id: same, name: One, category: C}\n")
if err := os.Mkdir(filepath.Join(dir, "glossary"), 0755); err != nil {
t.Fatal(err)
}
write(filepath.Join(dir, "glossary", "other.yml"), "x:\n entries:\n - {id: same, name: Two, category: C}\n")
if _, err := Load(ck.Input{Source: ck.File(main)}, ""); err == nil {
t.Fatal("peer conflict accepted")
}
}
func TestGlossaryUnderlaySkipsAbsentMain(t *testing.T) {
dir := t.TempDir()
if err := os.WriteFile(filepath.Join(dir, "glossary.yml"), []byte("leak:\n entries:\n - {id: a, name: A, category: C}\n"), 0644); err != nil {
t.Fatal(err)
}
t.Chdir(dir)
result, err := Load(ck.Input{Source: ck.NoSource()}, "")
if err != nil {
t.Fatal(err)
}
if len(result.Config.GlossaryCollections) != 0 {
t.Fatalf("unanchored glossary loaded: %+v", result.Config.GlossaryCollections)
}
}