Unify canonical sequence index semantics for version decoding
This commit is contained in:
90
version_path_test.go
Normal file
90
version_path_test.go
Normal file
@@ -0,0 +1,90 @@
|
||||
package configkit
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestVersionPathsShareCanonicalSequenceSemantics(t *testing.T) {
|
||||
t.Parallel()
|
||||
type config struct {
|
||||
Versions []string `yaml:"versions"`
|
||||
}
|
||||
for _, token := range []string{"0", "+0", "-0", "00", "+1"} {
|
||||
for _, value := range []string{"4", "'4'"} {
|
||||
t.Run(token+"/"+value, func(t *testing.T) {
|
||||
path, err := ParsePath("/versions/" + token)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var checked Version
|
||||
result, err := Load[config](Bytes("version.yml", []byte("versions: ["+value+"]\n")), Options[config]{Definition: Definition[config]{
|
||||
Version: &VersionRule{Path: path, Check: func(v Version, _ *Validation) error { checked = v; return nil }},
|
||||
}})
|
||||
want := Version{}
|
||||
if token == "0" {
|
||||
want = Version{Present: true, Text: "4"}
|
||||
}
|
||||
if checked != want {
|
||||
t.Fatalf("checked = %#v, want %#v", checked, want)
|
||||
}
|
||||
if token != "0" && value == "4" {
|
||||
requireDiagnostic(t, err, CodeDecodeType, "/versions/0")
|
||||
return
|
||||
}
|
||||
if err != nil || result.Config.Versions[0] != "4" {
|
||||
t.Fatalf("result = %#v, err = %v", result, err)
|
||||
}
|
||||
_, found := result.Metadata().Lookup(path)
|
||||
if found != (token == "0") {
|
||||
t.Fatalf("metadata lookup = %v", found)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestVersionPathsPreserveLiteralMappingKeysAndSegmentIntent(t *testing.T) {
|
||||
t.Parallel()
|
||||
for _, key := range []string{"0", "+0", "-0", "00", "a/b~"} {
|
||||
t.Run(key, func(t *testing.T) {
|
||||
path, err := ParsePath(Keys(key).String())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
result, err := Load[map[string]string](Bytes("version.yml", []byte("'"+key+"': 4\n")), Options[map[string]string]{Definition: Definition[map[string]string]{
|
||||
Version: &VersionRule{Path: path, Check: func(v Version, _ *Validation) error {
|
||||
if !v.Present || v.Text != "4" {
|
||||
t.Errorf("checked = %#v", v)
|
||||
}
|
||||
return nil
|
||||
}},
|
||||
}})
|
||||
if err != nil || result.Config[key] != "4" {
|
||||
t.Fatalf("result = %#v, err = %v", result, err)
|
||||
}
|
||||
if _, ok := result.Metadata().Lookup(path); !ok {
|
||||
t.Fatal("literal key missing from metadata")
|
||||
}
|
||||
})
|
||||
}
|
||||
for _, test := range []struct {
|
||||
name string
|
||||
path Path
|
||||
input string
|
||||
}{
|
||||
{"key cannot address sequence", Keys("versions", "0"), "versions: [4]\n"},
|
||||
{"index cannot address mapping", Keys("versions").Index(0), "versions: {'0': 4}\n"},
|
||||
} {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
type config struct {
|
||||
Versions any `yaml:"versions"`
|
||||
}
|
||||
_, err := Load[config](Bytes("version.yml", []byte(test.input)), Options[config]{Definition: Definition[config]{Version: &VersionRule{Path: test.path, Check: func(v Version, validation *Validation) error {
|
||||
if v.Present {
|
||||
t.Errorf("wrong segment kind found version: %#v", v)
|
||||
}
|
||||
validation.Error(Keys("versions"), "version absent")
|
||||
return nil
|
||||
}}}})
|
||||
requireDiagnostic(t, err, CodeVersionError, "/versions")
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user