Build item policies without repeated accumulated copies

This commit is contained in:
2026-10-24 01:20:12 +00:00
parent 1a673753b9
commit fafc28421f
3 changed files with 85 additions and 8 deletions

View File

@@ -229,6 +229,64 @@ func TestItemPolicyProjectionCountsContributionsWithoutLocalPolicy(t *testing.T)
}
}
func TestItemPolicyProjectionDetachesRepeatedScopes(t *testing.T) {
t.Parallel()
local := collectionPolicyScope{}
local.set(Keys("steps"), collectionPolicy{identityFields: []string{"id"}, identityPresent: true})
scope := acquisitionScope{}
ranges := make(map[sequenceRangeKey]sequenceRange)
for index, destination := range []string{"items", "other", "items"} {
path := Keys(destination)
scope.contributions = append(scope.contributions, acquiredContribution{
document: parseItemPolicyDocument(t, "item", destination+": [{}]\n"), destination: path,
nested: &composedDocument{collectionPolicies: local},
})
output := 0
if index == 2 {
output = 1
}
ranges[sequenceRangeKey{sourceIndex: index, path: path.String()}] = sequenceRange{start: output, end: output + 1}
}
first, second := &composedDocument{}, &composedDocument{}
projectNestedCollectionPolicies(first, scope, ranges)
projectNestedCollectionPolicies(second, scope, ranges)
policy := first.collectionPolicies.collections[Keys("items").String()].policy
if len(policy.recordOrder) != 2 || policy.recordOrder[0] == policy.recordOrder[1] {
t.Fatal("separately placed records did not retain distinct owners")
}
other := second.collectionPolicies.collections[Keys("items").String()].policy
if policy.recordOrder[0] == other.recordOrder[0] {
t.Fatal("independent projections reused a record owner")
}
// Mutate stored state directly: a detached query result would conceal an
// accidental alias between incrementally constructed record scopes.
steps := Keys("steps").String()
firstRecord := policy.recordPolicies[policy.recordOrder[0]]
firstRecord.collections[steps].policy.identityFields[0] = "changed"
for _, check := range []struct {
composed *composedDocument
path Path
index int
}{
{first, Keys("items"), 1}, {first, Keys("other"), 0},
{second, Keys("items"), 0}, {second, Keys("items"), 1}, {second, Keys("other"), 0},
} {
outer, _ := check.composed.collectionPolicies.at(check.path)
record, found := outer.recordPolicyAt(check.index)
identity, present := record.scope.at(Keys("steps"))
if !found || !present || !reflect.DeepEqual(identity.identityFields, []string{"id"}) {
t.Fatalf("mutation leaked into %s item %d: %#v", check.path, check.index, identity)
}
}
if local.collections[steps].policy.identityFields[0] != "id" {
t.Fatal("projected state mutated the incoming scope")
}
local.collections[steps].policy.identityFields[0] = "source-changed"
if other.recordPolicies[other.recordOrder[0]].collections[steps].policy.identityFields[0] != "id" {
t.Fatal("incoming scope remained aliased to projected state")
}
}
func TestOverlaySequenceTransfersIncomingItemPolicyOwnership(t *testing.T) {
path := Keys("records")
registered := mustCompileSequenceIdentityPolicy(t, []sequenceIdentityRegistration{{selector: sequenceIdentitySelector{literalSequenceSelector("records")}, identityFields: []string{"id"}}})