From 2b5d889bb919627f4ca11b4c204a92d9fa599fd5 Mon Sep 17 00:00:00 2001 From: John Date: Tue, 15 Jan 2019 21:54:34 +0800 Subject: [PATCH] fulfil unit test cases of gconv --- g/util/gconv/gconv_z_unit_basic_test.go | 34 ++++ g/util/gconv/gconv_z_unit_map_test.go | 31 +++ g/util/gconv/gconv_z_unit_slice_test.go | 25 +++ g/util/gconv/gconv_z_unit_struct_test.go | 246 ++++++++++++++++++++++- g/util/gconv/gconv_z_unit_time_test.go | 25 +++ g/util/gtest/gtest.go | 8 +- 6 files changed, 367 insertions(+), 2 deletions(-) create mode 100644 g/util/gconv/gconv_z_unit_basic_test.go create mode 100644 g/util/gconv/gconv_z_unit_map_test.go create mode 100644 g/util/gconv/gconv_z_unit_slice_test.go create mode 100644 g/util/gconv/gconv_z_unit_time_test.go diff --git a/g/util/gconv/gconv_z_unit_basic_test.go b/g/util/gconv/gconv_z_unit_basic_test.go new file mode 100644 index 000000000..8c44f5fac --- /dev/null +++ b/g/util/gconv/gconv_z_unit_basic_test.go @@ -0,0 +1,34 @@ +// Copyright 2018 gf Author(https://gitee.com/johng/gf). 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://gitee.com/johng/gf. + +package gconv_test + +import ( + "gitee.com/johng/gf/g/util/gconv" + "gitee.com/johng/gf/g/util/gtest" + "testing" +) + + +func Test_Basic(t *testing.T) { + gtest.Case(t, func() { + value := 123.456 + gtest.AssertEQ(gconv.Int(value), int(123)) + gtest.AssertEQ(gconv.Int8(value), int8(123)) + gtest.AssertEQ(gconv.Int16(value), int16(123)) + gtest.AssertEQ(gconv.Int32(value), int32(123)) + gtest.AssertEQ(gconv.Int64(value), int64(123)) + gtest.AssertEQ(gconv.Uint(value), uint(123)) + gtest.AssertEQ(gconv.Uint8(value), uint8(123)) + gtest.AssertEQ(gconv.Uint16(value), uint16(123)) + gtest.AssertEQ(gconv.Uint32(value), uint32(123)) + gtest.AssertEQ(gconv.Uint64(value), uint64(123)) + gtest.AssertEQ(gconv.Float32(value), float32(123.456)) + gtest.AssertEQ(gconv.Float64(value), float64(123.456)) + gtest.AssertEQ(gconv.Bool(value), true) + gtest.AssertEQ(gconv.String(value), "123.456") + }) +} diff --git a/g/util/gconv/gconv_z_unit_map_test.go b/g/util/gconv/gconv_z_unit_map_test.go new file mode 100644 index 000000000..2aaf8712c --- /dev/null +++ b/g/util/gconv/gconv_z_unit_map_test.go @@ -0,0 +1,31 @@ +// Copyright 2018 gf Author(https://gitee.com/johng/gf). 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://gitee.com/johng/gf. + +package gconv_test + +import ( + "gitee.com/johng/gf/g/util/gconv" + "gitee.com/johng/gf/g/util/gtest" + "testing" +) + + +func Test_Map(t *testing.T) { + gtest.Case(t, func() { + m1 := map[string]string{ + "k" : "v", + } + m2 := map[int]string{ + 3 : "v", + } + m3 := map[float64]float32{ + 1.22 : 3.1, + } + gtest.Assert(gconv.Map(m1), m1) + gtest.Assert(gconv.Map(m2), m2) + gtest.Assert(gconv.Map(m3), m3) + }) +} diff --git a/g/util/gconv/gconv_z_unit_slice_test.go b/g/util/gconv/gconv_z_unit_slice_test.go new file mode 100644 index 000000000..e27062295 --- /dev/null +++ b/g/util/gconv/gconv_z_unit_slice_test.go @@ -0,0 +1,25 @@ +// Copyright 2018 gf Author(https://gitee.com/johng/gf). 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://gitee.com/johng/gf. + +package gconv_test + +import ( + "gitee.com/johng/gf/g/util/gconv" + "gitee.com/johng/gf/g/util/gtest" + "testing" +) + + +func Test_Slice(t *testing.T) { + gtest.Case(t, func() { + value := 123.456 + gtest.AssertEQ(gconv.Bytes("123"), []byte("123")) + gtest.AssertEQ(gconv.Strings(value), []string{"123.456"}) + gtest.AssertEQ(gconv.Ints(value), []int{123}) + gtest.AssertEQ(gconv.Floats(value), []float64{123.456}) + gtest.AssertEQ(gconv.Interfaces(value), []interface{}{123.456}) + }) +} diff --git a/g/util/gconv/gconv_z_unit_struct_test.go b/g/util/gconv/gconv_z_unit_struct_test.go index 86ff3cb2b..31b87597b 100644 --- a/g/util/gconv/gconv_z_unit_struct_test.go +++ b/g/util/gconv/gconv_z_unit_struct_test.go @@ -14,7 +14,7 @@ import ( ) -func Test_Struct_Basic(t *testing.T) { +func Test_Struct_Basic1(t *testing.T) { gtest.Case(t, func() { type User struct { Uid int @@ -70,3 +70,247 @@ func Test_Struct_Basic(t *testing.T) { }) }) } + +// 使用默认映射规则绑定属性值到对象 +func Test_Struct_Basic2(t *testing.T) { + gtest.Case(t, func() { + type User struct { + Uid int + Name string + SiteUrl string + Pass1 string + Pass2 string + + } + user := new(User) + params := g.Map { + "uid" : 1, + "Name" : "john", + "site_url" : "https://gfer.me", + "PASS1" : "123", + "PASS2" : "456", + } + if err := gconv.Struct(params, user); err != nil { + gtest.Error(err) + } + gtest.Assert(user, &User{ + Uid : 1, + Name : "john", + SiteUrl : "https://gfer.me", + Pass1 : "123", + Pass2 : "456", + }) + }) +} + +// slice类型属性的赋值 +func Test_Struct_Attr_Slice(t *testing.T) { + gtest.Case(t, func() { + type User struct { + Scores []int + } + + user := new(User) + scores := []interface{}{99, 100, 60, 140} + + // 通过map映射转换 + if err := gconv.Struct(g.Map{"Scores" : scores}, user); err != nil { + gtest.Error(err) + } else { + gtest.Assert(user, &User{ + Scores : []int{99, 100, 60, 140}, + }) + } + + // 通过变量映射转换,直接slice赋值 + if err := gconv.Struct(scores, user); err != nil { + gtest.Error(err) + } else { + gtest.Assert(user, &User{ + Scores : []int{99, 100, 60, 140}, + }) + } + }) +} + +// 属性为struct对象 +func Test_Struct_Attr_Struct(t *testing.T) { + gtest.Case(t, func() { + type Score struct { + Name string + Result int + } + type User struct { + Scores Score + } + + user := new(User) + scores := map[string]interface{}{ + "Scores" : map[string]interface{}{ + "Name" : "john", + "Result" : 100, + }, + } + + // 嵌套struct转换 + if err := gconv.Struct(scores, user); err != nil { + gtest.Error(err) + } else { + gtest.Assert(user, &User{ + Scores : Score { + Name : "john", + Result : 100, + }, + }) + } + }) +} + +// 属性为struct对象指针 +func Test_Struct_Attr_Struct_Ptr(t *testing.T) { + gtest.Case(t, func() { + type Score struct { + Name string + Result int + } + type User struct { + Scores *Score + } + + user := new(User) + scores := map[string]interface{}{ + "Scores" : map[string]interface{}{ + "Name" : "john", + "Result" : 100, + }, + } + + // 嵌套struct转换 + if err := gconv.Struct(scores, user); err != nil { + gtest.Error(err) + } else { + gtest.Assert(user.Scores, &Score { + Name : "john", + Result : 100, + }) + } + }) +} + +// 属性为struct对象slice +func Test_Struct_Attr_Struct_Slice1(t *testing.T) { + gtest.Case(t, func() { + type Score struct { + Name string + Result int + } + type User struct { + Scores []Score + } + + user := new(User) + scores := map[string]interface{}{ + "Scores" : map[string]interface{}{ + "Name" : "john", + "Result" : 100, + }, + } + + // 嵌套struct转换,属性为slice类型,数值为map类型 + if err := gconv.Struct(scores, user); err != nil { + gtest.Error(err) + } else { + gtest.Assert(user.Scores, []Score { + { + Name : "john", + Result : 100, + }, + }) + } + }) +} + +// 属性为struct对象slice +func Test_Struct_Attr_Struct_Slice2(t *testing.T) { + gtest.Case(t, func() { + type Score struct { + Name string + Result int + } + type User struct { + Scores []Score + } + + user := new(User) + scores := map[string]interface{}{ + "Scores" : []interface{}{ + map[string]interface{}{ + "Name" : "john", + "Result" : 100, + }, + map[string]interface{}{ + "Name" : "smith", + "Result" : 60, + }, + }, + } + + // 嵌套struct转换,属性为slice类型,数值为slice map类型 + if err := gconv.Struct(scores, user); err != nil { + gtest.Error(err) + } else { + gtest.Assert(user.Scores, []Score { + { + Name : "john", + Result : 100, + }, + { + Name : "smith", + Result : 60, + }, + }) + } + }) +} + +// 属性为struct对象slice ptr +func Test_Struct_Attr_Struct_Slice_Ptr(t *testing.T) { + gtest.Case(t, func() { + type Score struct { + Name string + Result int + } + type User struct { + Scores []*Score + } + + user := new(User) + scores := map[string]interface{}{ + "Scores" : []interface{}{ + map[string]interface{}{ + "Name" : "john", + "Result" : 100, + }, + map[string]interface{}{ + "Name" : "smith", + "Result" : 60, + }, + }, + } + + // 嵌套struct转换,属性为slice类型,数值为slice map类型 + if err := gconv.Struct(scores, user); err != nil { + gtest.Error(err) + } else { + gtest.Assert(len(user.Scores), 2) + gtest.Assert(user.Scores[0], &Score { + Name : "john", + Result : 100, + }) + gtest.Assert(user.Scores[1], &Score { + Name : "smith", + Result : 60, + }) + } + }) +} diff --git a/g/util/gconv/gconv_z_unit_time_test.go b/g/util/gconv/gconv_z_unit_time_test.go new file mode 100644 index 000000000..7234a1990 --- /dev/null +++ b/g/util/gconv/gconv_z_unit_time_test.go @@ -0,0 +1,25 @@ +// Copyright 2018 gf Author(https://gitee.com/johng/gf). 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://gitee.com/johng/gf. + +package gconv_test + +import ( + "gitee.com/johng/gf/g/os/gtime" + "gitee.com/johng/gf/g/util/gconv" + "gitee.com/johng/gf/g/util/gtest" + "testing" + "time" +) + + +func Test_Time(t *testing.T) { + gtest.Case(t, func() { + t1 := "2011-10-10 01:02:03.456" + gtest.AssertEQ(gconv.GTime(t1), gtime.NewFromStr(t1)) + gtest.AssertEQ(gconv.Time(t1), gtime.NewFromStr(t1).Time) + gtest.AssertEQ(gconv.TimeDuration(100), 100*time.Nanosecond) + }) +} diff --git a/g/util/gtest/gtest.go b/g/util/gtest/gtest.go index 1847e6463..ff02abd8c 100644 --- a/g/util/gtest/gtest.go +++ b/g/util/gtest/gtest.go @@ -41,8 +41,14 @@ func Assert(value, expect interface{}) { } } -// 断言判断, 相等 +// 断言判断, 相等, 包括数据类型 func AssertEQ(value, expect interface{}) { + // 类型判断 + t1 := reflect.TypeOf(value) + t2 := reflect.TypeOf(expect) + if t1 != t2 { + panic(fmt.Sprintf(`[ASSERT] EXPECT TYPE %v == %v`, t1, t2)) + } rv := reflect.ValueOf(value) if rv.Kind() == reflect.Ptr { if rv.IsNil() {