github.com/gogf/gf/v2@v2.7.4/util/gconv/gconv_z_unit_struct_test.go (about) 1 // Copyright GoFrame Author(https://goframe.org). All Rights Reserved. 2 // 3 // This Source Code Form is subject to the terms of the MIT License. 4 // If a copy of the MIT was not distributed with this file, 5 // You can obtain one at https://github.com/gogf/gf. 6 7 package gconv_test 8 9 import ( 10 "strconv" 11 "testing" 12 "time" 13 14 "github.com/gogf/gf/v2/frame/g" 15 "github.com/gogf/gf/v2/os/gtime" 16 "github.com/gogf/gf/v2/test/gtest" 17 "github.com/gogf/gf/v2/util/gconv" 18 ) 19 20 type structExpect struct { 21 PlanetName string 22 Planet_Place string 23 planetTime string 24 } 25 26 type structTagGconvExpect struct { 27 PlanetNameGconv string `gconv:"PlanetName"` 28 PlanetPlaceGconv string `gconv:"-"` 29 } 30 type structTagParamExpect struct { 31 PlanetNameParam string `param:"PlanetName"` 32 PlanetPlaceParam string `param:"-"` 33 } 34 type structTagCExpect struct { 35 PlanetNameC string `c:"PlanetName"` 36 PlanetPlaceC string `c:"-"` 37 } 38 type structTagPExpect struct { 39 PlanetNameP string `p:"PlanetName"` 40 PlanetPlaceP string `p:"-"` 41 } 42 type structTagJsonExpect struct { 43 PlanetNameJson string `json:"PlanetName"` 44 PlanetPlaceJson string `json:"-"` 45 } 46 47 var structValueTests = []map[string]string{ 48 { 49 "planetname": "Earth", 50 "planetplace": "亚马逊雨林", 51 "planettime": "2021-01-01", 52 }, 53 { 54 "planetName": "Earth", 55 "planetPlace": "亚马逊雨林", 56 "planetTime": "2021-01-01", 57 }, 58 { 59 "planet-name": "Earth", 60 "planet-place": "亚马逊雨林", 61 "planet-time": "2021-01-01", 62 }, 63 { 64 "planet_name": "Earth", 65 "planet_place": "亚马逊雨林", 66 "planet_time": "2021-01-01", 67 }, 68 { 69 "planet name": "Earth", 70 "planet place": "亚马逊雨林", 71 "planet time": "2021-01-01", 72 }, 73 { 74 "PLANETNAME": "Earth", 75 "PLANETPLACE": "亚马逊雨林", 76 "PLANETTIME": "2021-01-01", 77 }, 78 { 79 "PLANETnAME": "Earth", 80 "PLANETpLACE": "亚马逊雨林", 81 "PLANETtIME": "2021-01-01", 82 }, 83 { 84 "PLANET-NAME": "Earth", 85 "PLANET-PLACE": "亚马逊雨林", 86 "PLANET-TIME": "2021-01-01", 87 }, 88 { 89 "PLANET_NAME": "Earth", 90 "PLANET_PLACE": "亚马逊雨林", 91 "PLANET_TIME": "2021-01-01", 92 }, 93 { 94 "PLANET NAME": "Earth", 95 "PLANET PLACE": "亚马逊雨林", 96 "PLANET TIME": "2021-01-01", 97 }, 98 { 99 "PlanetName": "Earth", 100 "PlanetPlace": "亚马逊雨林", 101 "PlanetTime": "2021-01-01", 102 }, 103 { 104 "Planet-Name": "Earth", 105 "Planet-Place": "亚马逊雨林", 106 "Planet-Time": "2021-01-01", 107 }, 108 { 109 "Planet_Name": "Earth", 110 "Planet_Place": "亚马逊雨林", 111 "Planet_Time": "2021-01-01", 112 }, 113 { 114 "Planet Name": "Earth", 115 "Planet Place": "亚马逊雨林", 116 "Planet Time": "2021-01-01", 117 }, 118 } 119 120 func TestStruct(t *testing.T) { 121 gtest.C(t, func(t *gtest.T) { 122 for _, test := range structValueTests { 123 var ( 124 err error 125 expect = new(structExpect) 126 ) 127 err = gconv.Struct(test, expect) 128 t.AssertNil(err) 129 t.Assert(expect.PlanetName, "Earth") 130 t.Assert(expect.Planet_Place, "亚马逊雨林") 131 t.Assert(expect.planetTime, "") 132 133 tagTestValue, ok := test["PlanetName"] 134 if !ok { 135 continue 136 } 137 var ( 138 expectTagGconv = new(structTagGconvExpect) 139 expectTagParam = new(structTagParamExpect) 140 expectTagC = new(structTagCExpect) 141 expectTagP = new(structTagPExpect) 142 expectTagJson = new(structTagJsonExpect) 143 ) 144 err = gconv.Struct(test, expectTagGconv) 145 t.AssertNil(err) 146 t.Assert(expectTagGconv.PlanetNameGconv, tagTestValue) 147 t.Assert(expectTagGconv.PlanetPlaceGconv, "") 148 149 err = gconv.Struct(test, expectTagParam) 150 t.AssertNil(err) 151 t.Assert(expectTagParam.PlanetNameParam, tagTestValue) 152 t.Assert(expectTagParam.PlanetPlaceParam, "") 153 154 err = gconv.Struct(test, expectTagC) 155 t.AssertNil(err) 156 t.Assert(expectTagC.PlanetNameC, tagTestValue) 157 t.Assert(expectTagC.PlanetPlaceC, "") 158 159 err = gconv.Struct(test, expectTagP) 160 t.AssertNil(err) 161 t.Assert(expectTagP.PlanetNameP, tagTestValue) 162 t.Assert(expectTagP.PlanetPlaceP, "") 163 164 err = gconv.Struct(test, expectTagJson) 165 t.AssertNil(err) 166 t.Assert(expectTagJson.PlanetNameJson, tagTestValue) 167 t.Assert(expectTagJson.PlanetPlaceJson, "") 168 } 169 }) 170 171 // Test for nil. 172 gtest.C(t, func(t *gtest.T) { 173 var ( 174 err error 175 expect = new(structExpect) 176 ) 177 178 err = gconv.Struct(nil, nil) 179 t.AssertNil(err) 180 t.Assert(expect.PlanetName, "") 181 t.Assert(expect.Planet_Place, "") 182 t.Assert(expect.planetTime, "") 183 }) 184 } 185 186 func TestStructDuplicateField(t *testing.T) { 187 gtest.C(t, func(t *gtest.T) { 188 m := map[string]any{ 189 "ID": 100, 190 } 191 type Nested1 struct { 192 ID string 193 } 194 type Nested2 struct { 195 ID uint 196 } 197 type Nested3 struct { 198 ID int 199 } 200 type Dest struct { 201 ID int 202 Nested1 203 Nested2 204 Nested3 205 } 206 var ( 207 err error 208 dest = new(Dest) 209 ) 210 err = gconv.Struct(m, dest) 211 t.AssertNil(err) 212 t.Assert(dest.ID, m["ID"]) 213 t.Assert(dest.Nested1.ID, strconv.Itoa(m["ID"].(int))) 214 t.Assert(dest.Nested2.ID, m["ID"]) 215 t.Assert(dest.Nested3.ID, m["ID"]) 216 }) 217 } 218 219 func TestStructErr(t *testing.T) { 220 gtest.C(t, func(t *gtest.T) { 221 type Score struct { 222 Name string 223 Result int 224 } 225 type User struct { 226 Score Score 227 } 228 229 user := new(User) 230 scores := map[string]interface{}{ 231 "Score": 1, 232 } 233 err := gconv.Struct(scores, user) 234 t.AssertNE(err, nil) 235 }) 236 237 gtest.C(t, func(t *gtest.T) { 238 type CustomString string 239 type CustomStruct struct { 240 S string 241 } 242 var ( 243 a CustomString = "abc" 244 b *CustomStruct 245 ) 246 err := gconv.Scan(a, &b) 247 t.AssertNE(err, nil) 248 t.Assert(b, nil) 249 }) 250 251 gtest.C(t, func(t *gtest.T) { 252 var i *int = nil 253 err := gconv.Struct(map[string]string{}, i) 254 t.AssertNE(err, nil) 255 }) 256 } 257 258 // Test for Struct containing time.Time attribute. 259 func TestStructWithTime(t *testing.T) { 260 gtest.C(t, func(t *gtest.T) { 261 type S struct { 262 T *gtime.Time 263 } 264 var ( 265 err error 266 now = time.Now() 267 s = new(S) 268 ) 269 err = gconv.Struct(g.Map{ 270 "t": &now, 271 }, s) 272 t.AssertNil(err) 273 t.Assert(s.T.UTC().Time.String(), now.UTC().String()) 274 }) 275 } 276 277 func TestStructs(t *testing.T) { 278 gtest.C(t, func(t *gtest.T) { 279 for _, test := range structValueTests { 280 var ( 281 err error 282 tests = []map[string]string{test, test} 283 expects []*structExpect 284 ) 285 err = gconv.SliceStruct(tests, &expects) 286 t.AssertNil(err) 287 t.Assert(len(expects), 2) 288 for _, expect := range expects { 289 t.Assert(expect.PlanetName, "Earth") 290 t.Assert(expect.Planet_Place, "亚马逊雨林") 291 t.Assert(expect.planetTime, "") 292 } 293 294 tagTestValue, ok := test["PlanetName"] 295 if !ok { 296 continue 297 } 298 var ( 299 expectTagGconvs = []*structTagGconvExpect{} 300 expectTagParams = []*structTagParamExpect{} 301 expectTagCs = []*structTagCExpect{} 302 expectTagPs = []*structTagPExpect{} 303 expectTagJsons = []*structTagJsonExpect{} 304 ) 305 306 err = gconv.SliceStruct(tests, &expectTagGconvs) 307 t.AssertNil(err) 308 t.Assert(len(expectTagGconvs), 2) 309 for _, expect := range expectTagGconvs { 310 t.Assert(expect.PlanetNameGconv, tagTestValue) 311 t.Assert(expect.PlanetPlaceGconv, "") 312 } 313 314 err = gconv.SliceStruct(tests, &expectTagParams) 315 t.AssertNil(err) 316 t.Assert(len(expectTagParams), 2) 317 for _, expect := range expectTagParams { 318 t.Assert(expect.PlanetNameParam, tagTestValue) 319 t.Assert(expect.PlanetPlaceParam, "") 320 } 321 322 err = gconv.SliceStruct(tests, &expectTagCs) 323 t.AssertNil(err) 324 t.Assert(len(expectTagCs), 2) 325 for _, expect := range expectTagCs { 326 t.Assert(expect.PlanetNameC, tagTestValue) 327 t.Assert(expect.PlanetPlaceC, "") 328 } 329 330 err = gconv.SliceStruct(tests, &expectTagPs) 331 t.AssertNil(err) 332 t.Assert(len(expectTagPs), 2) 333 for _, expect := range expectTagPs { 334 t.Assert(expect.PlanetNameP, tagTestValue) 335 t.Assert(expect.PlanetPlaceP, "") 336 } 337 338 err = gconv.SliceStruct(tests, &expectTagJsons) 339 t.AssertNil(err) 340 t.Assert(len(expectTagJsons), 2) 341 for _, expect := range expectTagJsons { 342 t.Assert(expect.PlanetNameJson, tagTestValue) 343 t.Assert(expect.PlanetPlaceJson, "") 344 } 345 } 346 }) 347 }