Files
ConfigKit/internal/engine/override_history_order_test.go

94 lines
3.4 KiB
Go

package engine
import "testing"
func TestCLIHistoryFollowsInheritanceAndPrecedesResolution(t *testing.T) {
t.Parallel()
for _, test := range []struct {
name string
layered, records, equal, resolve bool
}{
{name: "ordinary mapping"},
{name: "layered mapping equal with resolution", layered: true, equal: true, resolve: true},
{name: "ordinary records equal", records: true, equal: true},
{name: "layered records with resolution", layered: true, records: true, resolve: true},
} {
t.Run(test.name, func(t *testing.T) {
body := "base: {value: parent}\nchild: {extends: base, value: authored}\n"
query, parent := Keys("child", "value"), Keys("base", "value")
cliValue := "cli"
if test.equal {
cliValue = "authored"
}
override := Override{Path: query, Value: cliValue, Flag: "--value"}
if test.records {
body = "configkit:\n sequences: [{destination: [items], key: id}]\nitems: [{id: base, value: parent}, {id: child, extends: {id: base}}]\n"
query, parent = Keys("items").Index(1).Key("value"), Keys("items").Index(0).Key("value")
if test.equal {
cliValue = "parent"
}
override = Override{Path: Keys("items"), Value: []any{map[string]any{"id": "base", "value": "parent"}, map[string]any{"id": "child", "value": cliValue}}, Flag: "--items"}
}
definition := Definition[map[string]any]{}
if test.resolve {
definition.Resolve = func(value *map[string]any, resolution *Resolution) error {
recorded := query
if test.records {
(*value)["items"].([]any)[1].(map[string]any)["value"] = "resolved"
recorded = Keys("items")
} else {
(*value)["child"].(map[string]any)["value"] = "resolved"
}
resolution.Record(recorded, ChangeNormalization, "normalize after CLI", parent)
return nil
}
}
source := Bytes("source", []byte(body))
var loaded *testResult[map[string]any]
var err error
if test.layered {
loaded, err = testGroupedLoad(loadRequest[map[string]any]{main: loadInput{source: source}, definition: definition, overrides: []Override{override}})
} else {
loaded, err = testLoad(source, Options[map[string]any]{Definition: definition, Overrides: []Override{override}})
}
if err != nil {
t.Fatal(err)
}
history := loaded.Metadata().History(query)
inherited, cli, resolved := false, false, false
for _, change := range history {
if change.Origin.Operation == ChangeInheritance {
if cli {
t.Fatal("inheritance reported after CLI")
}
inherited = true
} else if change.Origin.Layer == LayerBase && cli {
t.Fatal("source definition reappeared after CLI")
}
if change.Origin.Layer == LayerCLI {
if !inherited || resolved {
t.Fatal("CLI reported outside its lifecycle phase")
}
cli = true
}
if change.Origin.Layer == LayerResolution {
if !cli {
t.Fatal("resolution reported before CLI")
}
resolved = true
if len(change.Dependencies) != 1 || change.Dependencies[0].String() != parent.String() {
t.Fatalf("resolution dependencies = %#v", change.Dependencies)
}
}
}
if !inherited || !cli || resolved != test.resolve {
t.Fatalf("missing lifecycle history: %#v", history)
}
info, _ := loaded.Metadata().Lookup(query)
if history[len(history)-1].Origin.Layer != info.Origin.Layer {
t.Fatal("last history origin disagrees with effective metadata")
}
})
}
}