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  }