108 lines
4.3 KiB
Go
108 lines
4.3 KiB
Go
package configkit_test
|
|
|
|
import (
|
|
"reflect"
|
|
"testing"
|
|
"testing/fstest"
|
|
|
|
configkit "gitea.maximumdirect.net/eric/ConfigKit"
|
|
)
|
|
|
|
func TestUnderlaySequenceDescendantOrigins(t *testing.T) {
|
|
for _, later := range []bool{false, true} {
|
|
name := "first tier"
|
|
if later {
|
|
name = "later tier"
|
|
}
|
|
t.Run(name, func(t *testing.T) {
|
|
bundle := configkit.NewFilesystem("bundle", fstest.MapFS{
|
|
"main.yml": &fstest.MapFile{Data: []byte("configkit: {imports: [{path: items.yml}]}\n")},
|
|
"items.yml": &fstest.MapFile{Data: []byte("items: [{name: first, nested: [false]}]\n")},
|
|
})
|
|
tiers := []configkit.Underlay{}
|
|
if later {
|
|
tiers = append(tiers, configkit.Underlay{Inputs: []configkit.Input{{Source: configkit.Mapping("lower", map[string]any{"other": true})}}})
|
|
}
|
|
tiers = append(tiers, configkit.Underlay{Inputs: []configkit.Input{{Source: bundle.File("main.yml"), Imports: true}}})
|
|
paths := []string{"/items", "/items/0", "/items/0/name", "/items/0/nested", "/items/0/nested/0"}
|
|
entry := map[string]configkit.Origin{}
|
|
result, err := configkit.LoadLayered[map[string]any](configkit.Input{Source: configkit.Mapping("main", map[string]any{"main": true})}, configkit.LayeredOptions[map[string]any]{
|
|
Underlays: tiers,
|
|
Definition: configkit.Definition[map[string]any]{Resolve: func(_ *map[string]any, resolution *configkit.Resolution) error {
|
|
for _, pointer := range paths {
|
|
path, _ := configkit.ParsePath(pointer)
|
|
info, ok := resolution.InputInfo(path)
|
|
if !ok {
|
|
t.Errorf("missing resolver input %s", pointer)
|
|
}
|
|
entry[pointer] = info.Origin
|
|
}
|
|
return nil
|
|
}},
|
|
})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
var sourceID string
|
|
for _, source := range result.Sources() {
|
|
if source.Path == "items.yml" {
|
|
sourceID = source.ID
|
|
}
|
|
}
|
|
if sourceID == "" {
|
|
t.Fatal("missing imported source")
|
|
}
|
|
for _, pointer := range paths {
|
|
path, _ := configkit.ParsePath(pointer)
|
|
info, ok := result.Metadata().Lookup(path)
|
|
if !ok || info.Origin.Layer != configkit.LayerUnderlay || len(info.Origin.Locations) != 1 || info.Origin.Locations[0].SourceID != sourceID {
|
|
t.Errorf("%s origin = %+v", pointer, info.Origin)
|
|
}
|
|
if !reflect.DeepEqual(entry[pointer], info.Origin) {
|
|
t.Errorf("%s resolver origin differs", pointer)
|
|
}
|
|
explanation, ok := result.Explain(path)
|
|
if !ok || !reflect.DeepEqual(explanation.Origin, info.Origin) {
|
|
t.Errorf("%s explanation origin differs", pointer)
|
|
}
|
|
history := result.Metadata().History(path)
|
|
if len(history) == 0 || !reflect.DeepEqual(history[len(history)-1].Origin, info.Origin) {
|
|
t.Errorf("%s history = %+v", pointer, history)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestUnderlayHistoryRetainsLaterMappingContributors(t *testing.T) {
|
|
result, err := configkit.LoadLayered[map[string]any](configkit.Input{Source: configkit.NoSource()}, configkit.LayeredOptions[map[string]any]{Underlays: []configkit.Underlay{
|
|
{Inputs: []configkit.Input{{Source: configkit.Mapping("one", map[string]any{"x": 1})}}},
|
|
{Inputs: []configkit.Input{{Source: configkit.Mapping("two", map[string]any{"x": map[string]any{}})}}},
|
|
{Inputs: []configkit.Input{{Source: configkit.Mapping("three", map[string]any{"x": map[string]any{"y": 2}})}}},
|
|
}})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
path := configkit.Keys("x")
|
|
info, _ := result.Metadata().Lookup(path)
|
|
wantOrigin := configkit.Origin{Layer: configkit.LayerUnderlay, Locations: []configkit.Location{{SourceID: "source-2"}, {SourceID: "source-3"}}}
|
|
if !reflect.DeepEqual(info.Origin, wantOrigin) {
|
|
t.Fatalf("effective origin = %+v, want %+v", info.Origin, wantOrigin)
|
|
}
|
|
history := result.Metadata().History(path)
|
|
if len(history) != 3 || !reflect.DeepEqual(history[len(history)-1].Origin, info.Origin) {
|
|
t.Fatalf("history = %+v, effective origin = %+v", history, info.Origin)
|
|
}
|
|
explanation, ok := result.Explain(path)
|
|
if !ok || !reflect.DeepEqual(explanation.Origin, info.Origin) {
|
|
t.Fatal("explanation and metadata disagree")
|
|
}
|
|
if len(explanation.History) != 3 {
|
|
t.Fatalf("explanation history = %+v", explanation.History)
|
|
}
|
|
last := explanation.History[len(explanation.History)-1].Origin
|
|
if last.Layer != configkit.LayerUnderlay || len(last.Locations) != 1 || last.Locations[0].SourceID != "source-3" {
|
|
t.Fatalf("last explanation origin = %+v", last)
|
|
}
|
|
}
|