Move configuration reports to shared rendering
This commit is contained in:
@@ -2,49 +2,9 @@ package ckconfig
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"go.yaml.in/yaml/v4"
|
||||
)
|
||||
|
||||
func TestDecodeSafeSnapshotPreservesYAMLTypes(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
text string
|
||||
kind yaml.Kind
|
||||
tag string
|
||||
value string
|
||||
}{
|
||||
{name: "null", text: "null\n", kind: yaml.ScalarNode, tag: "!!null", value: "null"},
|
||||
{name: "boolean", text: "true\n", kind: yaml.ScalarNode, tag: "!!bool", value: "true"},
|
||||
{name: "large integer", text: "9007199254740993\n", kind: yaml.ScalarNode, tag: "!!int", value: "9007199254740993"},
|
||||
{name: "numeric string", text: "'123'\n", kind: yaml.ScalarNode, tag: "!!str", value: "123"},
|
||||
{name: "boolean-like string", text: "'false'\n", kind: yaml.ScalarNode, tag: "!!str", value: "false"},
|
||||
{name: "empty mapping", text: "{}\n", kind: yaml.MappingNode, tag: "!!map"},
|
||||
{name: "empty sequence", text: "[]\n", kind: yaml.SequenceNode, tag: "!!seq"},
|
||||
}
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
node, err := decodeSafeSnapshot(test.text)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if node.Kind != test.kind || node.Tag != test.tag || node.Value != test.value {
|
||||
t.Fatalf("node kind/tag/value = %v/%q/%q, want %v/%q/%q", node.Kind, node.Tag, node.Value, test.kind, test.tag, test.value)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
nested, err := decodeSafeSnapshot("items:\n - name: example\n enabled: false\n")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if nested.Kind != yaml.MappingNode || nested.Content[1].Kind != yaml.SequenceNode || nested.Content[1].Content[0].Content[3].Tag != "!!bool" {
|
||||
t.Fatalf("nested collection/scalar tags were not preserved: %#v", nested)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecodeJSONPointerPreservesSemanticTokens(t *testing.T) {
|
||||
tests := []struct {
|
||||
pointer string
|
||||
@@ -73,74 +33,25 @@ func TestDecodeJSONPointerPreservesSemanticTokens(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestPlaceYAMLValueBuildsOrderedSemanticMappings(t *testing.T) {
|
||||
var placer yamlValuePlacer
|
||||
category := &yaml.Node{Kind: yaml.MappingNode, Tag: "!!map"}
|
||||
paths := [][]string{
|
||||
{"parent", "0", "dot.name", "50%"},
|
||||
{"parent", "second"},
|
||||
{"a/b", "~1"},
|
||||
{""},
|
||||
}
|
||||
for index, path := range paths {
|
||||
value := &yaml.Node{Kind: yaml.ScalarNode, Tag: "!!str", Value: string(rune('a' + index))}
|
||||
updated, err := placer.placeValue(category, path, value)
|
||||
if err != nil {
|
||||
t.Fatalf("place %q: %v", pointerFromTokens(path), err)
|
||||
}
|
||||
category = updated
|
||||
}
|
||||
|
||||
if len(category.Content) != 6 || category.Content[0].Value != "parent" || category.Content[2].Value != "a/b" || category.Content[4].Value != "" {
|
||||
t.Fatalf("mapping insertion order or empty key = %#v", category.Content)
|
||||
}
|
||||
parent := category.Content[1]
|
||||
if parent.Kind != yaml.MappingNode || len(parent.Content) != 4 || parent.Content[0].Value != "0" || parent.Content[2].Value != "second" {
|
||||
t.Fatalf("nested shared ancestor/order = %#v", parent)
|
||||
}
|
||||
numeric := parent.Content[1]
|
||||
dotted := numeric.Content[1]
|
||||
if numeric.Kind != yaml.MappingNode || numeric.Content[0].Value != "dot.name" || dotted.Kind != yaml.MappingNode || dotted.Content[0].Value != "50%" {
|
||||
t.Fatalf("semantic tokens were changed: numeric=%#v dotted=%#v", numeric, dotted)
|
||||
}
|
||||
if category.Content[1].Content[0].Tag != "!!str" || category.Content[2].Tag != "!!str" || category.Content[4].Tag != "!!str" {
|
||||
t.Fatal("mapping keys are not explicitly tagged as YAML strings")
|
||||
}
|
||||
}
|
||||
|
||||
func TestPlaceYAMLValueHandlesRootAndEmptyKey(t *testing.T) {
|
||||
var placer yamlValuePlacer
|
||||
category := &yaml.Node{Kind: yaml.MappingNode, Tag: "!!map"}
|
||||
root := &yaml.Node{Kind: yaml.ScalarNode, Tag: "!!null", Value: "null"}
|
||||
updated, err := placer.placeValue(category, nil, root)
|
||||
if err != nil || updated != root {
|
||||
t.Fatalf("root placement = %#v, %v", updated, err)
|
||||
}
|
||||
|
||||
category = &yaml.Node{Kind: yaml.MappingNode, Tag: "!!map"}
|
||||
value := &yaml.Node{Kind: yaml.ScalarNode, Tag: "!!str", Value: "empty-key"}
|
||||
updated, err = placer.placeValue(category, []string{""}, value)
|
||||
func TestPlaceReportValue(t *testing.T) {
|
||||
var root any = map[string]any{}
|
||||
var err error
|
||||
root, err = placeReportValue(root, []string{"a/b", "~1"}, false)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if updated != category || len(category.Content) != 2 || category.Content[0].Value != "" || category.Content[0].Tag != "!!str" || category.Content[1] != value {
|
||||
t.Fatalf("slash path placement = %#v", category)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPlaceYAMLValueRejectsIncompatibleAncestors(t *testing.T) {
|
||||
var placer yamlValuePlacer
|
||||
category := &yaml.Node{Kind: yaml.MappingNode, Tag: "!!map", Content: []*yaml.Node{
|
||||
stringKey("parent"), {Kind: yaml.ScalarNode, Tag: "!!str", Value: "leaf"},
|
||||
}}
|
||||
_, err := placer.placeValue(category, []string{"parent", "child"}, &yaml.Node{Kind: yaml.ScalarNode, Tag: "!!null", Value: "null"})
|
||||
if err == nil || !strings.Contains(err.Error(), "/parent/child") || !strings.Contains(err.Error(), "/parent") {
|
||||
t.Fatalf("incompatible ancestor error = %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecodeSafeSnapshotRejectsMalformedYAML(t *testing.T) {
|
||||
if _, err := decodeSafeSnapshot("value: [unterminated\n"); err == nil {
|
||||
t.Fatal("malformed snapshot unexpectedly decoded")
|
||||
root, err = placeReportValue(root, []string{""}, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
want := map[string]any{"a/b": map[string]any{"~1": false}, "": nil}
|
||||
if !reflect.DeepEqual(root, want) {
|
||||
t.Fatalf("got %#v", root)
|
||||
}
|
||||
if _, err := placeReportValue(root, []string{"a/b", "~1", "child"}, 1); err == nil {
|
||||
t.Fatal("scalar ancestor accepted")
|
||||
}
|
||||
if value, err := placeReportValue(root, nil, "replacement"); err != nil || value != "replacement" {
|
||||
t.Fatalf("root: %#v, %v", value, err)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user