github.com/wangyougui/gf/v2@v2.6.5/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/wangyougui/gf.
     6  
     7  package gconv_test
     8  
     9  import (
    10  	"testing"
    11  	"time"
    12  
    13  	"github.com/wangyougui/gf/v2/container/gvar"
    14  	"github.com/wangyougui/gf/v2/encoding/gjson"
    15  	"github.com/wangyougui/gf/v2/frame/g"
    16  	"github.com/wangyougui/gf/v2/internal/json"
    17  	"github.com/wangyougui/gf/v2/os/gtime"
    18  	"github.com/wangyougui/gf/v2/test/gtest"
    19  	"github.com/wangyougui/gf/v2/util/gconv"
    20  )
    21  
    22  func Test_Struct_Basic1(t *testing.T) {
    23  	gtest.C(t, func(t *gtest.T) {
    24  		type User struct {
    25  			Uid      int
    26  			Name     string
    27  			Site_Url string
    28  			NickName string
    29  			Pass1    string `gconv:"password1"`
    30  			Pass2    string `gconv:"password2"`
    31  		}
    32  		user := new(User)
    33  		params1 := g.Map{
    34  			"uid":       1,
    35  			"Name":      "john",
    36  			"siteurl":   "https://goframe.org",
    37  			"nick_name": "johng",
    38  			"PASS1":     "123",
    39  			"PASS2":     "456",
    40  		}
    41  		if err := gconv.Struct(params1, user); err != nil {
    42  			t.Error(err)
    43  		}
    44  		t.Assert(user, &User{
    45  			Uid:      1,
    46  			Name:     "john",
    47  			Site_Url: "https://goframe.org",
    48  			NickName: "johng",
    49  			Pass1:    "123",
    50  			Pass2:    "456",
    51  		})
    52  
    53  		user = new(User)
    54  		params2 := g.Map{
    55  			"uid":       2,
    56  			"name":      "smith",
    57  			"site-url":  "https://goframe.org",
    58  			"nick name": "johng",
    59  			"password1": "111",
    60  			"password2": "222",
    61  		}
    62  		if err := gconv.Struct(params2, user); err != nil {
    63  			t.Error(err)
    64  		}
    65  		t.Assert(user, &User{
    66  			Uid:      2,
    67  			Name:     "smith",
    68  			Site_Url: "https://goframe.org",
    69  			NickName: "johng",
    70  			Pass1:    "111",
    71  			Pass2:    "222",
    72  		})
    73  	})
    74  }
    75  
    76  func Test_Struct_Basic2(t *testing.T) {
    77  	gtest.C(t, func(t *gtest.T) {
    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  			t.Error(err)
    95  		}
    96  		t.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  func Test_Struct_Attr_Pointer(t *testing.T) {
   107  	gtest.C(t, func(t *gtest.T) {
   108  		type User struct {
   109  			Uid  *int
   110  			Name *string
   111  		}
   112  		user := new(User)
   113  		params := g.Map{
   114  			"uid":  "1",
   115  			"Name": "john",
   116  		}
   117  		if err := gconv.Struct(params, user); err != nil {
   118  			t.Error(err)
   119  		}
   120  		t.Assert(user.Uid, 1)
   121  		t.Assert(*user.Name, "john")
   122  	})
   123  }
   124  
   125  func Test_Struct_Attr_Slice1(t *testing.T) {
   126  	gtest.C(t, func(t *gtest.T) {
   127  		type User struct {
   128  			Scores []int
   129  		}
   130  		scores := []interface{}{99, 100, 60, 140}
   131  		user := new(User)
   132  		if err := gconv.Struct(g.Map{"Scores": scores}, user); err != nil {
   133  			t.Error(err)
   134  		} else {
   135  			t.Assert(user, &User{
   136  				Scores: []int{99, 100, 60, 140},
   137  			})
   138  		}
   139  	})
   140  }
   141  
   142  // It does not support this kind of converting yet.
   143  //func Test_Struct_Attr_Slice2(t *testing.T) {
   144  //	gtest.C(t, func(t *gtest.T) {
   145  //		type User struct {
   146  //			Scores [][]int
   147  //		}
   148  //		scores := []interface{}{[]interface{}{99, 100, 60, 140}}
   149  //		user := new(User)
   150  //		if err := gconv.Struct(g.Map{"Scores": scores}, user); err != nil {
   151  //			t.Error(err)
   152  //		} else {
   153  //			t.Assert(user, &User{
   154  //				Scores: [][]int{{99, 100, 60, 140}},
   155  //			})
   156  //		}
   157  //	})
   158  //}
   159  
   160  func Test_Struct_Attr_Struct(t *testing.T) {
   161  	gtest.C(t, func(t *gtest.T) {
   162  		type Score struct {
   163  			Name   string
   164  			Result int
   165  		}
   166  		type User struct {
   167  			Scores Score
   168  		}
   169  
   170  		user := new(User)
   171  		scores := map[string]interface{}{
   172  			"Scores": map[string]interface{}{
   173  				"Name":   "john",
   174  				"Result": 100,
   175  			},
   176  		}
   177  
   178  		// 嵌套struct转换
   179  		if err := gconv.Struct(scores, user); err != nil {
   180  			t.Error(err)
   181  		} else {
   182  			t.Assert(user, &User{
   183  				Scores: Score{
   184  					Name:   "john",
   185  					Result: 100,
   186  				},
   187  			})
   188  		}
   189  	})
   190  }
   191  
   192  func Test_Struct_Attr_Struct_Ptr(t *testing.T) {
   193  	gtest.C(t, func(t *gtest.T) {
   194  		type Score struct {
   195  			Name   string
   196  			Result int
   197  		}
   198  		type User struct {
   199  			Scores *Score
   200  		}
   201  
   202  		user := new(User)
   203  		scores := map[string]interface{}{
   204  			"Scores": map[string]interface{}{
   205  				"Name":   "john",
   206  				"Result": 100,
   207  			},
   208  		}
   209  
   210  		// 嵌套struct转换
   211  		if err := gconv.Struct(scores, user); err != nil {
   212  			t.Error(err)
   213  		} else {
   214  			t.Assert(user.Scores, &Score{
   215  				Name:   "john",
   216  				Result: 100,
   217  			})
   218  		}
   219  	})
   220  }
   221  
   222  func Test_Struct_Attr_Struct_Slice1(t *testing.T) {
   223  	gtest.C(t, func(t *gtest.T) {
   224  		type Score struct {
   225  			Name   string
   226  			Result int
   227  		}
   228  		type User struct {
   229  			Scores []Score
   230  		}
   231  
   232  		user := new(User)
   233  		scores := map[string]interface{}{
   234  			"Scores": map[string]interface{}{
   235  				"Name":   "john",
   236  				"Result": 100,
   237  			},
   238  		}
   239  
   240  		if err := gconv.Struct(scores, user); err != nil {
   241  			t.Error(err)
   242  		} else {
   243  			t.Assert(user.Scores, []Score{
   244  				{
   245  					Name:   "john",
   246  					Result: 100,
   247  				},
   248  			})
   249  		}
   250  	})
   251  }
   252  
   253  func Test_Struct_Attr_Struct_Slice2(t *testing.T) {
   254  	gtest.C(t, func(t *gtest.T) {
   255  		type Score struct {
   256  			Name   string
   257  			Result int
   258  		}
   259  		type User struct {
   260  			Scores []Score
   261  		}
   262  
   263  		user := new(User)
   264  		scores := map[string]interface{}{
   265  			"Scores": []interface{}{
   266  				map[string]interface{}{
   267  					"Name":   "john",
   268  					"Result": 100,
   269  				},
   270  				map[string]interface{}{
   271  					"Name":   "smith",
   272  					"Result": 60,
   273  				},
   274  			},
   275  		}
   276  
   277  		if err := gconv.Struct(scores, user); err != nil {
   278  			t.Error(err)
   279  		} else {
   280  			t.Assert(user.Scores, []Score{
   281  				{
   282  					Name:   "john",
   283  					Result: 100,
   284  				},
   285  				{
   286  					Name:   "smith",
   287  					Result: 60,
   288  				},
   289  			})
   290  		}
   291  	})
   292  }
   293  
   294  func Test_Struct_Attr_Struct_Slice_Ptr(t *testing.T) {
   295  	gtest.C(t, func(t *gtest.T) {
   296  		type Score struct {
   297  			Name   string
   298  			Result int
   299  		}
   300  		type User struct {
   301  			Scores []*Score
   302  		}
   303  
   304  		user := new(User)
   305  		scores := map[string]interface{}{
   306  			"Scores": []interface{}{
   307  				map[string]interface{}{
   308  					"Name":   "john",
   309  					"Result": 100,
   310  				},
   311  				map[string]interface{}{
   312  					"Name":   "smith",
   313  					"Result": 60,
   314  				},
   315  			},
   316  		}
   317  
   318  		// 嵌套struct转换,属性为slice类型,数值为slice map类型
   319  		if err := gconv.Struct(scores, user); err != nil {
   320  			t.Error(err)
   321  		} else {
   322  			t.Assert(len(user.Scores), 2)
   323  			t.Assert(user.Scores[0], &Score{
   324  				Name:   "john",
   325  				Result: 100,
   326  			})
   327  			t.Assert(user.Scores[1], &Score{
   328  				Name:   "smith",
   329  				Result: 60,
   330  			})
   331  		}
   332  	})
   333  }
   334  
   335  func Test_Struct_Attr_CustomType1(t *testing.T) {
   336  	type MyInt int
   337  	type User struct {
   338  		Id   MyInt
   339  		Name string
   340  	}
   341  	gtest.C(t, func(t *gtest.T) {
   342  		user := new(User)
   343  		err := gconv.Struct(g.Map{"id": 1, "name": "john"}, user)
   344  		t.AssertNil(err)
   345  		t.Assert(user.Id, 1)
   346  		t.Assert(user.Name, "john")
   347  	})
   348  }
   349  
   350  func Test_Struct_Attr_CustomType2(t *testing.T) {
   351  	type MyInt int
   352  	type User struct {
   353  		Id   []MyInt
   354  		Name string
   355  	}
   356  	gtest.C(t, func(t *gtest.T) {
   357  		user := new(User)
   358  		err := gconv.Struct(g.Map{"id": g.Slice{1, 2}, "name": "john"}, user)
   359  		t.AssertNil(err)
   360  		t.Assert(user.Id, g.Slice{1, 2})
   361  		t.Assert(user.Name, "john")
   362  	})
   363  }
   364  
   365  // From: k8s.io/apimachinery@v0.22.0/pkg/apis/meta/v1/duration.go
   366  type MyDuration struct {
   367  	time.Duration
   368  }
   369  
   370  // UnmarshalJSON implements the json.Unmarshaller interface.
   371  func (d *MyDuration) UnmarshalJSON(b []byte) error {
   372  	var str string
   373  	err := json.Unmarshal(b, &str)
   374  	if err != nil {
   375  		return err
   376  	}
   377  
   378  	pd, err := time.ParseDuration(str)
   379  	if err != nil {
   380  		return err
   381  	}
   382  	d.Duration = pd
   383  	return nil
   384  }
   385  
   386  func Test_Struct_Attr_CustomType3(t *testing.T) {
   387  	type Config struct {
   388  		D MyDuration
   389  	}
   390  	gtest.C(t, func(t *gtest.T) {
   391  		config := new(Config)
   392  		err := gconv.Struct(g.Map{"d": "15s"}, config)
   393  		t.AssertNil(err)
   394  		t.Assert(config.D, "15s")
   395  	})
   396  	gtest.C(t, func(t *gtest.T) {
   397  		config := new(Config)
   398  		err := gconv.Struct(g.Map{"d": `"15s"`}, config)
   399  		t.AssertNil(err)
   400  		t.Assert(config.D, "15s")
   401  	})
   402  }
   403  
   404  func Test_Struct_PrivateAttribute(t *testing.T) {
   405  	type User struct {
   406  		Id   int
   407  		name string
   408  	}
   409  	gtest.C(t, func(t *gtest.T) {
   410  		user := new(User)
   411  		err := gconv.Struct(g.Map{"id": 1, "name": "john"}, user)
   412  		t.AssertNil(err)
   413  		t.Assert(user.Id, 1)
   414  		t.Assert(user.name, "")
   415  	})
   416  }
   417  
   418  func Test_StructEmbedded1(t *testing.T) {
   419  	type Base struct {
   420  		Age int
   421  	}
   422  	type User struct {
   423  		Id   int
   424  		Name string
   425  		Base
   426  	}
   427  	gtest.C(t, func(t *gtest.T) {
   428  		user := new(User)
   429  		params := g.Map{
   430  			"id":   1,
   431  			"name": "john",
   432  			"age":  18,
   433  		}
   434  		err := gconv.Struct(params, user)
   435  		t.AssertNil(err)
   436  		t.Assert(user.Id, params["id"])
   437  		t.Assert(user.Name, params["name"])
   438  		t.Assert(user.Age, 18)
   439  	})
   440  }
   441  
   442  func Test_StructEmbedded2(t *testing.T) {
   443  	type Ids struct {
   444  		Id  int
   445  		Uid int
   446  	}
   447  	type Base struct {
   448  		Ids
   449  		Time string
   450  	}
   451  	type User struct {
   452  		Base
   453  		Name string
   454  	}
   455  	params := g.Map{
   456  		"id":   1,
   457  		"uid":  10,
   458  		"name": "john",
   459  	}
   460  	gtest.C(t, func(t *gtest.T) {
   461  		user := new(User)
   462  		err := gconv.Struct(params, user)
   463  		t.AssertNil(err)
   464  		t.Assert(user.Id, 1)
   465  		t.Assert(user.Uid, 10)
   466  		t.Assert(user.Name, "john")
   467  	})
   468  }
   469  
   470  func Test_StructEmbedded3(t *testing.T) {
   471  	gtest.C(t, func(t *gtest.T) {
   472  		type Ids struct {
   473  			Id  int `json:"id"`
   474  			Uid int `json:"uid"`
   475  		}
   476  		type Base struct {
   477  			Ids
   478  			CreateTime string `json:"create_time"`
   479  		}
   480  		type User struct {
   481  			Base
   482  			Passport string `json:"passport"`
   483  			Password string `json:"password"`
   484  			Nickname string `json:"nickname"`
   485  		}
   486  		data := g.Map{
   487  			"id":          100,
   488  			"uid":         101,
   489  			"passport":    "t1",
   490  			"password":    "123456",
   491  			"nickname":    "T1",
   492  			"create_time": "2019",
   493  		}
   494  		user := new(User)
   495  		err := gconv.Struct(data, user)
   496  		t.AssertNil(err)
   497  		t.Assert(user.Id, 100)
   498  		t.Assert(user.Uid, 101)
   499  		t.Assert(user.Nickname, "T1")
   500  		t.Assert(user.CreateTime, "2019")
   501  	})
   502  }
   503  
   504  // https://github.com/wangyougui/gf/issues/775
   505  func Test_StructEmbedded4(t *testing.T) {
   506  	gtest.C(t, func(t *gtest.T) {
   507  		type Sub2 struct {
   508  			SubName string
   509  		}
   510  		type sub1 struct {
   511  			Sub2
   512  			Name string
   513  		}
   514  		type Test struct {
   515  			Sub sub1 `json:"sub"`
   516  		}
   517  
   518  		data := `{
   519      "sub": {
   520  		"map":{"k":"v"},
   521          "Name": "name",
   522          "SubName": "subname"
   523      }}`
   524  
   525  		expect := Test{
   526  			Sub: sub1{
   527  				Name: "name",
   528  				Sub2: Sub2{
   529  					SubName: "subname",
   530  				},
   531  			},
   532  		}
   533  		tx := new(Test)
   534  		if err := gconv.Struct(data, &tx); err != nil {
   535  			panic(err)
   536  		}
   537  		t.Assert(tx, expect)
   538  	})
   539  }
   540  
   541  func Test_StructEmbedded5(t *testing.T) {
   542  	gtest.C(t, func(t *gtest.T) {
   543  		type Base struct {
   544  			Pass1 string `param:"password1"`
   545  			Pass2 string `param:"password2"`
   546  		}
   547  		type UserWithBase1 struct {
   548  			Id   int
   549  			Name string
   550  			Base
   551  		}
   552  		type UserWithBase2 struct {
   553  			Id   int
   554  			Name string
   555  			Pass Base
   556  		}
   557  
   558  		data := g.Map{
   559  			"id":        1,
   560  			"name":      "john",
   561  			"password1": "123",
   562  			"password2": "456",
   563  		}
   564  		var err error
   565  		user1 := new(UserWithBase1)
   566  		user2 := new(UserWithBase2)
   567  		err = gconv.Struct(data, user1)
   568  		t.AssertNil(err)
   569  		t.Assert(user1, &UserWithBase1{1, "john", Base{"123", "456"}})
   570  
   571  		err = gconv.Struct(data, user2)
   572  		t.AssertNil(err)
   573  		t.Assert(user2, &UserWithBase2{1, "john", Base{"", ""}})
   574  
   575  		var user3 *UserWithBase1
   576  		err = gconv.Struct(user1, &user3)
   577  		t.AssertNil(err)
   578  		t.Assert(user3, user1)
   579  	})
   580  }
   581  
   582  func Test_Struct_Time(t *testing.T) {
   583  	gtest.C(t, func(t *gtest.T) {
   584  		type User struct {
   585  			CreateTime time.Time
   586  		}
   587  		now := time.Now()
   588  		user := new(User)
   589  		gconv.Struct(g.Map{
   590  			"create_time": now,
   591  		}, user)
   592  		t.Assert(user.CreateTime.UTC().String(), now.UTC().String())
   593  	})
   594  
   595  	gtest.C(t, func(t *gtest.T) {
   596  		type User struct {
   597  			CreateTime *time.Time
   598  		}
   599  		now := time.Now()
   600  		user := new(User)
   601  		gconv.Struct(g.Map{
   602  			"create_time": &now,
   603  		}, user)
   604  		t.Assert(user.CreateTime.UTC().String(), now.UTC().String())
   605  	})
   606  
   607  	gtest.C(t, func(t *gtest.T) {
   608  		type User struct {
   609  			CreateTime *gtime.Time
   610  		}
   611  		now := time.Now()
   612  		user := new(User)
   613  		gconv.Struct(g.Map{
   614  			"create_time": &now,
   615  		}, user)
   616  		t.Assert(user.CreateTime.Time.UTC().String(), now.UTC().String())
   617  	})
   618  
   619  	gtest.C(t, func(t *gtest.T) {
   620  		type User struct {
   621  			CreateTime gtime.Time
   622  		}
   623  		now := time.Now()
   624  		user := new(User)
   625  		gconv.Struct(g.Map{
   626  			"create_time": &now,
   627  		}, user)
   628  		t.Assert(user.CreateTime.Time.UTC().String(), now.UTC().String())
   629  	})
   630  
   631  	gtest.C(t, func(t *gtest.T) {
   632  		type User struct {
   633  			CreateTime gtime.Time
   634  		}
   635  		now := time.Now()
   636  		user := new(User)
   637  		gconv.Struct(g.Map{
   638  			"create_time": now,
   639  		}, user)
   640  		t.Assert(user.CreateTime.Time.UTC().String(), now.UTC().String())
   641  	})
   642  }
   643  
   644  func Test_Struct_GTime(t *testing.T) {
   645  	// https://github.com/wangyougui/gf/issues/1387
   646  	gtest.C(t, func(t *gtest.T) {
   647  		type User struct {
   648  			Name       string
   649  			CreateTime *gtime.Time
   650  		}
   651  		var user *User
   652  		err := gconv.Struct(`{"Name":"John","CreateTime":""}`, &user)
   653  		t.AssertNil(err)
   654  		t.AssertNE(user, nil)
   655  		t.Assert(user.Name, `John`)
   656  		t.Assert(user.CreateTime, nil)
   657  	})
   658  }
   659  
   660  // Auto create struct when given pointer.
   661  func Test_Struct_Create(t *testing.T) {
   662  	gtest.C(t, func(t *gtest.T) {
   663  		type User struct {
   664  			Uid  int
   665  			Name string
   666  		}
   667  		user := (*User)(nil)
   668  		params := g.Map{
   669  			"uid":  1,
   670  			"Name": "john",
   671  		}
   672  		err := gconv.Struct(params, &user)
   673  		t.AssertNil(err)
   674  		t.Assert(user.Uid, 1)
   675  		t.Assert(user.Name, "john")
   676  	})
   677  
   678  	gtest.C(t, func(t *gtest.T) {
   679  		type User struct {
   680  			Uid  int
   681  			Name string
   682  		}
   683  		user := (*User)(nil)
   684  		params := g.Map{
   685  			"uid":  1,
   686  			"Name": "john",
   687  		}
   688  		err := gconv.Struct(params, user)
   689  		t.AssertNE(err, nil)
   690  		t.Assert(user, nil)
   691  	})
   692  }
   693  
   694  func Test_Struct_Interface(t *testing.T) {
   695  	gtest.C(t, func(t *gtest.T) {
   696  		type User struct {
   697  			Uid  interface{}
   698  			Name interface{}
   699  		}
   700  		user := (*User)(nil)
   701  		params := g.Map{
   702  			"uid":  1,
   703  			"Name": nil,
   704  		}
   705  		err := gconv.Struct(params, &user)
   706  		t.AssertNil(err)
   707  		t.Assert(user.Uid, 1)
   708  		t.Assert(user.Name, nil)
   709  	})
   710  }
   711  
   712  func Test_Struct_NilAttribute(t *testing.T) {
   713  	gtest.C(t, func(t *gtest.T) {
   714  		type Item struct {
   715  			Title string `json:"title"`
   716  			Key   string `json:"key"`
   717  		}
   718  
   719  		type M struct {
   720  			Id    string                 `json:"id"`
   721  			Me    map[string]interface{} `json:"me"`
   722  			Txt   string                 `json:"txt"`
   723  			Items []*Item                `json:"items"`
   724  		}
   725  		m := new(M)
   726  		err := gconv.Struct(g.Map{
   727  			"id": "88888",
   728  			"me": g.Map{
   729  				"name": "mikey",
   730  				"day":  "20009",
   731  			},
   732  			"txt":   "hello",
   733  			"items": nil,
   734  		}, m)
   735  		t.AssertNil(err)
   736  		t.AssertNE(m.Me, nil)
   737  		t.Assert(m.Me["day"], "20009")
   738  		t.Assert(m.Items, nil)
   739  	})
   740  }
   741  
   742  func Test_Struct_Complex(t *testing.T) {
   743  	gtest.C(t, func(t *gtest.T) {
   744  		type ApplyReportDetail struct {
   745  			ApplyScore        string `json:"apply_score"`
   746  			ApplyCredibility  string `json:"apply_credibility"`
   747  			QueryOrgCount     string `json:"apply_query_org_count"`
   748  			QueryFinanceCount string `json:"apply_query_finance_count"`
   749  			QueryCashCount    string `json:"apply_query_cash_count"`
   750  			QuerySumCount     string `json:"apply_query_sum_count"`
   751  			LatestQueryTime   string `json:"apply_latest_query_time"`
   752  			LatestOneMonth    string `json:"apply_latest_one_month"`
   753  			LatestThreeMonth  string `json:"apply_latest_three_month"`
   754  			LatestSixMonth    string `json:"apply_latest_six_month"`
   755  		}
   756  		type BehaviorReportDetail struct {
   757  			LoansScore         string `json:"behavior_report_detailloans_score"`
   758  			LoansCredibility   string `json:"behavior_report_detailloans_credibility"`
   759  			LoansCount         string `json:"behavior_report_detailloans_count"`
   760  			LoansSettleCount   string `json:"behavior_report_detailloans_settle_count"`
   761  			LoansOverdueCount  string `json:"behavior_report_detailloans_overdue_count"`
   762  			LoansOrgCount      string `json:"behavior_report_detailloans_org_count"`
   763  			ConsfinOrgCount    string `json:"behavior_report_detailconsfin_org_count"`
   764  			LoansCashCount     string `json:"behavior_report_detailloans_cash_count"`
   765  			LatestOneMonth     string `json:"behavior_report_detaillatest_one_month"`
   766  			LatestThreeMonth   string `json:"behavior_report_detaillatest_three_month"`
   767  			LatestSixMonth     string `json:"behavior_report_detaillatest_six_month"`
   768  			HistorySucFee      string `json:"behavior_report_detailhistory_suc_fee"`
   769  			HistoryFailFee     string `json:"behavior_report_detailhistory_fail_fee"`
   770  			LatestOneMonthSuc  string `json:"behavior_report_detaillatest_one_month_suc"`
   771  			LatestOneMonthFail string `json:"behavior_report_detaillatest_one_month_fail"`
   772  			LoansLongTime      string `json:"behavior_report_detailloans_long_time"`
   773  			LoansLatestTime    string `json:"behavior_report_detailloans_latest_time"`
   774  		}
   775  		type CurrentReportDetail struct {
   776  			LoansCreditLimit    string `json:"current_report_detailloans_credit_limit"`
   777  			LoansCredibility    string `json:"current_report_detailloans_credibility"`
   778  			LoansOrgCount       string `json:"current_report_detailloans_org_count"`
   779  			LoansProductCount   string `json:"current_report_detailloans_product_count"`
   780  			LoansMaxLimit       string `json:"current_report_detailloans_max_limit"`
   781  			LoansAvgLimit       string `json:"current_report_detailloans_avg_limit"`
   782  			ConsfinCreditLimit  string `json:"current_report_detailconsfin_credit_limit"`
   783  			ConsfinCredibility  string `json:"current_report_detailconsfin_credibility"`
   784  			ConsfinOrgCount     string `json:"current_report_detailconsfin_org_count"`
   785  			ConsfinProductCount string `json:"current_report_detailconsfin_product_count"`
   786  			ConsfinMaxLimit     string `json:"current_report_detailconsfin_max_limit"`
   787  			ConsfinAvgLimit     string `json:"current_report_detailconsfin_avg_limit"`
   788  		}
   789  		type ResultDetail struct {
   790  			ApplyReportDetail    ApplyReportDetail    `json:"apply_report_detail"`
   791  			BehaviorReportDetail BehaviorReportDetail `json:"behavior_report_detail"`
   792  			CurrentReportDetail  CurrentReportDetail  `json:"current_report_detail"`
   793  		}
   794  
   795  		type Data struct {
   796  			Code         string       `json:"code"`
   797  			Desc         string       `json:"desc"`
   798  			TransID      string       `json:"trans_id"`
   799  			TradeNo      string       `json:"trade_no"`
   800  			Fee          string       `json:"fee"`
   801  			IDNo         string       `json:"id_no"`
   802  			IDName       string       `json:"id_name"`
   803  			Versions     string       `json:"versions"`
   804  			ResultDetail ResultDetail `json:"result_detail"`
   805  		}
   806  
   807  		type XinYanModel struct {
   808  			Success   bool        `json:"success"`
   809  			Data      Data        `json:"data"`
   810  			ErrorCode interface{} `json:"errorCode"`
   811  			ErrorMsg  interface{} `json:"errorMsg"`
   812  		}
   813  
   814  		var data = `{
   815      "success": true,
   816      "data": {
   817          "code": "0",
   818          "desc": "查询成功",
   819          "trans_id": "14910304379231213",
   820          "trade_no": "201704011507240100057329",
   821          "fee": "Y",
   822          "id_no": "0783231bcc39f4957e99907e02ae401c",
   823          "id_name": "dd67a5943781369ddd7c594e231e9e70",
   824          "versions": "1.0.0",
   825          "result_detail":{
   826              "apply_report_detail": {
   827                  "apply_score": "189",
   828                  "apply_credibility": "84",
   829                  "query_org_count": "7",
   830                  "query_finance_count": "2",
   831                  "query_cash_count": "2",
   832                  "query_sum_count": "13",
   833                  "latest_query_time": "2017-09-03",
   834                  "latest_one_month": "1",
   835                  "latest_three_month": "5",
   836                  "latest_six_month": "12"
   837              },
   838              "behavior_report_detail": {
   839                  "loans_score": "199",
   840                  "loans_credibility": "90",
   841                  "loans_count": "300",
   842                  "loans_settle_count": "280",
   843                  "loans_overdue_count": "20",
   844                  "loans_org_count": "5",
   845                  "consfin_org_count": "3",
   846                  "loans_cash_count": "2",
   847                  "latest_one_month": "3",
   848                  "latest_three_month": "20",
   849                  "latest_six_month": "23",
   850                  "history_suc_fee": "30",
   851                  "history_fail_fee": "25",
   852                  "latest_one_month_suc": "5",
   853                  "latest_one_month_fail": "20",
   854                  "loans_long_time": "130",
   855                  "loans_latest_time": "2017-09-16"
   856              },
   857              "current_report_detail": {
   858                  "loans_credit_limit": "1400",
   859                  "loans_credibility": "80",
   860                  "loans_org_count": "7",
   861                  "loans_product_count": "8",
   862                  "loans_max_limit": "2000",
   863                  "loans_avg_limit": "1000",
   864                  "consfin_credit_limit": "1500",
   865                  "consfin_credibility": "90",
   866                  "consfin_org_count": "8",
   867                  "consfin_product_count": "5",
   868                  "consfin_max_limit": "5000",
   869                  "consfin_avg_limit": "3000"
   870              }
   871          }
   872      },
   873      "errorCode": null,
   874      "errorMsg": null
   875  }`
   876  		m := make(g.Map)
   877  		err := json.UnmarshalUseNumber([]byte(data), &m)
   878  		t.AssertNil(err)
   879  
   880  		model := new(XinYanModel)
   881  		err = gconv.Struct(m, model)
   882  		t.AssertNil(err)
   883  		t.Assert(model.ErrorCode, nil)
   884  		t.Assert(model.ErrorMsg, nil)
   885  		t.Assert(model.Success, true)
   886  		t.Assert(model.Data.IDName, "dd67a5943781369ddd7c594e231e9e70")
   887  		t.Assert(model.Data.TradeNo, "201704011507240100057329")
   888  		t.Assert(model.Data.ResultDetail.ApplyReportDetail.ApplyScore, "189")
   889  		t.Assert(model.Data.ResultDetail.BehaviorReportDetail.LoansSettleCount, "280")
   890  		t.Assert(model.Data.ResultDetail.CurrentReportDetail.LoansProductCount, "8")
   891  	})
   892  }
   893  
   894  func Test_Struct_CatchPanic(t *testing.T) {
   895  	gtest.C(t, func(t *gtest.T) {
   896  		type Score struct {
   897  			Name   string
   898  			Result int
   899  		}
   900  		type User struct {
   901  			Score Score
   902  		}
   903  
   904  		user := new(User)
   905  		scores := map[string]interface{}{
   906  			"Score": 1,
   907  		}
   908  		err := gconv.Struct(scores, user)
   909  		t.AssertNE(err, nil)
   910  	})
   911  }
   912  
   913  type T struct {
   914  	Name string
   915  }
   916  
   917  func (t *T) Test() string {
   918  	return t.Name
   919  }
   920  
   921  type TestInterface interface {
   922  	Test() string
   923  }
   924  
   925  type TestStruct struct {
   926  	TestInterface
   927  }
   928  
   929  func Test_Struct_Embedded(t *testing.T) {
   930  	// Implemented interface attribute.
   931  	gtest.C(t, func(t *gtest.T) {
   932  		v1 := TestStruct{
   933  			TestInterface: &T{"john"},
   934  		}
   935  		v2 := g.Map{}
   936  		err := gconv.Struct(v2, &v1)
   937  		t.AssertNil(err)
   938  		t.Assert(v1.Test(), "john")
   939  	})
   940  	// Implemented interface attribute.
   941  	gtest.C(t, func(t *gtest.T) {
   942  		v1 := TestStruct{
   943  			TestInterface: &T{"john"},
   944  		}
   945  		v2 := g.Map{
   946  			"name": "test",
   947  		}
   948  		err := gconv.Struct(v2, &v1)
   949  		t.AssertNil(err)
   950  		t.Assert(v1.Test(), "test")
   951  	})
   952  	// No implemented interface attribute.
   953  	gtest.C(t, func(t *gtest.T) {
   954  		v1 := TestStruct{}
   955  		v2 := g.Map{
   956  			"name": "test",
   957  		}
   958  		err := gconv.Struct(v2, &v1)
   959  		t.AssertNil(err)
   960  		t.Assert(v1.TestInterface, nil)
   961  	})
   962  }
   963  
   964  func Test_Struct_Slice(t *testing.T) {
   965  	gtest.C(t, func(t *gtest.T) {
   966  		type User struct {
   967  			Scores []int
   968  		}
   969  		user := new(User)
   970  		array := g.Slice{1, 2, 3}
   971  		err := gconv.Struct(g.Map{"scores": array}, user)
   972  		t.AssertNil(err)
   973  		t.Assert(user.Scores, array)
   974  	})
   975  	gtest.C(t, func(t *gtest.T) {
   976  		type User struct {
   977  			Scores []int32
   978  		}
   979  		user := new(User)
   980  		array := g.Slice{1, 2, 3}
   981  		err := gconv.Struct(g.Map{"scores": array}, user)
   982  		t.AssertNil(err)
   983  		t.Assert(user.Scores, array)
   984  	})
   985  	gtest.C(t, func(t *gtest.T) {
   986  		type User struct {
   987  			Scores []int64
   988  		}
   989  		user := new(User)
   990  		array := g.Slice{1, 2, 3}
   991  		err := gconv.Struct(g.Map{"scores": array}, user)
   992  		t.AssertNil(err)
   993  		t.Assert(user.Scores, array)
   994  	})
   995  	gtest.C(t, func(t *gtest.T) {
   996  		type User struct {
   997  			Scores []uint
   998  		}
   999  		user := new(User)
  1000  		array := g.Slice{1, 2, 3}
  1001  		err := gconv.Struct(g.Map{"scores": array}, user)
  1002  		t.AssertNil(err)
  1003  		t.Assert(user.Scores, array)
  1004  	})
  1005  	gtest.C(t, func(t *gtest.T) {
  1006  		type User struct {
  1007  			Scores []uint32
  1008  		}
  1009  		user := new(User)
  1010  		array := g.Slice{1, 2, 3}
  1011  		err := gconv.Struct(g.Map{"scores": array}, user)
  1012  		t.AssertNil(err)
  1013  		t.Assert(user.Scores, array)
  1014  	})
  1015  	gtest.C(t, func(t *gtest.T) {
  1016  		type User struct {
  1017  			Scores []uint64
  1018  		}
  1019  		user := new(User)
  1020  		array := g.Slice{1, 2, 3}
  1021  		err := gconv.Struct(g.Map{"scores": array}, user)
  1022  		t.AssertNil(err)
  1023  		t.Assert(user.Scores, array)
  1024  	})
  1025  	gtest.C(t, func(t *gtest.T) {
  1026  		type User struct {
  1027  			Scores []float32
  1028  		}
  1029  		user := new(User)
  1030  		array := g.Slice{1, 2, 3}
  1031  		err := gconv.Struct(g.Map{"scores": array}, user)
  1032  		t.AssertNil(err)
  1033  		t.Assert(user.Scores, array)
  1034  	})
  1035  	gtest.C(t, func(t *gtest.T) {
  1036  		type User struct {
  1037  			Scores []float64
  1038  		}
  1039  		user := new(User)
  1040  		array := g.Slice{1, 2, 3}
  1041  		err := gconv.Struct(g.Map{"scores": array}, user)
  1042  		t.AssertNil(err)
  1043  		t.Assert(user.Scores, array)
  1044  	})
  1045  }
  1046  
  1047  func Test_Struct_To_Struct(t *testing.T) {
  1048  	var TestA struct {
  1049  		Id   int       `p:"id"`
  1050  		Date time.Time `p:"date"`
  1051  	}
  1052  
  1053  	var TestB struct {
  1054  		Id   int       `p:"id"`
  1055  		Date time.Time `p:"date"`
  1056  	}
  1057  	TestB.Id = 666
  1058  	TestB.Date = time.Now()
  1059  
  1060  	gtest.C(t, func(t *gtest.T) {
  1061  		t.Assert(gconv.Struct(TestB, &TestA), nil)
  1062  		t.Assert(TestA.Id, TestB.Id)
  1063  		t.Assert(TestA.Date, TestB.Date)
  1064  	})
  1065  }
  1066  
  1067  func Test_Struct_WithJson(t *testing.T) {
  1068  	type A struct {
  1069  		Name string
  1070  	}
  1071  	type B struct {
  1072  		A
  1073  		Score int
  1074  	}
  1075  	gtest.C(t, func(t *gtest.T) {
  1076  		b1 := &B{}
  1077  		b1.Name = "john"
  1078  		b1.Score = 100
  1079  		b, _ := json.Marshal(b1)
  1080  		b2 := &B{}
  1081  		err := gconv.Struct(b, b2)
  1082  		t.AssertNil(err)
  1083  		t.Assert(b2, b1)
  1084  	})
  1085  }
  1086  
  1087  func Test_Struct_AttrStructHasTheSameTag(t *testing.T) {
  1088  	type Product struct {
  1089  		Id              int       `json:"id"`
  1090  		UpdatedAt       time.Time `json:"-" `
  1091  		UpdatedAtFormat string    `json:"updated_at" `
  1092  	}
  1093  
  1094  	type Order struct {
  1095  		Id        int       `json:"id"`
  1096  		UpdatedAt time.Time `json:"updated_at"`
  1097  		Product   Product   `json:"products"`
  1098  	}
  1099  	gtest.C(t, func(t *gtest.T) {
  1100  		data := g.Map{
  1101  			"id":         1,
  1102  			"updated_at": time.Now(),
  1103  		}
  1104  		order := new(Order)
  1105  		err := gconv.Struct(data, order)
  1106  		t.AssertNil(err)
  1107  		t.Assert(order.Id, data["id"])
  1108  		t.Assert(order.UpdatedAt, data["updated_at"])
  1109  		t.Assert(order.Product.Id, 0)
  1110  		t.Assert(order.Product.UpdatedAt.IsZero(), true)
  1111  		t.Assert(order.Product.UpdatedAtFormat, "")
  1112  	})
  1113  }
  1114  
  1115  func Test_Struct_DirectReflectSet(t *testing.T) {
  1116  	type A struct {
  1117  		Id   int
  1118  		Name string
  1119  	}
  1120  
  1121  	gtest.C(t, func(t *gtest.T) {
  1122  		var (
  1123  			a = &A{
  1124  				Id:   1,
  1125  				Name: "john",
  1126  			}
  1127  			b *A
  1128  		)
  1129  		err := gconv.Struct(a, &b)
  1130  		t.AssertNil(err)
  1131  		t.AssertEQ(a, b)
  1132  	})
  1133  	gtest.C(t, func(t *gtest.T) {
  1134  		var (
  1135  			a = A{
  1136  				Id:   1,
  1137  				Name: "john",
  1138  			}
  1139  			b A
  1140  		)
  1141  		err := gconv.Struct(a, &b)
  1142  		t.AssertNil(err)
  1143  		t.AssertEQ(a, b)
  1144  	})
  1145  }
  1146  
  1147  func Test_Struct_NilEmbeddedStructAttribute(t *testing.T) {
  1148  	type A struct {
  1149  		Name string
  1150  	}
  1151  	type B struct {
  1152  		*A
  1153  		Id int
  1154  	}
  1155  
  1156  	gtest.C(t, func(t *gtest.T) {
  1157  		var (
  1158  			b *B
  1159  		)
  1160  		err := gconv.Struct(g.Map{
  1161  			"id":   1,
  1162  			"name": nil,
  1163  		}, &b)
  1164  		t.AssertNil(err)
  1165  		t.Assert(b.Id, 1)
  1166  		t.Assert(b.Name, "")
  1167  	})
  1168  }
  1169  
  1170  func Test_Struct_JsonParam(t *testing.T) {
  1171  	type A struct {
  1172  		Id   int    `json:"id"`
  1173  		Name string `json:"name"`
  1174  	}
  1175  	// struct
  1176  	gtest.C(t, func(t *gtest.T) {
  1177  		var a = A{}
  1178  		err := gconv.Struct([]byte(`{"id":1,"name":"john"}`), &a)
  1179  		t.AssertNil(err)
  1180  		t.Assert(a.Id, 1)
  1181  		t.Assert(a.Name, "john")
  1182  	})
  1183  	// *struct
  1184  	gtest.C(t, func(t *gtest.T) {
  1185  		var a = &A{}
  1186  		err := gconv.Struct([]byte(`{"id":1,"name":"john"}`), a)
  1187  		t.AssertNil(err)
  1188  		t.Assert(a.Id, 1)
  1189  		t.Assert(a.Name, "john")
  1190  	})
  1191  	// *struct nil
  1192  	gtest.C(t, func(t *gtest.T) {
  1193  		var a *A
  1194  		err := gconv.Struct([]byte(`{"id":1,"name":"john"}`), &a)
  1195  		t.AssertNil(err)
  1196  		t.Assert(a.Id, 1)
  1197  		t.Assert(a.Name, "john")
  1198  	})
  1199  }
  1200  
  1201  func Test_Struct_GVarAttribute(t *testing.T) {
  1202  	type A struct {
  1203  		Id     int    `json:"id"`
  1204  		Name   string `json:"name"`
  1205  		Status bool   `json:"status"`
  1206  	}
  1207  	gtest.C(t, func(t *gtest.T) {
  1208  		var (
  1209  			a    = A{}
  1210  			data = g.Map{
  1211  				"id":     100,
  1212  				"name":   "john",
  1213  				"status": gvar.New(false),
  1214  			}
  1215  		)
  1216  		err := gconv.Struct(data, &a)
  1217  		t.AssertNil(err)
  1218  		t.Assert(a.Id, data["id"])
  1219  		t.Assert(a.Name, data["name"])
  1220  		t.Assert(a.Status, data["status"])
  1221  	})
  1222  
  1223  }
  1224  
  1225  func Test_Struct_MapAttribute(t *testing.T) {
  1226  	type NodeStatus struct {
  1227  		ID int
  1228  	}
  1229  	type Nodes map[string]NodeStatus
  1230  	type Output struct {
  1231  		Nodes Nodes
  1232  	}
  1233  
  1234  	gtest.C(t, func(t *gtest.T) {
  1235  		var (
  1236  			out  = Output{}
  1237  			data = g.Map{
  1238  				"nodes": g.Map{
  1239  					"name": g.Map{
  1240  						"id": 10000,
  1241  					},
  1242  				},
  1243  			}
  1244  		)
  1245  		err := gconv.Struct(data, &out)
  1246  		t.AssertNil(err)
  1247  	})
  1248  }
  1249  
  1250  func Test_Struct_Empty_MapStringString(t *testing.T) {
  1251  	gtest.C(t, func(t *gtest.T) {
  1252  		type S struct {
  1253  			Id int
  1254  		}
  1255  		var (
  1256  			s   = &S{}
  1257  			err = gconv.Struct(map[string]string{}, s)
  1258  		)
  1259  		t.AssertNil(err)
  1260  	})
  1261  }
  1262  
  1263  // https://github.com/wangyougui/gf/issues/1563
  1264  func Test_Struct_Issue1563(t *testing.T) {
  1265  	type User struct {
  1266  		Pass1 string `c:"password1"`
  1267  	}
  1268  	gtest.C(t, func(t *gtest.T) {
  1269  		for i := 0; i < 100; i++ {
  1270  			user := new(User)
  1271  			params2 := g.Map{
  1272  				"password1": "111",
  1273  				//"PASS1":     "222",
  1274  				"Pass1": "333",
  1275  			}
  1276  			if err := gconv.Struct(params2, user); err == nil {
  1277  				t.Assert(user.Pass1, `111`)
  1278  			}
  1279  		}
  1280  	})
  1281  }
  1282  
  1283  // https://github.com/wangyougui/gf/issues/1597
  1284  func Test_Struct_Issue1597(t *testing.T) {
  1285  	gtest.C(t, func(t *gtest.T) {
  1286  		type S struct {
  1287  			A int
  1288  			B json.RawMessage
  1289  		}
  1290  
  1291  		jsonByte := []byte(`{
  1292  		"a":1, 
  1293  		"b":{
  1294  			"c": 3
  1295  		}
  1296  	}`)
  1297  		data, err := gjson.DecodeToJson(jsonByte)
  1298  		t.AssertNil(err)
  1299  		s := &S{}
  1300  		err = data.Scan(s)
  1301  		t.AssertNil(err)
  1302  		t.Assert(s.B, `{"c":3}`)
  1303  	})
  1304  }
  1305  
  1306  // https://github.com/wangyougui/gf/issues/2980
  1307  func Test_Struct_Issue2980(t *testing.T) {
  1308  	type Post struct {
  1309  		CreatedAt *gtime.Time `json:"createdAt" `
  1310  	}
  1311  
  1312  	type PostWithUser struct {
  1313  		Post
  1314  		UserName string `json:"UserName"`
  1315  	}
  1316  
  1317  	gtest.C(t, func(t *gtest.T) {
  1318  		date := gtime.New("2023-09-22 12:00:00").UTC()
  1319  		params := g.Map{
  1320  			"CreatedAt": gtime.New("2023-09-22 12:00:00").UTC(),
  1321  			"UserName":  "Galileo",
  1322  		}
  1323  		postWithUser := new(PostWithUser)
  1324  		err := gconv.Scan(params, postWithUser)
  1325  		t.AssertNil(err)
  1326  		t.Assert(date.Location(), postWithUser.CreatedAt.Location())
  1327  		t.Assert(date.Unix(), postWithUser.CreatedAt.Unix())
  1328  	})
  1329  }
  1330  
  1331  func Test_Scan_WithDoubleSliceAttribute(t *testing.T) {
  1332  	inputData := [][]string{
  1333  		{"aa", "bb", "cc"},
  1334  		{"11", "22", "33"},
  1335  	}
  1336  	data := struct {
  1337  		Data [][]string
  1338  	}{
  1339  		Data: inputData,
  1340  	}
  1341  	gtest.C(t, func(t *gtest.T) {
  1342  		jv := gjson.New(gjson.MustEncodeString(data))
  1343  		err := jv.Scan(&data)
  1344  		t.AssertNil(err)
  1345  		t.Assert(data.Data, inputData)
  1346  	})
  1347  
  1348  }
  1349  
  1350  func Test_Struct_WithCustomType(t *testing.T) {
  1351  	type PayMode int
  1352  
  1353  	type Req1 struct {
  1354  		PayMode PayMode
  1355  	}
  1356  	type Req2 struct {
  1357  		PayMode *PayMode
  1358  	}
  1359  	var (
  1360  		params = gconv.Map(`{"PayMode": 1000}`)
  1361  		req1   *Req1
  1362  		req2   *Req2
  1363  		err1   error
  1364  		err2   error
  1365  	)
  1366  	err1 = gconv.Struct(params, &req1)
  1367  	err2 = gconv.Struct(params, &req2)
  1368  	gtest.C(t, func(t *gtest.T) {
  1369  		t.AssertNil(err1)
  1370  		t.Assert(req1.PayMode, 1000)
  1371  
  1372  		t.AssertNil(err2)
  1373  		t.AssertNE(req2.PayMode, nil)
  1374  		t.Assert(*req2.PayMode, 1000)
  1375  	})
  1376  }
  1377  
  1378  func Test_Struct_EmptyStruct(t *testing.T) {
  1379  	gtest.C(t, func(t *gtest.T) {
  1380  		var err error
  1381  
  1382  		type StructA struct {
  1383  		}
  1384  
  1385  		type StructB struct {
  1386  		}
  1387  
  1388  		var s1 StructA
  1389  		var s2 *StructB
  1390  
  1391  		err = gconv.Scan(s1, &s2)
  1392  		t.AssertNil(err)
  1393  
  1394  		err = gconv.Scan(&s1, &s2)
  1395  		t.AssertNil(err)
  1396  
  1397  		type StructC struct {
  1398  			Val int `json:"val,omitempty"`
  1399  		}
  1400  
  1401  		type StructD struct {
  1402  			Val int
  1403  		}
  1404  
  1405  		var s3 StructC
  1406  		var s4 *StructD
  1407  
  1408  		err = gconv.Scan(s3, &s4)
  1409  		t.AssertNil(err)
  1410  		t.Assert(s4.Val, 0)
  1411  
  1412  		err = gconv.Scan(&s3, &s4)
  1413  		t.AssertNil(err)
  1414  		t.Assert(s4.Val, 0)
  1415  
  1416  		s3.Val = 123
  1417  		err = gconv.Scan(s3, &s4)
  1418  		t.AssertNil(err)
  1419  		t.Assert(s4.Val, 123)
  1420  
  1421  		err = gconv.Scan(&s3, &s4)
  1422  		t.AssertNil(err)
  1423  		t.Assert(s4.Val, 123)
  1424  
  1425  	})
  1426  }