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  }