Assisted-by: GLM 5.3 Flash
This commit is contained in:
+107
@@ -1316,3 +1316,110 @@ func TestDecodeFixedArray(t *testing.T) {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestRequiredTag(t *testing.T) {
|
||||
type Config struct {
|
||||
Host string `toml:"host,required"`
|
||||
Radius int `toml:"radius"`
|
||||
}
|
||||
t.Run("a present key satisfies the tag", func(t *testing.T) {
|
||||
var cfg Config
|
||||
if err := Unmarshal([]byte("radius = 2\nhost = \"example.org\"\n"), &cfg); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if cfg.Host != "example.org" || cfg.Radius != 2 {
|
||||
t.Errorf("decoded %+v", cfg)
|
||||
}
|
||||
})
|
||||
t.Run("a missing key is an error", func(t *testing.T) {
|
||||
var cfg Config
|
||||
err := Unmarshal([]byte("radius = 2\n"), &cfg)
|
||||
want := `interpres: missing required key "host"`
|
||||
if err == nil || err.Error() != want {
|
||||
t.Errorf("err = %v, want %q", err, want)
|
||||
}
|
||||
})
|
||||
t.Run("the error carries the key path", func(t *testing.T) {
|
||||
var outer struct {
|
||||
Server Config `toml:"server"`
|
||||
}
|
||||
err := Unmarshal([]byte("[server]\nradius = 1\n"), &outer)
|
||||
want := `server: interpres: missing required key "host"`
|
||||
if err == nil || err.Error() != want {
|
||||
t.Errorf("err = %v, want %q", err, want)
|
||||
}
|
||||
})
|
||||
t.Run("case-insensitive match satisfies the tag", func(t *testing.T) {
|
||||
var cfg Config
|
||||
if err := Unmarshal([]byte("HOST = \"x\"\n"), &cfg); err != nil {
|
||||
t.Errorf("err = %v, want nil", err)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
type ctxRecorder struct {
|
||||
got context.Context
|
||||
value any
|
||||
}
|
||||
|
||||
func (r *ctxRecorder) UnmarshalTOMLContext(ctx context.Context, data any) error {
|
||||
r.got = ctx
|
||||
r.value = data
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestUnmarshalerContext(t *testing.T) {
|
||||
t.Run("the context reaches the method", func(t *testing.T) {
|
||||
type keyT struct{}
|
||||
ctx := context.WithValue(context.Background(), keyT{}, "sentinel")
|
||||
var r ctxRecorder
|
||||
if err := UnmarshalContext(ctx, []byte("a = 1\n"), &r); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if v, _ := r.got.Value(keyT{}).(string); v != "sentinel" {
|
||||
t.Errorf("ctx = %v, want the caller's context", r.got)
|
||||
}
|
||||
tree, isMap := r.value.(map[string]any)
|
||||
if !isMap || tree["a"] != int64(1) {
|
||||
t.Errorf("value = %#v, want the tree with a = 1", r.value)
|
||||
}
|
||||
})
|
||||
t.Run("the context wins over Unmarshaler", func(t *testing.T) {
|
||||
var v struct {
|
||||
R ctxBoth `toml:"r"`
|
||||
}
|
||||
if err := Unmarshal([]byte("r = 1\n"), &v); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !v.R.ctxCalled {
|
||||
t.Error("UnmarshalTOMLContext was not called")
|
||||
}
|
||||
if v.R.plainCalled {
|
||||
t.Error("UnmarshalTOML was called although the context method exists")
|
||||
}
|
||||
})
|
||||
t.Run("a non-cancellable entry point hands in Background", func(t *testing.T) {
|
||||
var r ctxRecorder
|
||||
if err := Unmarshal([]byte("a = 1\n"), &r); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if r.got != context.Background() {
|
||||
t.Errorf("ctx = %v, want context.Background", r.got)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
type ctxBoth struct {
|
||||
ctxCalled bool
|
||||
plainCalled bool
|
||||
}
|
||||
|
||||
func (b *ctxBoth) UnmarshalTOMLContext(ctx context.Context, data any) error {
|
||||
b.ctxCalled = true
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *ctxBoth) UnmarshalTOML(data any) error {
|
||||
b.plainCalled = true
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user