package engine import ( "errors" "reflect" "testing" "gitea.maximumdirect.net/eric/ConfigKit/internal/document" ) func TestNormalizeDestinationUsesLiteralMappingKeys(t *testing.T) { t.Parallel() parsed, err := ParsePath("/a~1b/0/~0") if err != nil { t.Fatal(err) } normalized, err := normalizeDestination(parsed) if err != nil { t.Fatal(err) } if got, want := normalized.String(), "/a~1b/0/~0"; got != want { t.Fatalf("normalized path = %q, want %q", got, want) } for index, want := range []string{"a/b", "0", "~"} { segment := normalized.segments[index] if segment.kind != pathSegmentKey || segment.key != want { t.Fatalf("segment %d = %#v, want key %q", index, segment, want) } } original := Keys("owned", "path") owned, err := normalizeDestination(original) if err != nil { t.Fatal(err) } owned.segments[0].key = "changed" if got := original.String(); got != "/owned/path" { t.Fatalf("normalizing shared path storage mutated its input: %q", got) } } func TestMappingPlacementModeMatchesZeroValue(t *testing.T) { t.Parallel() body := &document.Node{ Kind: document.Mapping, Mapping: []document.Entry{{ Key: "name", Value: &document.Node{Kind: document.String, Text: "entry"}, }}, } destination := Keys("catalog", "entry") path, zero, err := placeDocument(body, destination, body.Location, 5, 32) if err != nil { t.Fatal(err) } explicitPath, explicit, err := placeDocumentWithMode(body, destination, placementModeMapping, body.Location, 5, 32) if err != nil { t.Fatal(err) } if path.String() != explicitPath.String() || !reflect.DeepEqual(zero, explicit) { t.Fatalf("zero placement (%q, %#v) differs from mapping mode (%q, %#v)", path.String(), zero, explicitPath.String(), explicit) } } func TestAppendDestinationCopiesLiteralSegments(t *testing.T) { t.Parallel() parent := Keys("collection", "entry") relative := Keys("a/b", "0", "~") combined := appendDestination(parent, relative) if got, want := combined.String(), "/collection/entry/a~1b/0/~0"; got != want { t.Fatalf("combined destination = %q, want %q", got, want) } if len(combined.segments) != 5 { t.Fatalf("combined segments = %#v", combined.segments) } for index, segment := range combined.segments { if segment.kind != pathSegmentKey { t.Errorf("segment %d kind = %v, want mapping key", index, segment.kind) } } combined.segments[0].key = "changed parent" combined.segments[2].key = "changed relative" if got := parent.String(); got != "/collection/entry" { t.Fatalf("combined path shares parent segment storage: %q", got) } if got := relative.String(); got != "/a~1b/0/~0" { t.Fatalf("combined path shares relative segment storage: %q", got) } } func TestNormalizeDestinationRejectsIndicesAndReservedKeys(t *testing.T) { t.Parallel() for name, path := range map[string]Path{ "explicit index": Keys("items").Index(0), "negative index": Keys("items").Index(-1), "invalid path": Path{invalid: true}, "configkit": Keys("configkit"), "extends": Keys("extends"), "nested configkit": Keys("outer", "configkit"), "nested extends": Keys("outer", "extends"), } { t.Run(name, func(t *testing.T) { t.Parallel() if _, err := normalizeDestination(path); !errors.Is(err, errInvalidDestination) { t.Fatalf("normalizeDestination(%q) error = %v, want invalid destination", path.String(), err) } }) } for _, key := range []string{"myextends", "configkit2", "", ".", "..", "../x", "a.b", "a/b", "~"} { t.Run("ordinary key "+key, func(t *testing.T) { t.Parallel() if _, err := normalizeDestination(Keys(key)); err != nil { t.Fatalf("normalizeDestination(%q): %v", key, err) } }) } } func TestPlaceDocumentWrapsEmptyMappingAndPreservesSourceCoordinates(t *testing.T) { t.Parallel() rootLocation := document.Location{SourceID: "source-a", Line: 1, Column: 1} body := &document.Node{ Kind: document.Mapping, Location: document.Location{SourceID: "source-a", Line: 4, Column: 1}, } path, placed, err := placeDocument(body, Keys("a", "b"), rootLocation, 2, 5) if err != nil { t.Fatal(err) } if got, want := path.String(), "/a/b"; got != want { t.Fatalf("normalized destination = %q, want %q", got, want) } if placed == body || len(placed.Mapping) != 1 || placed.Mapping[0].Key != "a" { t.Fatalf("outer destination mapping was not created: %#v", placed) } inner := placed.Mapping[0].Value if inner.Kind != document.Mapping || len(inner.Mapping) != 1 || inner.Mapping[0].Key != "b" { t.Fatalf("inner destination mapping was not created: %#v", inner) } if inner.Mapping[0].Value != body || len(body.Mapping) != 0 { t.Fatal("placement mutated or copied the authored body") } if placed.Location != rootLocation || inner.Location != rootLocation || placed.Mapping[0].KeyLocation != rootLocation || placed.Mapping[0].ValueLocation != rootLocation { t.Fatal("introduced structure did not use the source-root coordinate fallback") } if body.Location != (document.Location{SourceID: "source-a", Line: 4, Column: 1}) { t.Fatalf("authored body location changed: %#v", body.Location) } if got, want := countInputNodes(placed), countInputNodes(body)+4; got != want { t.Fatalf("placed node count = %d, want body count plus four synthetic nodes (%d)", got, want) } } func TestPlaceDocumentPreservesAuthoredEntryCoordinates(t *testing.T) { t.Parallel() rootLocation := document.Location{SourceID: "source-b", Line: 1, Column: 1} bodyLocation := document.Location{SourceID: "source-b", Line: 3, Column: 1} keyLocation := document.Location{SourceID: "source-b", Line: 3, Column: 3} valueLocation := document.Location{SourceID: "source-b", Line: 4, Column: 5} value := &document.Node{Kind: document.String, Location: valueLocation, Text: "value"} body := &document.Node{ Kind: document.Mapping, Location: bodyLocation, Mapping: []document.Entry{{ Key: "leaf", KeyLocation: keyLocation, ValueLocation: valueLocation, Value: value, }}, } _, placed, err := placeDocument(body, Keys("mounted"), rootLocation, 2, 5) if err != nil { t.Fatal(err) } if placed.Mapping[0].KeyLocation != rootLocation || placed.Mapping[0].ValueLocation != rootLocation { t.Fatal("introduced destination entry did not use the source-root fallback") } if placed.Mapping[0].Value != body || body.Location != bodyLocation { t.Fatal("placement changed the authored body node or location") } entry := body.Mapping[0] if entry.KeyLocation != keyLocation || entry.ValueLocation != valueLocation || entry.Value != value || value.Location != valueLocation { t.Fatal("placement changed authored entry or value coordinates") } } func TestPlaceDocumentRootAndBounds(t *testing.T) { t.Parallel() body := &document.Node{ Kind: document.Mapping, Mapping: []document.Entry{{ Key: "leaf", Value: &document.Node{Kind: document.String, Text: "value"}, }}, } path, placed, err := placeDocument(body, Path{}, body.Location, 1, 3) if err != nil { t.Fatal(err) } if path.String() != "" || placed != body { t.Fatal("root placement must preserve the existing body") } destination := Keys("a", "b") if !destinationWithinLimits(body, destination, 3, 7) { t.Fatal("exact depth and node limits should admit the placed document") } if destinationWithinLimits(body, destination, 2, 7) { t.Fatal("placement exceeding the depth limit was accepted") } if destinationWithinLimits(body, destination, 3, 6) { t.Fatal("placement exceeding the node limit was accepted") } _, placed, err = placeDocument(body, destination, body.Location, 3, 6) if !errors.Is(err, errDestinationLimit) || placed != nil { t.Fatalf("bounded placement returned node %p and error %v", placed, err) } _, absent, err := placeDocument(nil, destination, document.Location{}, 0, 0) if err != nil || absent != nil { t.Fatalf("absent body should not consume placement limits: node %p, error %v", absent, err) } } func TestPlaceDocumentSequenceItemAndMountedBounds(t *testing.T) { t.Parallel() root := document.Location{SourceID: "item", Line: 1, Column: 1} body := &document.Node{Kind: document.Mapping, Location: root} destination := Keys("catalog", "entries") placedPath, placed, err := placeDocumentWithMode(body, destination, placementModeSequenceItem, root, 3, 6) if err != nil { t.Fatal(err) } if placedPath.String() != "/catalog/entries" || placed.Kind != document.Mapping { t.Fatalf("placed root = %q %#v", placedPath.String(), placed) } container, ok := documentAtPath(placed, destination) if !ok || container.Kind != document.Sequence || len(container.Sequence) != 1 || container.Sequence[0] != body { t.Fatalf("item destination = %#v, present %v", container, ok) } if got, want := countInputNodes(placed), countInputNodes(body)+destinationWrapperNodeCount(destination)+1; got != want { t.Fatalf("item node count = %d, want %d", got, want) } if container.Location != root || container.Sequence[0].Location != root { t.Fatal("synthetic sequence or authored mapping lost source coordinates") } if _, _, err := placeDocumentWithMode(body, Path{}, placementModeSequenceItem, root, 3, 6); !errors.Is(err, errInvalidDestination) { t.Fatalf("root item placement error = %v, want invalid destination", err) } if _, _, err := placeDocumentWithMode(&document.Node{Kind: document.String}, destination, placementModeSequenceItem, root, 3, 6); !errors.Is(err, errInvalidDestination) { t.Fatalf("non-mapping item placement error = %v, want invalid destination", err) } if _, _, err := placeDocumentWithMode(body, destination, placementMode(255), root, 3, 6); !errors.Is(err, errInvalidDestination) { t.Fatalf("unknown placement mode error = %v, want invalid destination", err) } for _, test := range []struct { name string depth int nodes int wantAccept bool }{ {name: "exact allowance", depth: 3, nodes: 6, wantAccept: true}, {name: "one too shallow", depth: 2, nodes: 6}, {name: "one node short", depth: 3, nodes: 5}, } { t.Run(test.name, func(t *testing.T) { t.Parallel() _, _, err := placeDocumentWithMode(body, destination, placementModeSequenceItem, root, test.depth, test.nodes) if test.wantAccept && err != nil { t.Fatalf("exact bounds rejected: %v", err) } if !test.wantAccept && !errors.Is(err, errDestinationLimit) { t.Fatalf("over-bound placement error = %v", err) } }) } }