Prepare reusable inheritance scope execution

This commit is contained in:
2026-10-23 20:32:10 +00:00
parent 9d4d2e2a17
commit 268fd03579
4 changed files with 305 additions and 34 deletions

View File

@@ -61,6 +61,92 @@ func TestIdentifiedInheritanceGraphSchedulesForwardReferencesInPlace(t *testing.
}
}
func TestIdentifiedInheritanceScopeAdapterReusesTemplateExecution(t *testing.T) {
sequence := parseIdentifiedInheritanceSequence(t, "identified-scope", `- id: child-a
tenant: team-a
extends: {id: parent-a, tenant: team-a}
settings: {child: a}
- id: parent-a
tenant: team-a
settings: {parent: a}
- id: child-b
tenant: team-b
extends: {id: parent-b, tenant: team-b}
settings: {child: b}
- id: parent-b
tenant: team-b
settings: {parent: b}
`)
path := Keys("jobs")
graph, diagnostics := analyzeIdentifiedInheritanceGraph(sequence, path, []string{"tenant", "id"})
if len(diagnostics) != 0 {
t.Fatalf("analyze identified graph: %#v", diagnostics)
}
policies := collectionPolicyScope{}
policies.set(path.Index(1).Key("steps"), collectionPolicy{
identityFields: []string{"step-id"}, identityPresent: true,
})
result, diagnostics := applyIdentifiedInheritanceTemplates(graph, defaultProjectionLimits(), nil, policies, sequencePolicy{})
if len(diagnostics) != 0 {
t.Fatalf("apply identified templates: %#v", diagnostics)
}
if got := len(result.root.Sequence); got != 4 {
t.Fatalf("result sequence length = %d, want 4", got)
}
for index, want := range []string{"child-a", "parent-a", "child-b", "parent-b"} {
id, found := documentAtPath(result.root.Sequence[index], Path{}.Key("id"))
if !found || id.Text != want {
t.Fatalf("result identity at index %d = %#v, found %t; want %q", index, id, found, want)
}
}
for index, want := range []string{"a", "b"} {
value, found := documentAtPath(result.root.Sequence[index*2], Path{}.Key("settings").Key("parent"))
if !found || value.Text != want {
t.Fatalf("inherited value at record %d = %#v, found %t; want %q", index*2, value, found, want)
}
}
if len(result.transfers) != 2 || result.transfers[0].from.String() != "/jobs/1" || result.transfers[0].to.String() != "/jobs/0" ||
result.transfers[1].from.String() != "/jobs/3" || result.transfers[1].to.String() != "/jobs/2" {
t.Fatalf("record transfers = %#v, want independent transfers at authored positions", result.transfers)
}
if len(result.controls) != 2 || result.controls[0].path.String() != "/jobs/0/extends" || result.controls[1].path.String() != "/jobs/2/extends" {
t.Fatalf("relationship controls = %#v, want paths from child positions", result.controls)
}
if len(result.operations) != 4 || result.operations[1].transfer == nil || result.operations[1].transfer.to.String() != "/jobs/0" ||
result.operations[3].transfer == nil || result.operations[3].transfer.to.String() != "/jobs/2" {
t.Fatalf("relationship history operations = %#v, want transfer evidence at child positions", result.operations)
}
if _, found := result.origins[path.Index(0).Key("id").String()]; !found {
t.Fatal("resolved sequence output did not retain the child identity origin path")
}
projectedPolicy, found := result.collectionPolicies.at(path.Index(0).Key("steps"))
if !found || !projectedPolicy.identityPresent || len(projectedPolicy.identityFields) != 1 || projectedPolicy.identityFields[0] != "step-id" {
t.Fatalf("inherited nested collection policy = %#v, found %t", projectedPolicy, found)
}
adapter := identifiedSequenceInheritanceScope{graph: graph, policies: policies}
fields := adapter.templates()[0].identityFields
if len(fields) != 2 || fields[0] != "id" || fields[1] != "tenant" {
t.Fatalf("payload identity fields = %v, want [id tenant]", fields)
}
templates := adapter.templates()
parentPolicy, found := templates[1].collectionPolicies.at(Keys("steps"))
if !found || len(parentPolicy.identityFields) != 1 || parentPolicy.identityFields[0] != "step-id" {
t.Fatalf("parent nested policy = %#v, found %t", parentPolicy, found)
}
if _, found := templates[0].collectionPolicies.at(Keys("steps")); found {
t.Fatal("nested policy from one record leaked into a sibling template")
}
parentPolicy.identityFields[0] = "changed"
templates[1].collectionPolicies.set(Keys("steps"), parentPolicy)
reused, found := adapter.templates()[1].collectionPolicies.at(Keys("steps"))
if !found || len(reused.identityFields) != 1 || reused.identityFields[0] != "step-id" {
t.Fatal("reusing the adapter observed a mutation to a prior template snapshot")
}
if sequence.Sequence[0].Mapping[0].Value.Text != "child-a" {
t.Fatal("executing the sequence adapter mutated its source scope")
}
}
func TestIdentifiedInheritanceRequiresChildIdentityBeforeParentLookup(t *testing.T) {
sequence := parseIdentifiedInheritanceSequence(t, "missing-child-field", `- id: child
extends: {id: parent, tenant: acme}