mirror of
https://github.com/zeromicro/go-zero.git
synced 2026-07-02 00:35:37 +08:00
fix(mapping): correct unmarshaling of pointer-to-slice fields (#5662)
Co-authored-by: kevin <wanjunfeng@gmail.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -931,6 +931,113 @@ func TestUnmarshalJsonArray(t *testing.T) {
|
|||||||
assert.Equal(t, 18, v[0].Age)
|
assert.Equal(t, 18, v[0].Age)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestUnmarshalJsonBytesPointerSliceUint64(t *testing.T) {
|
||||||
|
t.Run("with values", func(t *testing.T) {
|
||||||
|
var c struct {
|
||||||
|
IDs *[]uint64 `json:"ids,optional"`
|
||||||
|
}
|
||||||
|
content := []byte(`{"ids":[9000,9001]}`)
|
||||||
|
|
||||||
|
assert.Nil(t, UnmarshalJsonBytes(content, &c))
|
||||||
|
assert.NotNil(t, c.IDs)
|
||||||
|
assert.Equal(t, []uint64{9000, 9001}, *c.IDs)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("omitted", func(t *testing.T) {
|
||||||
|
var c struct {
|
||||||
|
IDs *[]uint64 `json:"ids,optional"`
|
||||||
|
}
|
||||||
|
content := []byte(`{}`)
|
||||||
|
|
||||||
|
assert.Nil(t, UnmarshalJsonBytes(content, &c))
|
||||||
|
assert.Nil(t, c.IDs)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("null", func(t *testing.T) {
|
||||||
|
var c struct {
|
||||||
|
IDs *[]uint64 `json:"ids,optional"`
|
||||||
|
}
|
||||||
|
content := []byte(`{"ids":null}`)
|
||||||
|
|
||||||
|
assert.Nil(t, UnmarshalJsonBytes(content, &c))
|
||||||
|
assert.Nil(t, c.IDs)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("empty array", func(t *testing.T) {
|
||||||
|
var c struct {
|
||||||
|
IDs *[]uint64 `json:"ids,optional"`
|
||||||
|
}
|
||||||
|
content := []byte(`{"ids":[]}`)
|
||||||
|
|
||||||
|
assert.Nil(t, UnmarshalJsonBytes(content, &c))
|
||||||
|
assert.NotNil(t, c.IDs)
|
||||||
|
assert.Equal(t, []uint64{}, *c.IDs)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUnmarshalJsonBytesPointerSliceOtherTypes(t *testing.T) {
|
||||||
|
t.Run("pointer to []string", func(t *testing.T) {
|
||||||
|
var c struct {
|
||||||
|
Names *[]string `json:"names,optional"`
|
||||||
|
}
|
||||||
|
content := []byte(`{"names":["a","b"]}`)
|
||||||
|
|
||||||
|
assert.Nil(t, UnmarshalJsonBytes(content, &c))
|
||||||
|
assert.NotNil(t, c.Names)
|
||||||
|
assert.Equal(t, []string{"a", "b"}, *c.Names)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("pointer to []int", func(t *testing.T) {
|
||||||
|
var c struct {
|
||||||
|
Values *[]int `json:"values,optional"`
|
||||||
|
}
|
||||||
|
content := []byte(`{"values":[1,2,3]}`)
|
||||||
|
|
||||||
|
assert.Nil(t, UnmarshalJsonBytes(content, &c))
|
||||||
|
assert.NotNil(t, c.Values)
|
||||||
|
assert.Equal(t, []int{1, 2, 3}, *c.Values)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUnmarshalJsonBytesPointerSliceStruct(t *testing.T) {
|
||||||
|
type Item struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Age int `json:"age"`
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Run("with values", func(t *testing.T) {
|
||||||
|
var c struct {
|
||||||
|
Items *[]Item `json:"items,optional"`
|
||||||
|
}
|
||||||
|
content := []byte(`{"items":[{"name":"alice","age":30},{"name":"bob","age":25}]}`)
|
||||||
|
|
||||||
|
assert.Nil(t, UnmarshalJsonBytes(content, &c))
|
||||||
|
assert.NotNil(t, c.Items)
|
||||||
|
assert.Equal(t, []Item{{Name: "alice", Age: 30}, {Name: "bob", Age: 25}}, *c.Items)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("omitted", func(t *testing.T) {
|
||||||
|
var c struct {
|
||||||
|
Items *[]Item `json:"items,optional"`
|
||||||
|
}
|
||||||
|
content := []byte(`{}`)
|
||||||
|
|
||||||
|
assert.Nil(t, UnmarshalJsonBytes(content, &c))
|
||||||
|
assert.Nil(t, c.Items)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("empty array", func(t *testing.T) {
|
||||||
|
var c struct {
|
||||||
|
Items *[]Item `json:"items,optional"`
|
||||||
|
}
|
||||||
|
content := []byte(`{"items":[]}`)
|
||||||
|
|
||||||
|
assert.Nil(t, UnmarshalJsonBytes(content, &c))
|
||||||
|
assert.NotNil(t, c.Items)
|
||||||
|
assert.Equal(t, []Item{}, *c.Items)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func TestUnmarshalJsonBytesError(t *testing.T) {
|
func TestUnmarshalJsonBytesError(t *testing.T) {
|
||||||
var v []struct {
|
var v []struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
|
|||||||
@@ -142,11 +142,11 @@ func (u *Unmarshaler) fillSlice(fieldType reflect.Type, value reflect.Value,
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
baseType := fieldType.Elem()
|
baseType := Deref(fieldType).Elem()
|
||||||
dereffedBaseType := Deref(baseType)
|
dereffedBaseType := Deref(baseType)
|
||||||
dereffedBaseKind := dereffedBaseType.Kind()
|
dereffedBaseKind := dereffedBaseType.Kind()
|
||||||
if refValue.Len() == 0 {
|
if refValue.Len() == 0 {
|
||||||
value.Set(reflect.MakeSlice(reflect.SliceOf(baseType), 0, 0))
|
SetValue(fieldType, value, reflect.MakeSlice(reflect.SliceOf(baseType), 0, 0))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -179,7 +179,7 @@ func (u *Unmarshaler) fillSlice(fieldType reflect.Type, value reflect.Value,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if valid {
|
if valid {
|
||||||
value.Set(conv)
|
SetValue(fieldType, value, conv)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@@ -201,7 +201,7 @@ func (u *Unmarshaler) fillSliceFromString(fieldType reflect.Type, value reflect.
|
|||||||
return errUnsupportedType
|
return errUnsupportedType
|
||||||
}
|
}
|
||||||
|
|
||||||
baseFieldType := fieldType.Elem()
|
baseFieldType := Deref(fieldType).Elem()
|
||||||
baseFieldKind := baseFieldType.Kind()
|
baseFieldKind := baseFieldType.Kind()
|
||||||
conv := reflect.MakeSlice(reflect.SliceOf(baseFieldType), len(slice), cap(slice))
|
conv := reflect.MakeSlice(reflect.SliceOf(baseFieldType), len(slice), cap(slice))
|
||||||
|
|
||||||
@@ -211,7 +211,7 @@ func (u *Unmarshaler) fillSliceFromString(fieldType reflect.Type, value reflect.
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
value.Set(conv)
|
SetValue(fieldType, value, conv)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user