mirror of
https://gitee.com/johng/gf.git
synced 2024-12-02 12:17:53 +08:00
332 lines
6.4 KiB
Go
332 lines
6.4 KiB
Go
// Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
|
|
//
|
|
// This Source Code Form is subject to the terms of the MIT License.
|
|
// If a copy of the MIT was not distributed with this file,
|
|
// You can obtain one at https://github.com/gogf/gf.
|
|
|
|
package gconv_test
|
|
|
|
import (
|
|
"encoding/json"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/gogf/gf/v2/os/gtime"
|
|
"github.com/gogf/gf/v2/test/gtest"
|
|
"github.com/gogf/gf/v2/util/gconv"
|
|
)
|
|
|
|
func TestConverter_Struct(t *testing.T) {
|
|
type tA struct {
|
|
Val int
|
|
}
|
|
|
|
type tB struct {
|
|
Val1 int32
|
|
Val2 string
|
|
}
|
|
|
|
type tAA struct {
|
|
ValTop int
|
|
ValTA tA
|
|
}
|
|
|
|
type tBB struct {
|
|
ValTop int32
|
|
ValTB tB
|
|
}
|
|
|
|
type tCC struct {
|
|
ValTop string
|
|
ValTa *tB
|
|
}
|
|
|
|
type tDD struct {
|
|
ValTop string
|
|
ValTa tB
|
|
}
|
|
|
|
type tEE struct {
|
|
Val1 time.Time `json:"val1"`
|
|
Val2 *time.Time `json:"val2"`
|
|
Val3 *time.Time `json:"val3"`
|
|
}
|
|
|
|
type tFF struct {
|
|
Val1 json.RawMessage `json:"val1"`
|
|
Val2 []json.RawMessage `json:"val2"`
|
|
Val3 map[string]json.RawMessage `json:"val3"`
|
|
}
|
|
|
|
gtest.C(t, func(t *gtest.T) {
|
|
a := &tA{
|
|
Val: 1,
|
|
}
|
|
var b *tB
|
|
err := gconv.Scan(a, &b)
|
|
t.AssertNil(err)
|
|
t.AssertNE(b, nil)
|
|
t.Assert(b.Val1, 0)
|
|
t.Assert(b.Val2, "")
|
|
})
|
|
|
|
gtest.C(t, func(t *gtest.T) {
|
|
err := gconv.RegisterConverter(func(a tA) (b *tB, err error) {
|
|
b = &tB{
|
|
Val1: int32(a.Val),
|
|
Val2: "abc",
|
|
}
|
|
return
|
|
})
|
|
t.AssertNil(err)
|
|
})
|
|
|
|
gtest.C(t, func(t *gtest.T) {
|
|
a := &tA{
|
|
Val: 1,
|
|
}
|
|
var b *tB
|
|
err := gconv.Scan(a, &b)
|
|
t.AssertNil(err)
|
|
t.AssertNE(b, nil)
|
|
t.Assert(b.Val1, 1)
|
|
t.Assert(b.Val2, "abc")
|
|
})
|
|
|
|
gtest.C(t, func(t *gtest.T) {
|
|
a := &tA{
|
|
Val: 1,
|
|
}
|
|
var b *tB
|
|
err := gconv.Scan(a, &b)
|
|
t.AssertNil(err)
|
|
t.AssertNE(b, nil)
|
|
t.Assert(b.Val1, 1)
|
|
t.Assert(b.Val2, "abc")
|
|
})
|
|
|
|
gtest.C(t, func(t *gtest.T) {
|
|
a := &tA{
|
|
Val: 1,
|
|
}
|
|
var b *tB
|
|
err := gconv.Scan(a, &b)
|
|
t.AssertNil(err)
|
|
t.AssertNE(b, nil)
|
|
t.Assert(b.Val1, 1)
|
|
t.Assert(b.Val2, "abc")
|
|
})
|
|
|
|
gtest.C(t, func(t *gtest.T) {
|
|
a := &tA{
|
|
Val: 1,
|
|
}
|
|
var b *tB
|
|
err := gconv.Scan(a, &b)
|
|
t.AssertNil(err)
|
|
t.AssertNE(b, nil)
|
|
t.Assert(b.Val1, 1)
|
|
t.Assert(b.Val2, "abc")
|
|
})
|
|
|
|
gtest.C(t, func(t *gtest.T) {
|
|
aa := &tAA{
|
|
ValTop: 123,
|
|
ValTA: tA{Val: 234},
|
|
}
|
|
var bb *tBB
|
|
|
|
err := gconv.Scan(aa, &bb)
|
|
t.AssertNil(err)
|
|
t.AssertNE(bb, nil)
|
|
t.Assert(bb.ValTop, 123)
|
|
t.AssertNE(bb.ValTB.Val1, 234)
|
|
|
|
err = gconv.RegisterConverter(func(a tAA) (b *tBB, err error) {
|
|
b = &tBB{
|
|
ValTop: int32(a.ValTop) + 2,
|
|
}
|
|
err = gconv.Scan(a.ValTA, &b.ValTB)
|
|
return
|
|
})
|
|
t.AssertNil(err)
|
|
|
|
err = gconv.Scan(aa, &bb)
|
|
t.AssertNil(err)
|
|
t.AssertNE(bb, nil)
|
|
t.Assert(bb.ValTop, 125)
|
|
t.Assert(bb.ValTB.Val1, 234)
|
|
t.Assert(bb.ValTB.Val2, "abc")
|
|
|
|
})
|
|
|
|
gtest.C(t, func(t *gtest.T) {
|
|
aa := &tAA{
|
|
ValTop: 123,
|
|
ValTA: tA{Val: 234},
|
|
}
|
|
var cc *tCC
|
|
err := gconv.Scan(aa, &cc)
|
|
t.AssertNil(err)
|
|
t.AssertNE(cc, nil)
|
|
t.Assert(cc.ValTop, "123")
|
|
t.AssertNE(cc.ValTa, nil)
|
|
t.Assert(cc.ValTa.Val1, 234)
|
|
t.Assert(cc.ValTa.Val2, "abc")
|
|
})
|
|
|
|
gtest.C(t, func(t *gtest.T) {
|
|
aa := &tAA{
|
|
ValTop: 123,
|
|
ValTA: tA{Val: 234},
|
|
}
|
|
|
|
var dd *tDD
|
|
err := gconv.Scan(aa, &dd)
|
|
t.AssertNil(err)
|
|
t.AssertNE(dd, nil)
|
|
t.Assert(dd.ValTop, "123")
|
|
t.Assert(dd.ValTa.Val1, 234)
|
|
t.Assert(dd.ValTa.Val2, "abc")
|
|
})
|
|
|
|
// fix: https://github.com/gogf/gf/issues/2665
|
|
gtest.C(t, func(t *gtest.T) {
|
|
aa := &tEE{}
|
|
|
|
var tmp = map[string]any{
|
|
"val1": "2023-04-15 19:10:00 +0800 CST",
|
|
"val2": "2023-04-15 19:10:00 +0800 CST",
|
|
"val3": "2006-01-02T15:04:05Z07:00",
|
|
}
|
|
err := gconv.Struct(tmp, aa)
|
|
t.AssertNil(err)
|
|
t.AssertNE(aa, nil)
|
|
t.Assert(aa.Val1.Local(), gtime.New("2023-04-15 19:10:00 +0800 CST").Local().Time)
|
|
t.Assert(aa.Val2.Local(), gtime.New("2023-04-15 19:10:00 +0800 CST").Local().Time)
|
|
t.Assert(aa.Val3.Local(), gtime.New("2006-01-02T15:04:05Z07:00").Local().Time)
|
|
})
|
|
|
|
// fix: https://github.com/gogf/gf/issues/3006
|
|
gtest.C(t, func(t *gtest.T) {
|
|
ff := &tFF{}
|
|
var tmp = map[string]any{
|
|
"val1": map[string]any{"hello": "world"},
|
|
"val2": []any{map[string]string{"hello": "world"}},
|
|
"val3": map[string]map[string]string{"val3": {"hello": "world"}},
|
|
}
|
|
|
|
err := gconv.Struct(tmp, ff)
|
|
t.AssertNil(err)
|
|
t.AssertNE(ff, nil)
|
|
t.Assert(ff.Val1, []byte(`{"hello":"world"}`))
|
|
t.AssertEQ(len(ff.Val2), 1)
|
|
t.Assert(ff.Val2[0], []byte(`{"hello":"world"}`))
|
|
t.AssertEQ(len(ff.Val3), 1)
|
|
t.Assert(ff.Val3["val3"], []byte(`{"hello":"world"}`))
|
|
})
|
|
}
|
|
|
|
func TestConverter_CustomBasicType_ToStruct(t *testing.T) {
|
|
type CustomString string
|
|
type CustomStruct struct {
|
|
S string
|
|
}
|
|
gtest.C(t, func(t *gtest.T) {
|
|
var (
|
|
a CustomString = "abc"
|
|
b *CustomStruct
|
|
)
|
|
err := gconv.Scan(a, &b)
|
|
t.AssertNE(err, nil)
|
|
t.Assert(b, nil)
|
|
})
|
|
|
|
gtest.C(t, func(t *gtest.T) {
|
|
err := gconv.RegisterConverter(func(a CustomString) (b *CustomStruct, err error) {
|
|
b = &CustomStruct{
|
|
S: string(a),
|
|
}
|
|
return
|
|
})
|
|
t.AssertNil(err)
|
|
})
|
|
gtest.C(t, func(t *gtest.T) {
|
|
var (
|
|
a CustomString = "abc"
|
|
b *CustomStruct
|
|
)
|
|
err := gconv.Scan(a, &b)
|
|
t.AssertNil(err)
|
|
t.AssertNE(b, nil)
|
|
t.Assert(b.S, a)
|
|
})
|
|
gtest.C(t, func(t *gtest.T) {
|
|
var (
|
|
a CustomString = "abc"
|
|
b *CustomStruct
|
|
)
|
|
err := gconv.Scan(&a, &b)
|
|
t.AssertNil(err)
|
|
t.AssertNE(b, nil)
|
|
t.Assert(b.S, a)
|
|
})
|
|
}
|
|
|
|
// fix: https://github.com/gogf/gf/issues/3099
|
|
func TestConverter_CustomTimeType_ToStruct(t *testing.T) {
|
|
type timestamppb struct {
|
|
S string
|
|
}
|
|
type CustomGTime struct {
|
|
T *gtime.Time
|
|
}
|
|
type CustomPbTime struct {
|
|
T *timestamppb
|
|
}
|
|
gtest.C(t, func(t *gtest.T) {
|
|
var (
|
|
a = CustomGTime{
|
|
T: gtime.NewFromStrFormat("2023-10-26", "Y-m-d"),
|
|
}
|
|
b *CustomPbTime
|
|
)
|
|
err := gconv.Scan(a, &b)
|
|
t.AssertNil(err)
|
|
t.AssertNE(b, nil)
|
|
t.Assert(b.T.S, "")
|
|
})
|
|
|
|
gtest.C(t, func(t *gtest.T) {
|
|
err := gconv.RegisterConverter(func(in gtime.Time) (*timestamppb, error) {
|
|
return ×tamppb{
|
|
S: in.Local().Format("Y-m-d"),
|
|
}, nil
|
|
})
|
|
t.AssertNil(err)
|
|
err = gconv.RegisterConverter(func(in timestamppb) (*gtime.Time, error) {
|
|
return gtime.NewFromStr(in.S), nil
|
|
})
|
|
t.AssertNil(err)
|
|
})
|
|
gtest.C(t, func(t *gtest.T) {
|
|
var (
|
|
a = CustomGTime{
|
|
T: gtime.NewFromStrFormat("2023-10-26", "Y-m-d"),
|
|
}
|
|
b *CustomPbTime
|
|
c *CustomGTime
|
|
)
|
|
err := gconv.Scan(a, &b)
|
|
t.AssertNil(err)
|
|
t.AssertNE(b, nil)
|
|
t.AssertNE(b.T, nil)
|
|
|
|
err = gconv.Scan(b, &c)
|
|
t.AssertNil(err)
|
|
t.AssertNE(c, nil)
|
|
t.AssertNE(c.T, nil)
|
|
t.AssertEQ(a.T.Timestamp(), c.T.Timestamp())
|
|
})
|
|
}
|