104 lines
3.9 KiB
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")
|
|
}
|
|
}
|