github.com/wangyougui/gf/v2@v2.6.5/os/gstructs/gstructs_z_unit_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/wangyougui/gf. 6 7 package gstructs_test 8 9 import ( 10 "testing" 11 12 "github.com/wangyougui/gf/v2/frame/g" 13 "github.com/wangyougui/gf/v2/os/gstructs" 14 "github.com/wangyougui/gf/v2/test/gtest" 15 ) 16 17 func Test_Basic(t *testing.T) { 18 gtest.C(t, func(t *gtest.T) { 19 type User struct { 20 Id int 21 Name string `params:"name"` 22 Pass string `my-tag1:"pass1" my-tag2:"pass2" params:"pass"` 23 } 24 var user User 25 m, _ := gstructs.TagMapName(user, []string{"params"}) 26 t.Assert(m, g.Map{"name": "Name", "pass": "Pass"}) 27 m, _ = gstructs.TagMapName(&user, []string{"params"}) 28 t.Assert(m, g.Map{"name": "Name", "pass": "Pass"}) 29 30 m, _ = gstructs.TagMapName(&user, []string{"params", "my-tag1"}) 31 t.Assert(m, g.Map{"name": "Name", "pass": "Pass"}) 32 m, _ = gstructs.TagMapName(&user, []string{"my-tag1", "params"}) 33 t.Assert(m, g.Map{"name": "Name", "pass1": "Pass"}) 34 m, _ = gstructs.TagMapName(&user, []string{"my-tag2", "params"}) 35 t.Assert(m, g.Map{"name": "Name", "pass2": "Pass"}) 36 }) 37 38 gtest.C(t, func(t *gtest.T) { 39 type Base struct { 40 Pass1 string `params:"password1"` 41 Pass2 string `params:"password2"` 42 } 43 type UserWithBase struct { 44 Id int 45 Name string 46 Base `params:"base"` 47 } 48 user := new(UserWithBase) 49 m, _ := gstructs.TagMapName(user, []string{"params"}) 50 t.Assert(m, g.Map{ 51 "base": "Base", 52 "password1": "Pass1", 53 "password2": "Pass2", 54 }) 55 }) 56 57 gtest.C(t, func(t *gtest.T) { 58 type Base struct { 59 Pass1 string `params:"password1"` 60 Pass2 string `params:"password2"` 61 } 62 type UserWithEmbeddedAttribute struct { 63 Id int 64 Name string 65 Base 66 } 67 type UserWithoutEmbeddedAttribute struct { 68 Id int 69 Name string 70 Pass Base 71 } 72 user1 := new(UserWithEmbeddedAttribute) 73 user2 := new(UserWithoutEmbeddedAttribute) 74 m, _ := gstructs.TagMapName(user1, []string{"params"}) 75 t.Assert(m, g.Map{"password1": "Pass1", "password2": "Pass2"}) 76 m, _ = gstructs.TagMapName(user2, []string{"params"}) 77 t.Assert(m, g.Map{}) 78 }) 79 } 80 81 func Test_StructOfNilPointer(t *testing.T) { 82 gtest.C(t, func(t *gtest.T) { 83 type User struct { 84 Id int 85 Name string `params:"name"` 86 Pass string `my-tag1:"pass1" my-tag2:"pass2" params:"pass"` 87 } 88 var user *User 89 m, _ := gstructs.TagMapName(user, []string{"params"}) 90 t.Assert(m, g.Map{"name": "Name", "pass": "Pass"}) 91 m, _ = gstructs.TagMapName(&user, []string{"params"}) 92 t.Assert(m, g.Map{"name": "Name", "pass": "Pass"}) 93 94 m, _ = gstructs.TagMapName(&user, []string{"params", "my-tag1"}) 95 t.Assert(m, g.Map{"name": "Name", "pass": "Pass"}) 96 m, _ = gstructs.TagMapName(&user, []string{"my-tag1", "params"}) 97 t.Assert(m, g.Map{"name": "Name", "pass1": "Pass"}) 98 m, _ = gstructs.TagMapName(&user, []string{"my-tag2", "params"}) 99 t.Assert(m, g.Map{"name": "Name", "pass2": "Pass"}) 100 }) 101 } 102 103 func Test_Fields(t *testing.T) { 104 gtest.C(t, func(t *gtest.T) { 105 type User struct { 106 Id int 107 Name string `params:"name"` 108 Pass string `my-tag1:"pass1" my-tag2:"pass2" params:"pass"` 109 } 110 var user *User 111 fields, _ := gstructs.Fields(gstructs.FieldsInput{ 112 Pointer: user, 113 RecursiveOption: 0, 114 }) 115 t.Assert(len(fields), 3) 116 t.Assert(fields[0].Name(), "Id") 117 t.Assert(fields[1].Name(), "Name") 118 t.Assert(fields[1].Tag("params"), "name") 119 t.Assert(fields[2].Name(), "Pass") 120 t.Assert(fields[2].Tag("my-tag1"), "pass1") 121 t.Assert(fields[2].Tag("my-tag2"), "pass2") 122 t.Assert(fields[2].Tag("params"), "pass") 123 }) 124 } 125 126 func Test_Fields_WithEmbedded1(t *testing.T) { 127 gtest.C(t, func(t *gtest.T) { 128 type B struct { 129 Name string 130 Age int 131 } 132 type A struct { 133 Site string 134 B // Should be put here to validate its index. 135 Score int64 136 } 137 r, err := gstructs.Fields(gstructs.FieldsInput{ 138 Pointer: new(A), 139 RecursiveOption: gstructs.RecursiveOptionEmbeddedNoTag, 140 }) 141 t.AssertNil(err) 142 t.Assert(len(r), 4) 143 t.Assert(r[0].Name(), `Site`) 144 t.Assert(r[1].Name(), `Name`) 145 t.Assert(r[2].Name(), `Age`) 146 t.Assert(r[3].Name(), `Score`) 147 }) 148 } 149 150 func Test_Fields_WithEmbedded2(t *testing.T) { 151 type MetaNode struct { 152 Id uint `orm:"id,primary" description:""` 153 Capacity string `orm:"capacity" description:"Capacity string"` 154 Allocatable string `orm:"allocatable" description:"Allocatable string"` 155 Status string `orm:"status" description:"Status string"` 156 } 157 type MetaNodeZone struct { 158 Nodes uint 159 Clusters uint 160 Disk uint 161 Cpu uint 162 Memory uint 163 Zone string 164 } 165 166 type MetaNodeItem struct { 167 MetaNode 168 Capacity []MetaNodeZone `dc:"Capacity []MetaNodeZone"` 169 Allocatable []MetaNodeZone `dc:"Allocatable []MetaNodeZone"` 170 } 171 172 gtest.C(t, func(t *gtest.T) { 173 r, err := gstructs.Fields(gstructs.FieldsInput{ 174 Pointer: new(MetaNodeItem), 175 RecursiveOption: gstructs.RecursiveOptionEmbeddedNoTag, 176 }) 177 t.AssertNil(err) 178 t.Assert(len(r), 4) 179 t.Assert(r[0].Name(), `Id`) 180 t.Assert(r[1].Name(), `Capacity`) 181 t.Assert(r[1].TagStr(), `dc:"Capacity []MetaNodeZone"`) 182 t.Assert(r[2].Name(), `Allocatable`) 183 t.Assert(r[2].TagStr(), `dc:"Allocatable []MetaNodeZone"`) 184 t.Assert(r[3].Name(), `Status`) 185 }) 186 } 187 188 // Filter repeated fields when there is embedded struct. 189 func Test_Fields_WithEmbedded_Filter(t *testing.T) { 190 gtest.C(t, func(t *gtest.T) { 191 type B struct { 192 Name string 193 Age int 194 } 195 type A struct { 196 Name string 197 Site string 198 Age string 199 B // Should be put here to validate its index. 200 Score int64 201 } 202 r, err := gstructs.Fields(gstructs.FieldsInput{ 203 Pointer: new(A), 204 RecursiveOption: gstructs.RecursiveOptionEmbeddedNoTag, 205 }) 206 t.AssertNil(err) 207 t.Assert(len(r), 4) 208 t.Assert(r[0].Name(), `Name`) 209 t.Assert(r[1].Name(), `Site`) 210 t.Assert(r[2].Name(), `Age`) 211 t.Assert(r[3].Name(), `Score`) 212 }) 213 } 214 215 func Test_FieldMap(t *testing.T) { 216 gtest.C(t, func(t *gtest.T) { 217 type User struct { 218 Id int 219 Name string `params:"name"` 220 Pass string `my-tag1:"pass1" my-tag2:"pass2" params:"pass"` 221 } 222 var user *User 223 m, _ := gstructs.FieldMap(gstructs.FieldMapInput{ 224 Pointer: user, 225 PriorityTagArray: []string{"params"}, 226 RecursiveOption: gstructs.RecursiveOptionEmbedded, 227 }) 228 t.Assert(len(m), 3) 229 _, ok := m["Id"] 230 t.Assert(ok, true) 231 _, ok = m["Name"] 232 t.Assert(ok, false) 233 _, ok = m["name"] 234 t.Assert(ok, true) 235 _, ok = m["Pass"] 236 t.Assert(ok, false) 237 _, ok = m["pass"] 238 t.Assert(ok, true) 239 }) 240 gtest.C(t, func(t *gtest.T) { 241 type User struct { 242 Id int 243 Name string `params:"name"` 244 Pass string `my-tag1:"pass1" my-tag2:"pass2" params:"pass"` 245 } 246 var user *User 247 m, _ := gstructs.FieldMap(gstructs.FieldMapInput{ 248 Pointer: user, 249 PriorityTagArray: nil, 250 RecursiveOption: gstructs.RecursiveOptionEmbedded, 251 }) 252 t.Assert(len(m), 3) 253 _, ok := m["Id"] 254 t.Assert(ok, true) 255 _, ok = m["Name"] 256 t.Assert(ok, true) 257 _, ok = m["name"] 258 t.Assert(ok, false) 259 _, ok = m["Pass"] 260 t.Assert(ok, true) 261 _, ok = m["pass"] 262 t.Assert(ok, false) 263 }) 264 } 265 266 func Test_StructType(t *testing.T) { 267 gtest.C(t, func(t *gtest.T) { 268 type B struct { 269 Name string 270 } 271 type A struct { 272 B 273 } 274 r, err := gstructs.StructType(new(A)) 275 t.AssertNil(err) 276 t.Assert(r.Signature(), `github.com/wangyougui/gf/v2/os/gstructs_test/gstructs_test.A`) 277 }) 278 gtest.C(t, func(t *gtest.T) { 279 type B struct { 280 Name string 281 } 282 type A struct { 283 B 284 } 285 r, err := gstructs.StructType(new(A).B) 286 t.AssertNil(err) 287 t.Assert(r.Signature(), `github.com/wangyougui/gf/v2/os/gstructs_test/gstructs_test.B`) 288 }) 289 gtest.C(t, func(t *gtest.T) { 290 type B struct { 291 Name string 292 } 293 type A struct { 294 *B 295 } 296 r, err := gstructs.StructType(new(A).B) 297 t.AssertNil(err) 298 t.Assert(r.String(), `gstructs_test.B`) 299 }) 300 // Error. 301 gtest.C(t, func(t *gtest.T) { 302 type B struct { 303 Name string 304 } 305 type A struct { 306 *B 307 Id int 308 } 309 _, err := gstructs.StructType(new(A).Id) 310 t.AssertNE(err, nil) 311 }) 312 } 313 314 func Test_StructTypeBySlice(t *testing.T) { 315 gtest.C(t, func(t *gtest.T) { 316 type B struct { 317 Name string 318 } 319 type A struct { 320 Array []*B 321 } 322 r, err := gstructs.StructType(new(A).Array) 323 t.AssertNil(err) 324 t.Assert(r.Signature(), `github.com/wangyougui/gf/v2/os/gstructs_test/gstructs_test.B`) 325 }) 326 gtest.C(t, func(t *gtest.T) { 327 type B struct { 328 Name string 329 } 330 type A struct { 331 Array []B 332 } 333 r, err := gstructs.StructType(new(A).Array) 334 t.AssertNil(err) 335 t.Assert(r.Signature(), `github.com/wangyougui/gf/v2/os/gstructs_test/gstructs_test.B`) 336 }) 337 gtest.C(t, func(t *gtest.T) { 338 type B struct { 339 Name string 340 } 341 type A struct { 342 Array *[]B 343 } 344 r, err := gstructs.StructType(new(A).Array) 345 t.AssertNil(err) 346 t.Assert(r.Signature(), `github.com/wangyougui/gf/v2/os/gstructs_test/gstructs_test.B`) 347 }) 348 } 349 350 func TestType_FieldKeys(t *testing.T) { 351 gtest.C(t, func(t *gtest.T) { 352 type B struct { 353 Id int 354 Name string 355 } 356 type A struct { 357 Array []*B 358 } 359 r, err := gstructs.StructType(new(A).Array) 360 t.AssertNil(err) 361 t.Assert(r.FieldKeys(), g.Slice{"Id", "Name"}) 362 }) 363 } 364 365 func TestType_TagMap(t *testing.T) { 366 gtest.C(t, func(t *gtest.T) { 367 type A struct { 368 Id int `d:"123" description:"I love gf"` 369 Name string `v:"required" description:"应用Id"` 370 } 371 r, err := gstructs.Fields(gstructs.FieldsInput{ 372 Pointer: new(A), 373 RecursiveOption: 0, 374 }) 375 t.AssertNil(err) 376 377 t.Assert(len(r), 2) 378 t.Assert(r[0].TagMap()["d"], `123`) 379 t.Assert(r[0].TagMap()["description"], `I love gf`) 380 t.Assert(r[1].TagMap()["v"], `required`) 381 t.Assert(r[1].TagMap()["description"], `应用Id`) 382 }) 383 } 384 385 func TestType_TagJsonName(t *testing.T) { 386 gtest.C(t, func(t *gtest.T) { 387 type A struct { 388 Name string `json:"name,omitempty"` 389 } 390 r, err := gstructs.Fields(gstructs.FieldsInput{ 391 Pointer: new(A), 392 RecursiveOption: 0, 393 }) 394 t.AssertNil(err) 395 396 t.Assert(len(r), 1) 397 t.Assert(r[0].TagJsonName(), `name`) 398 }) 399 } 400 401 func TestType_TagDefault(t *testing.T) { 402 gtest.C(t, func(t *gtest.T) { 403 type A struct { 404 Name string `default:"john"` 405 Name2 string `d:"john"` 406 } 407 r, err := gstructs.Fields(gstructs.FieldsInput{ 408 Pointer: new(A), 409 RecursiveOption: 0, 410 }) 411 t.AssertNil(err) 412 413 t.Assert(len(r), 2) 414 t.Assert(r[0].TagDefault(), `john`) 415 t.Assert(r[1].TagDefault(), `john`) 416 }) 417 } 418 419 func TestType_TagParam(t *testing.T) { 420 gtest.C(t, func(t *gtest.T) { 421 type A struct { 422 Name string `param:"name"` 423 Name2 string `p:"name"` 424 } 425 r, err := gstructs.Fields(gstructs.FieldsInput{ 426 Pointer: new(A), 427 RecursiveOption: 0, 428 }) 429 t.AssertNil(err) 430 431 t.Assert(len(r), 2) 432 t.Assert(r[0].TagParam(), `name`) 433 t.Assert(r[1].TagParam(), `name`) 434 }) 435 } 436 437 func TestType_TagValid(t *testing.T) { 438 gtest.C(t, func(t *gtest.T) { 439 type A struct { 440 Name string `valid:"required"` 441 Name2 string `v:"required"` 442 } 443 r, err := gstructs.Fields(gstructs.FieldsInput{ 444 Pointer: new(A), 445 RecursiveOption: 0, 446 }) 447 t.AssertNil(err) 448 449 t.Assert(len(r), 2) 450 t.Assert(r[0].TagValid(), `required`) 451 t.Assert(r[1].TagValid(), `required`) 452 }) 453 } 454 455 func TestType_TagDescription(t *testing.T) { 456 gtest.C(t, func(t *gtest.T) { 457 type A struct { 458 Name string `description:"my name"` 459 Name2 string `des:"my name"` 460 Name3 string `dc:"my name"` 461 } 462 r, err := gstructs.Fields(gstructs.FieldsInput{ 463 Pointer: new(A), 464 RecursiveOption: 0, 465 }) 466 t.AssertNil(err) 467 468 t.Assert(len(r), 3) 469 t.Assert(r[0].TagDescription(), `my name`) 470 t.Assert(r[1].TagDescription(), `my name`) 471 t.Assert(r[2].TagDescription(), `my name`) 472 }) 473 } 474 475 func TestType_TagSummary(t *testing.T) { 476 gtest.C(t, func(t *gtest.T) { 477 type A struct { 478 Name string `summary:"my name"` 479 Name2 string `sum:"my name"` 480 Name3 string `sm:"my name"` 481 } 482 r, err := gstructs.Fields(gstructs.FieldsInput{ 483 Pointer: new(A), 484 RecursiveOption: 0, 485 }) 486 t.AssertNil(err) 487 488 t.Assert(len(r), 3) 489 t.Assert(r[0].TagSummary(), `my name`) 490 t.Assert(r[1].TagSummary(), `my name`) 491 t.Assert(r[2].TagSummary(), `my name`) 492 }) 493 } 494 495 func TestType_TagAdditional(t *testing.T) { 496 gtest.C(t, func(t *gtest.T) { 497 type A struct { 498 Name string `additional:"my name"` 499 Name2 string `ad:"my name"` 500 } 501 r, err := gstructs.Fields(gstructs.FieldsInput{ 502 Pointer: new(A), 503 RecursiveOption: 0, 504 }) 505 t.AssertNil(err) 506 507 t.Assert(len(r), 2) 508 t.Assert(r[0].TagAdditional(), `my name`) 509 t.Assert(r[1].TagAdditional(), `my name`) 510 }) 511 } 512 513 func TestType_TagExample(t *testing.T) { 514 gtest.C(t, func(t *gtest.T) { 515 type A struct { 516 Name string `example:"john"` 517 Name2 string `eg:"john"` 518 } 519 r, err := gstructs.Fields(gstructs.FieldsInput{ 520 Pointer: new(A), 521 RecursiveOption: 0, 522 }) 523 t.AssertNil(err) 524 525 t.Assert(len(r), 2) 526 t.Assert(r[0].TagExample(), `john`) 527 t.Assert(r[1].TagExample(), `john`) 528 }) 529 } 530 531 func Test_Fields_TagPriorityName(t *testing.T) { 532 gtest.C(t, func(t *gtest.T) { 533 type User struct { 534 Name string `gconv:"name_gconv" c:"name_c"` 535 Age uint `p:"name_p" param:"age_param"` 536 Pass string `json:"pass_json"` 537 IsMen bool 538 } 539 var user *User 540 fields, _ := gstructs.Fields(gstructs.FieldsInput{ 541 Pointer: user, 542 RecursiveOption: 0, 543 }) 544 t.Assert(fields[0].TagPriorityName(), "name_gconv") 545 t.Assert(fields[1].TagPriorityName(), "age_param") 546 t.Assert(fields[2].TagPriorityName(), "pass_json") 547 t.Assert(fields[3].TagPriorityName(), "IsMen") 548 }) 549 }