Complete historical inventory and query services

This commit is contained in:
2026-10-26 16:09:32 +00:00
parent cacc558288
commit 76521f7cd8
13 changed files with 311 additions and 78 deletions

View File

@@ -156,6 +156,68 @@ func TestHistorySelectionMatchesDeepSidesOfAncestorShapeChange(t *testing.T) {
}
}
func TestHistoryModelFinalizesLocationSensitivityAndDocumentReaders(t *testing.T) {
t.Parallel()
root := parseDocumentForDecode(t, "shape: {'0': {value: old}}\n")
value, _ := documentAtPath(root, Keys("shape", "0", "value"))
value.Sensitive = true
keyPath := Keys("shape", "0", "value")
dependency := Keys("credentials", "source")
builder := newHistoryBuilder()
builder.observeDocument(root, historyPhaseSources)
definitionAttribution := builder.addAttribution(Origin{
Layer: LayerBase, Locations: []Location{{SourceID: "base.yml", Line: 4, Column: 2}},
}, nil, nil)
definition := builder.nextPayload(historyPhaseSources)
builder.addObservation(historyObservation{
path: keyPath, phase: historyPhaseSources, payload: definition,
reportedPath: keyPath, role: historyRoleDefinition,
afterPresent: true, attributionRef: definitionAttribution,
})
resolutionAttribution := builder.addAttribution(
Origin{Layer: LayerResolution, Operation: ChangeNormalization},
[]string{"normalized credential"}, []Path{dependency},
)
resolution := builder.nextPayload(historyPhaseResolution)
builder.addObservation(historyObservation{
path: keyPath, phase: historyPhaseResolution, payload: resolution,
reportedPath: Keys("shape"), role: historyRoleOperation,
beforePresent: true, afterPresent: true, sensitive: true,
attributionRef: resolutionAttribution,
})
model := builder.freeze()
if got := model.documentRoots(); len(got) == 0 || got[0] != root {
t.Fatalf("document roots = %#v, want registered root", got)
}
if got, ok := model.documentAt(root, Keys("shape", "0")); !ok || got.Kind != document.Mapping {
t.Fatalf("indexed document lookup = %#v, %v", got, ok)
}
if got, ok := model.latestHistoricalLocation(keyPath); !ok || got.SourceID != "base.yml" || got.Line != 4 || got.Column != 2 {
t.Fatalf("latest historical location = %#v, %v", got, ok)
}
candidates := model.sensitivityCandidates()
var sawCandidate bool
for _, candidate := range candidates {
if !sameConcreteHistoryPath(candidate.path, keyPath) || !candidate.sensitive || len(candidate.dependencies) == 0 {
continue
}
if len(candidate.dependencies) != 1 || candidate.dependencies[0].String() != dependency.String() {
t.Fatalf("sensitivity dependencies = %#v", candidate.dependencies)
}
sawCandidate = true
}
if !sawCandidate {
t.Fatal("sensitivity candidate omitted the concrete historical path")
}
if got, found := model.documentAt(root, Keys("shape", "missing")); found || got != nil {
t.Fatalf("lookup for missing value = %#v, %v", got, found)
}
}
func TestHistoryBuilderScratchUsesOneDetachedWorkingDocument(t *testing.T) {
t.Parallel()