github.com/zhongdalu/gf@v1.0.0/g/util/gconv/gconv_z_unit_struct_test.go (about) 1 // Copyright 2018 gf Author(https://github.com/zhongdalu/gf). 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/zhongdalu/gf. 6 7 package gconv_test 8 9 import ( 10 "testing" 11 "time" 12 13 "github.com/zhongdalu/gf/g" 14 "github.com/zhongdalu/gf/g/os/gtime" 15 "github.com/zhongdalu/gf/g/test/gtest" 16 "github.com/zhongdalu/gf/g/util/gconv" 17 ) 18 19 func Test_Struct_Basic1(t *testing.T) { 20 gtest.Case(t, func() { 21 type User struct { 22 Uid int 23 Name string 24 Site_Url string 25 NickName string 26 Pass1 string `gconv:"password1"` 27 Pass2 string `gconv:"password2"` 28 } 29 // 使用默认映射规则绑定属性值到对象 30 user := new(User) 31 params1 := g.Map{ 32 "uid": 1, 33 "Name": "john", 34 "siteurl": "https://goframe.org", 35 "nick_name": "johng", 36 "PASS1": "123", 37 "PASS2": "456", 38 } 39 if err := gconv.Struct(params1, user); err != nil { 40 gtest.Error(err) 41 } 42 gtest.Assert(user, &User{ 43 Uid: 1, 44 Name: "john", 45 Site_Url: "https://goframe.org", 46 NickName: "johng", 47 Pass1: "123", 48 Pass2: "456", 49 }) 50 51 // 使用struct tag映射绑定属性值到对象 52 user = new(User) 53 params2 := g.Map{ 54 "uid": 2, 55 "name": "smith", 56 "site-url": "https://goframe.org", 57 "nick name": "johng", 58 "password1": "111", 59 "password2": "222", 60 } 61 if err := gconv.Struct(params2, user); err != nil { 62 gtest.Error(err) 63 } 64 gtest.Assert(user, &User{ 65 Uid: 2, 66 Name: "smith", 67 Site_Url: "https://goframe.org", 68 NickName: "johng", 69 Pass1: "111", 70 Pass2: "222", 71 }) 72 }) 73 } 74 75 // 使用默认映射规则绑定属性值到对象 76 func Test_Struct_Basic2(t *testing.T) { 77 gtest.Case(t, func() { 78 type User struct { 79 Uid int 80 Name string 81 SiteUrl string 82 Pass1 string 83 Pass2 string 84 } 85 user := new(User) 86 params := g.Map{ 87 "uid": 1, 88 "Name": "john", 89 "site_url": "https://goframe.org", 90 "PASS1": "123", 91 "PASS2": "456", 92 } 93 if err := gconv.Struct(params, user); err != nil { 94 gtest.Error(err) 95 } 96 gtest.Assert(user, &User{ 97 Uid: 1, 98 Name: "john", 99 SiteUrl: "https://goframe.org", 100 Pass1: "123", 101 Pass2: "456", 102 }) 103 }) 104 } 105 106 // 带有指针的基础类型属性 107 func Test_Struct_Basic3(t *testing.T) { 108 gtest.Case(t, func() { 109 type User struct { 110 Uid int 111 Name *string 112 } 113 user := new(User) 114 params := g.Map{ 115 "uid": 1, 116 "Name": "john", 117 } 118 if err := gconv.Struct(params, user); err != nil { 119 gtest.Error(err) 120 } 121 gtest.Assert(user.Uid, 1) 122 gtest.Assert(*user.Name, "john") 123 }) 124 } 125 126 // slice类型属性的赋值 127 func Test_Struct_Attr_Slice(t *testing.T) { 128 gtest.Case(t, func() { 129 type User struct { 130 Scores []int 131 } 132 scores := []interface{}{99, 100, 60, 140} 133 user := new(User) 134 if err := gconv.Struct(g.Map{"Scores": scores}, user); err != nil { 135 gtest.Error(err) 136 } else { 137 gtest.Assert(user, &User{ 138 Scores: []int{99, 100, 60, 140}, 139 }) 140 } 141 }) 142 } 143 144 // 属性为struct对象 145 func Test_Struct_Attr_Struct(t *testing.T) { 146 gtest.Case(t, func() { 147 type Score struct { 148 Name string 149 Result int 150 } 151 type User struct { 152 Scores Score 153 } 154 155 user := new(User) 156 scores := map[string]interface{}{ 157 "Scores": map[string]interface{}{ 158 "Name": "john", 159 "Result": 100, 160 }, 161 } 162 163 // 嵌套struct转换 164 if err := gconv.Struct(scores, user); err != nil { 165 gtest.Error(err) 166 } else { 167 gtest.Assert(user, &User{ 168 Scores: Score{ 169 Name: "john", 170 Result: 100, 171 }, 172 }) 173 } 174 }) 175 } 176 177 // 属性为struct对象指针 178 func Test_Struct_Attr_Struct_Ptr(t *testing.T) { 179 gtest.Case(t, func() { 180 type Score struct { 181 Name string 182 Result int 183 } 184 type User struct { 185 Scores *Score 186 } 187 188 user := new(User) 189 scores := map[string]interface{}{ 190 "Scores": map[string]interface{}{ 191 "Name": "john", 192 "Result": 100, 193 }, 194 } 195 196 // 嵌套struct转换 197 if err := gconv.Struct(scores, user); err != nil { 198 gtest.Error(err) 199 } else { 200 gtest.Assert(user.Scores, &Score{ 201 Name: "john", 202 Result: 100, 203 }) 204 } 205 }) 206 } 207 208 // 属性为struct对象slice 209 func Test_Struct_Attr_Struct_Slice1(t *testing.T) { 210 gtest.Case(t, func() { 211 type Score struct { 212 Name string 213 Result int 214 } 215 type User struct { 216 Scores []Score 217 } 218 219 user := new(User) 220 scores := map[string]interface{}{ 221 "Scores": map[string]interface{}{ 222 "Name": "john", 223 "Result": 100, 224 }, 225 } 226 227 // 嵌套struct转换,属性为slice类型,数值为map类型 228 if err := gconv.Struct(scores, user); err != nil { 229 gtest.Error(err) 230 } else { 231 gtest.Assert(user.Scores, []Score{ 232 { 233 Name: "john", 234 Result: 100, 235 }, 236 }) 237 } 238 }) 239 } 240 241 // 属性为struct对象slice 242 func Test_Struct_Attr_Struct_Slice2(t *testing.T) { 243 gtest.Case(t, func() { 244 type Score struct { 245 Name string 246 Result int 247 } 248 type User struct { 249 Scores []Score 250 } 251 252 user := new(User) 253 scores := map[string]interface{}{ 254 "Scores": []interface{}{ 255 map[string]interface{}{ 256 "Name": "john", 257 "Result": 100, 258 }, 259 map[string]interface{}{ 260 "Name": "smith", 261 "Result": 60, 262 }, 263 }, 264 } 265 266 // 嵌套struct转换,属性为slice类型,数值为slice map类型 267 if err := gconv.Struct(scores, user); err != nil { 268 gtest.Error(err) 269 } else { 270 gtest.Assert(user.Scores, []Score{ 271 { 272 Name: "john", 273 Result: 100, 274 }, 275 { 276 Name: "smith", 277 Result: 60, 278 }, 279 }) 280 } 281 }) 282 } 283 284 // 属性为struct对象slice ptr 285 func Test_Struct_Attr_Struct_Slice_Ptr(t *testing.T) { 286 gtest.Case(t, func() { 287 type Score struct { 288 Name string 289 Result int 290 } 291 type User struct { 292 Scores []*Score 293 } 294 295 user := new(User) 296 scores := map[string]interface{}{ 297 "Scores": []interface{}{ 298 map[string]interface{}{ 299 "Name": "john", 300 "Result": 100, 301 }, 302 map[string]interface{}{ 303 "Name": "smith", 304 "Result": 60, 305 }, 306 }, 307 } 308 309 // 嵌套struct转换,属性为slice类型,数值为slice map类型 310 if err := gconv.Struct(scores, user); err != nil { 311 gtest.Error(err) 312 } else { 313 gtest.Assert(len(user.Scores), 2) 314 gtest.Assert(user.Scores[0], &Score{ 315 Name: "john", 316 Result: 100, 317 }) 318 gtest.Assert(user.Scores[1], &Score{ 319 Name: "smith", 320 Result: 60, 321 }) 322 } 323 }) 324 } 325 326 func Test_Struct_PrivateAttribute(t *testing.T) { 327 type User struct { 328 Id int 329 name string 330 } 331 gtest.Case(t, func() { 332 user := new(User) 333 err := gconv.Struct(g.Map{"id": 1, "name": "john"}, user) 334 gtest.Assert(err, nil) 335 gtest.Assert(user.Id, 1) 336 gtest.Assert(user.name, "") 337 }) 338 } 339 340 func Test_Struct_Deep(t *testing.T) { 341 342 gtest.Case(t, func() { 343 type Base struct { 344 Age int 345 } 346 type User struct { 347 Id int 348 Name string 349 Base 350 } 351 user := new(User) 352 params := g.Map{ 353 "id": 1, 354 "name": "john", 355 "age": 18, 356 } 357 err := gconv.StructDeep(params, user) 358 gtest.Assert(err, nil) 359 gtest.Assert(user.Id, params["id"]) 360 gtest.Assert(user.Name, params["name"]) 361 gtest.Assert(user.Age, params["age"]) 362 }) 363 364 gtest.Case(t, func() { 365 type Ids struct { 366 Id int `json:"id"` 367 Uid int `json:"uid"` 368 } 369 type Base struct { 370 Ids 371 CreateTime string `json:"create_time"` 372 } 373 type User struct { 374 Base 375 Passport string `json:"passport"` 376 Password string `json:"password"` 377 Nickname string `json:"nickname"` 378 } 379 data := g.Map{ 380 "id": 100, 381 "uid": 101, 382 "passport": "t1", 383 "password": "123456", 384 "nickname": "T1", 385 "create_time": "2019", 386 } 387 user := new(User) 388 err := gconv.StructDeep(data, user) 389 gtest.Assert(err, nil) 390 gtest.Assert(user.Id, 100) 391 gtest.Assert(user.Uid, 101) 392 gtest.Assert(user.Nickname, "T1") 393 gtest.Assert(user.CreateTime, "2019") 394 }) 395 } 396 397 func Test_Struct_Time(t *testing.T) { 398 gtest.Case(t, func() { 399 type User struct { 400 CreateTime time.Time 401 } 402 now := time.Now() 403 user := new(User) 404 gconv.Struct(g.Map{ 405 "create_time": now, 406 }, user) 407 gtest.Assert(user.CreateTime.UTC().String(), now.UTC().String()) 408 }) 409 410 gtest.Case(t, func() { 411 type User struct { 412 CreateTime *time.Time 413 } 414 now := time.Now() 415 user := new(User) 416 gconv.Struct(g.Map{ 417 "create_time": &now, 418 }, user) 419 gtest.Assert(user.CreateTime.UTC().String(), now.UTC().String()) 420 }) 421 422 gtest.Case(t, func() { 423 type User struct { 424 CreateTime *gtime.Time 425 } 426 now := time.Now() 427 user := new(User) 428 gconv.Struct(g.Map{ 429 "create_time": &now, 430 }, user) 431 gtest.Assert(user.CreateTime.Time.UTC().String(), now.UTC().String()) 432 }) 433 434 gtest.Case(t, func() { 435 type User struct { 436 CreateTime gtime.Time 437 } 438 now := time.Now() 439 user := new(User) 440 gconv.Struct(g.Map{ 441 "create_time": &now, 442 }, user) 443 gtest.Assert(user.CreateTime.Time.UTC().String(), now.UTC().String()) 444 }) 445 446 gtest.Case(t, func() { 447 type User struct { 448 CreateTime gtime.Time 449 } 450 now := time.Now() 451 user := new(User) 452 gconv.Struct(g.Map{ 453 "create_time": now, 454 }, user) 455 gtest.Assert(user.CreateTime.Time.UTC().String(), now.UTC().String()) 456 }) 457 } 458 459 // Auto create struct when given pointer. 460 func Test_Struct_Create(t *testing.T) { 461 gtest.Case(t, func() { 462 type User struct { 463 Uid int 464 Name string 465 } 466 user := (*User)(nil) 467 params := g.Map{ 468 "uid": 1, 469 "Name": "john", 470 } 471 err := gconv.Struct(params, &user) 472 gtest.Assert(err, nil) 473 gtest.Assert(user.Uid, 1) 474 gtest.Assert(user.Name, "john") 475 }) 476 477 gtest.Case(t, func() { 478 type User struct { 479 Uid int 480 Name string 481 } 482 user := (*User)(nil) 483 params := g.Map{ 484 "uid": 1, 485 "Name": "john", 486 } 487 err := gconv.Struct(params, user) 488 gtest.AssertNE(err, nil) 489 gtest.Assert(user, nil) 490 }) 491 492 }