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") }) } }