103 lines
4.4 KiB
Go
103 lines
4.4 KiB
Go
package engine
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
"testing"
|
|
"testing/fstest"
|
|
)
|
|
|
|
func TestLayeredSequenceProjectsNestedSourceDestinations(t *testing.T) {
|
|
t.Parallel()
|
|
type catalog struct {
|
|
Items []map[string]any `yaml:"items"`
|
|
}
|
|
for _, mode := range []string{"upsert", "append", "replace"} {
|
|
for _, underlay := range []bool{false, true} {
|
|
t.Run(fmt.Sprintf("%s/underlay=%t", mode, underlay), func(t *testing.T) {
|
|
files := fstest.MapFS{}
|
|
for _, id := range []string{"a", "b", "c"} {
|
|
files[id+"/record.yml"] = &fstest.MapFile{Data: []byte("configkit: {imports: [{path: helper.yml}]}\nid: " + id + "\n")}
|
|
files[id+"/helper.yml"] = &fstest.MapFile{Data: []byte("value: " + id + "\n")}
|
|
}
|
|
files["main.yml"] = &fstest.MapFile{Data: []byte("configkit:\n sequences: [{destination: [items], key: id, mode: " + mode + "}]\n imports: [{glob: '*/record.yml', destination: [items], placement: sequence-item}]\n")}
|
|
lower := "items: [{id: b}, {id: a}, {id: keep}]\n"
|
|
want := map[string]int{"a": 1, "b": 0, "c": 3}
|
|
if mode == "append" {
|
|
lower = "items: [{id: keep}]\n"
|
|
want = map[string]int{"a": 1, "b": 2, "c": 3}
|
|
} else if mode == "replace" {
|
|
want = map[string]int{"a": 0, "b": 1, "c": 2}
|
|
}
|
|
incoming := loadInput{source: NewFilesystem("catalog", files).File("main.yml"), imports: true}
|
|
request := loadRequest[catalog]{main: incoming, underlays: []loadGroup{{inputs: []loadInput{{source: Bytes("lower", []byte(lower))}}}}}
|
|
if underlay {
|
|
request.main = loadInput{source: NoSource()}
|
|
request.underlays = append(request.underlays, loadGroup{inputs: []loadInput{incoming}})
|
|
}
|
|
loaded, err := testGroupedLoad(request)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
helpers := 0
|
|
for _, source := range loaded.Sources() {
|
|
if !strings.HasSuffix(source.Path, "/helper.yml") {
|
|
continue
|
|
}
|
|
helpers++
|
|
context, ok := loaded.SourceContext(source.ID)
|
|
if !ok {
|
|
t.Fatal("missing declaring context")
|
|
}
|
|
index, ok := want[context.BaseDir]
|
|
if !ok || source.Destination.String() != Keys("items").Index(index).String() {
|
|
t.Errorf("%s destination = %s, want item %d", context.BaseDir, source.Destination, index)
|
|
}
|
|
if loaded.Config.Items[index]["value"] != context.BaseDir {
|
|
t.Errorf("source destination identifies another record: %#v", loaded.Config.Items[index])
|
|
}
|
|
}
|
|
if helpers != 3 {
|
|
t.Fatalf("retained %d helpers, want 3", helpers)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestTierProjectionPreservesSourceLocalVersionEvidence(t *testing.T) {
|
|
t.Parallel()
|
|
local := Keys("version")
|
|
destination := Keys("items").Index(0).Key("details")
|
|
lower := &sourceVersionEvidence{sourceID: "lower", path: local, destination: destination.clone()}
|
|
higher := &sourceVersionEvidence{
|
|
sourceID: "higher", path: local, resolvedPath: local,
|
|
destination: destination.clone(), version: Version{Text: "accepted"},
|
|
projectedPaths: []Path{appendDestination(destination, local), destination.clone()},
|
|
}
|
|
sources := []SourceInfo{{ID: "higher", Path: "record/helper.yml", Destination: destination.clone()}}
|
|
state := &sourceVersionState{evidence: []*sourceVersionEvidence{lower, higher}}
|
|
projectTierSourceDestinations(sources, state.evidenceSince(1), []sequenceHistoryContribution{{
|
|
path: Keys("items"), mode: sequenceHistoryMapped,
|
|
items: []sequenceItemProjection{{inputIndex: 0, outputIndex: 1}},
|
|
}})
|
|
want := Keys("items").Index(1).Key("details")
|
|
if sources[0].Destination.String() != want.String() || sources[0].Path != "record/helper.yml" || higher.destination.String() != want.String() {
|
|
t.Fatalf("projected source/evidence = %#v, %#v", sources, higher)
|
|
}
|
|
if lower.destination.String() != destination.String() || lower.projectedPaths != nil {
|
|
t.Fatal("incoming projection relabeled a lower historical contribution")
|
|
}
|
|
if higher.path.String() != local.String() || higher.resolvedPath.String() != local.String() {
|
|
t.Fatal("projection changed source-local version coordinates")
|
|
}
|
|
paths := higher.sensitivityPaths()
|
|
if len(paths) != 2 || paths[0].String() != want.Key("version").String() || paths[1].String() != want.String() {
|
|
t.Fatalf("projected sensitivity paths = %#v", paths)
|
|
}
|
|
check := sourceVersionCheckForEvidence(higher, newDiffSensitivity(map[string]bool{want.String(): true}, nil), false)
|
|
if !check.Redacted || check.Version.Text != "" || check.Path.String() != local.String() {
|
|
t.Fatalf("version classification did not use effective coordinates: %#v", check)
|
|
}
|
|
}
|