Keep complete paths in missing version evidence
This commit is contained in:
@@ -265,21 +265,23 @@ func (evidence *sourceVersionEvidence) redactText() {
|
||||
}
|
||||
|
||||
func resolveSourceVersionPath(root *document.Node, path Path) sourceVersionPath {
|
||||
resolved := sourceVersionPath{absence: sourceVersionPathInvalid}
|
||||
// Refine only segments whose container shape is known, keeping the full
|
||||
// requested suffix when lookup stops before the declaration.
|
||||
resolved := sourceVersionPath{absence: sourceVersionPathInvalid, resolvedPath: path.clone()}
|
||||
if root == nil || !path.valid() {
|
||||
return resolved
|
||||
}
|
||||
current := root
|
||||
resolved.nearest = current.Location
|
||||
resolved.ancestors = append(resolved.ancestors, sourceVersionAncestor{kind: current.Kind})
|
||||
for _, segment := range path.segments {
|
||||
for position, segment := range path.segments {
|
||||
switch current.Kind {
|
||||
case document.Mapping:
|
||||
if segment.kind == pathSegmentIndex {
|
||||
resolved.absence = sourceVersionPathObstructed
|
||||
return resolved
|
||||
}
|
||||
resolved.resolvedPath = resolved.resolvedPath.Key(segment.key)
|
||||
resolved.resolvedPath.segments[position] = pathSegment{kind: pathSegmentKey, key: segment.key}
|
||||
found := false
|
||||
for _, entry := range current.Mapping {
|
||||
if entry.Key == segment.key {
|
||||
@@ -298,7 +300,7 @@ func resolveSourceVersionPath(root *document.Node, path Path) sourceVersionPath
|
||||
resolved.absence = sourceVersionIndexUnavailable
|
||||
return resolved
|
||||
}
|
||||
resolved.resolvedPath = resolved.resolvedPath.Index(index)
|
||||
resolved.resolvedPath.segments[position] = pathSegment{kind: pathSegmentIndex, index: index}
|
||||
if index >= len(current.Sequence) {
|
||||
resolved.absence = sourceVersionIndexUnavailable
|
||||
return resolved
|
||||
@@ -310,7 +312,7 @@ func resolveSourceVersionPath(root *document.Node, path Path) sourceVersionPath
|
||||
}
|
||||
resolved.nearest = current.Location
|
||||
resolved.ancestors = append(resolved.ancestors, sourceVersionAncestor{
|
||||
path: resolved.resolvedPath.clone(), kind: current.Kind,
|
||||
path: Path{segments: clonePathSegments(resolved.resolvedPath.segments[:position+1], 0)}, kind: current.Kind,
|
||||
})
|
||||
}
|
||||
resolved.node = current
|
||||
|
||||
@@ -3,11 +3,40 @@ package engine
|
||||
import (
|
||||
"errors"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"gitea.maximumdirect.net/eric/ConfigKit/internal/document"
|
||||
)
|
||||
|
||||
func TestSourceVersionAbsentPathKeepsUnresolvedSegmentIntent(t *testing.T) {
|
||||
t.Parallel()
|
||||
for _, test := range []struct {
|
||||
name string
|
||||
body string
|
||||
path string
|
||||
want []pathSegment
|
||||
}{
|
||||
{"missing member", "{}\n", "/meta/version", []pathSegment{{kind: pathSegmentKey, key: "meta"}, {kind: pathSegmentParsed, key: "version"}}},
|
||||
{"scalar obstruction", "meta: false\n", "/meta/version", []pathSegment{{kind: pathSegmentKey, key: "meta"}, {kind: pathSegmentParsed, key: "version"}}},
|
||||
{"unavailable index", "meta: []\n", "/meta/3/version", []pathSegment{{kind: pathSegmentKey, key: "meta"}, {kind: pathSegmentIndex, index: 3}, {kind: pathSegmentParsed, key: "version"}}},
|
||||
} {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
path, err := ParsePath(test.path)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
resolved := resolveSourceVersionPath(sourceVersionTestDocument(t, test.body), path)
|
||||
if resolved.present || !reflect.DeepEqual(resolved.resolvedPath.segments, test.want) {
|
||||
t.Fatalf("absent path = %#v, want %#v", resolved.resolvedPath, test.want)
|
||||
}
|
||||
if !reflect.DeepEqual(path.segments, mustParseSourceVersionPath(t, test.path).segments) {
|
||||
t.Fatal("lookup mutated the requested path")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
type sourceVersionMountedService struct {
|
||||
Version string `yaml:"version"`
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user