79 lines
2.5 KiB
Go
79 lines
2.5 KiB
Go
package engine
|
|
|
|
import (
|
|
"reflect"
|
|
"testing"
|
|
|
|
"gitea.maximumdirect.net/eric/ConfigKit/internal/document"
|
|
)
|
|
|
|
func TestOverlayDocumentsRecursesMappingsAndReplacesAtomicSubtrees(t *testing.T) {
|
|
baseRoot := parseCompositionDocument(t, "source-1", `shared:
|
|
kept: base
|
|
changed: old
|
|
sequence: [one, two]
|
|
nullable: value
|
|
to_map: scalar
|
|
to_scalar: {child: old}
|
|
`)
|
|
base, diagnostics := composeDocuments(baseRoot)
|
|
if len(diagnostics) != 0 {
|
|
t.Fatal(diagnostics)
|
|
}
|
|
overlay := parseCompositionDocument(t, "source-2", `shared:
|
|
changed: new
|
|
added: overlay
|
|
sequence: []
|
|
nullable: null
|
|
to_map: {child: new}
|
|
to_scalar: scalar
|
|
`)
|
|
baseBefore := document.Clone(base.root)
|
|
overlayBefore := document.Clone(overlay)
|
|
|
|
result, diagnostics := overlayDocuments(base, overlay)
|
|
if len(diagnostics) != 0 {
|
|
t.Fatalf("overlayDocuments() diagnostics = %#v", diagnostics)
|
|
}
|
|
checks := []struct {
|
|
path Path
|
|
kind document.Kind
|
|
text string
|
|
}{
|
|
{path: Keys("shared", "kept"), kind: document.String, text: "base"},
|
|
{path: Keys("shared", "changed"), kind: document.String, text: "new"},
|
|
{path: Keys("shared", "added"), kind: document.String, text: "overlay"},
|
|
{path: Keys("sequence"), kind: document.Sequence},
|
|
{path: Keys("nullable"), kind: document.Null},
|
|
{path: Keys("to_map"), kind: document.Mapping},
|
|
{path: Keys("to_map", "child"), kind: document.String, text: "new"},
|
|
{path: Keys("to_scalar"), kind: document.String, text: "scalar"},
|
|
}
|
|
for _, check := range checks {
|
|
node, ok := documentAtPath(result.root, check.path)
|
|
if !ok || node.Kind != check.kind || node.Text != check.text {
|
|
t.Errorf("node %s = %#v, %v", check.path.String(), node, ok)
|
|
}
|
|
}
|
|
if _, exists := result.origins["/sequence/0"]; exists {
|
|
t.Fatal("replaced empty sequence retained a stale index origin")
|
|
}
|
|
if _, exists := result.origins["/to_scalar/child"]; exists {
|
|
t.Fatal("parent replacement retained a stale child origin")
|
|
}
|
|
shared := result.origins["/shared"]
|
|
if shared.Layer != LayerOverlay || len(shared.Locations) != 2 {
|
|
t.Fatalf("shared mapping origin = %#v", shared)
|
|
}
|
|
if len(result.overlays) != 5 {
|
|
t.Fatalf("overlay records = %#v, want five replacements", result.overlays)
|
|
}
|
|
if !reflect.DeepEqual(base.root, baseBefore) || !reflect.DeepEqual(overlay, overlayBefore) {
|
|
t.Fatal("overlay mutated an input document")
|
|
}
|
|
result.root.Mapping[0].Value.Mapping[0].Value.Text = "changed"
|
|
if !reflect.DeepEqual(base.root, baseBefore) || !reflect.DeepEqual(overlay, overlayBefore) {
|
|
t.Fatal("overlay result aliases an input document")
|
|
}
|
|
}
|