Files
configkit/facade_config_directives_test.go

104 lines
3.9 KiB
Go

package configkit_test
import (
"strings"
"testing"
"testing/fstest"
configkit "go.maximumdirect.net/configkit"
)
func TestDocumentRootControlsAndNestedApplicationConfig(t *testing.T) {
type settings struct {
Imports string `yaml:"imports"`
}
type app struct {
Service struct {
Config settings `yaml:"config"`
} `yaml:"service"`
}
result, err := configkit.Load[app](configkit.Bytes("main", []byte("config: {sequences: []}\nservice: {config: {imports: ordinary}}\n")))
if err != nil || result.Config.Service.Config.Imports != "ordinary" {
t.Fatalf("result = %#v, error = %v", result, err)
}
}
func TestMountedConfigDataKeepsControlEvidenceAndHiding(t *testing.T) {
type settings struct {
Imports string `yaml:"imports"`
Token string `yaml:"token" configkit:"secret"`
}
type app struct {
Config settings `yaml:"config"`
}
fs := configkit.NewFilesystem("bundle", fstest.MapFS{
"main.yml": {Data: []byte("config: {imports: [{path: missing.yml}, {path: data.yml, destination: [config]}]}\n")},
"data.yml": {Data: []byte("imports: ordinary\ntoken: disposable-canary\n")},
})
result, err := configkit.Load[app](fs.File("main.yml"), configkit.Options[app]{Imports: true})
if err != nil {
t.Fatal(err)
}
if result.Config.Config.Imports != "ordinary" {
t.Fatalf("config = %#v", result.Config)
}
sources := result.Sources()
if len(sources) != 2 || len(sources[0].EmptyImportSelections) != 1 || sources[0].EmptyImportSelections[0].Path.String() != "/config/imports/0" {
t.Fatalf("sources = %#v", sources)
}
if _, ok := result.Metadata().Lookup(configkit.Keys("config", "imports")); !ok {
t.Fatal("missing application value")
}
if _, ok := result.Explain(configkit.Keys("config", "imports")); !ok {
t.Fatal("missing explanation")
}
var output strings.Builder
if err := result.WriteEffective(&output); err != nil || strings.Contains(output.String(), "disposable-canary") || !strings.Contains(output.String(), "ordinary") {
t.Fatalf("effective output = %q, %v", output.String(), err)
}
}
func TestOldControlSpellingsAreOrdinaryData(t *testing.T) {
body := "configkit: {imports: [{path: nonexistent.yml}]}\n_configkit: ordinary\n"
result, err := configkit.Load[map[string]any](configkit.Bytes("old", []byte(body)))
if err != nil || result.Config["configkit"] == nil || result.Config["_configkit"] != "ordinary" {
t.Fatalf("result = %#v, error = %v", result, err)
}
if _, err := configkit.Load[struct{}](configkit.Bytes("strict", []byte(body))); err == nil {
t.Fatal("strict schema accepted unknown data")
}
}
func TestDefaultsOverridesAndResolutionAtConfigRoot(t *testing.T) {
type settings struct {
Enabled bool `yaml:"enabled"`
Count int `yaml:"count"`
}
type app struct {
Config settings `yaml:"config"`
}
entryExplicit := false
result, err := configkit.Load[app](configkit.NoSource(), configkit.Options[app]{
Definition: configkit.Definition[app]{
Defaults: func() app { return app{Config: settings{Enabled: true, Count: 2}} },
Resolve: func(value *app, r *configkit.Resolution) error {
info, ok := r.EntryInfo(configkit.Keys("config", "enabled"))
entryExplicit = ok && info.Explicit && info.Origin.Layer == configkit.LayerCLI
value.Config.Count = 7
r.RecordNormalization(configkit.Keys("config", "count"), "normalize count")
return nil
},
},
Overrides: []configkit.Override{{Path: configkit.Keys("config", "enabled"), Value: false, Flag: "--enabled"}},
})
if err != nil || result == nil || !entryExplicit || result.Config.Config.Enabled || result.Config.Config.Count != 7 {
t.Fatalf("result = %#v, entry explicit = %t, error = %v", result, entryExplicit, err)
}
if info, ok := result.Metadata().Lookup(configkit.Keys("config", "enabled")); !ok || !info.Explicit || info.Origin.Layer != configkit.LayerCLI {
t.Fatalf("final enabled info = %#v, %t", info, ok)
}
if _, ok := result.Explain(configkit.Keys("config", "count")); !ok {
t.Fatal("missing resolution explanation")
}
}